被迫营业的数据管理技术上机实验

自己选的课,哭着也要上完。

本学期开始进行专业方向分流,我分到的方向是网络与通信软件方向。最开始以为选修课学分还差一点,所以选择了这门课 Web 开发方向的专业课。不过最后发现其实学分已经够了。算了,选都选了又没法退,就硬着头皮上吧。不过话说回来将这门课作为 Web 方向的第一门专业课总有种奇怪的感觉……

言归正传,这门课主要学习的是非关系型数据库,以 Hadoop、Redis 和 Memcached 为主要实例。而四次上机实验的内容则是关于 Hadoop 和 Redis 的配置以及使用。在这里记录一下踩坑的全过程。

本文具体的实验环境如下:宿主机系统 Windows 10 专业版(2004),虚拟机软件 VMware Workstation 16,虚拟机系统 Ubuntu 20.04.1(x64)。注意这里使用的虚拟机系统并非是推荐的 CentOS。

在继续阅读之前,请确保已经完成环境的配置(系统的安装、VMware Tools 的安装等),同时也建议执行一次 sudo apt update && sudo apt upgrade

实验一:Hadoop 和 HBase 的安装和配置

第一次实验的目标是配置 Hadoop(含 HDFS、MapReduce 和 YARN)和 HBase。使用的软件和具体版本号为:Hadoop 3.1.4、HBase 2.2.6。这里我们仅配置一主一从伪分布式环境。

需要注意的是,HBase 对 Hadoop 的版本有着严格的要求,具体可以查看 Hadoop version support matrix。经过测试 Hadoop 3.3.0 无法和现有的 HBase 版本配合使用。

前期准备

为了便于后续操作,我们专门添加一个用于 Hadoop 的用户,用户名和密码均为 hadoop。输入以下命令:

sudo useradd -m hadoop -s /bin/bash
sudo passwd hadoop
sudo adduser hadoop sudo
su - hadoop
sudo apt update

接下来进行一些环境准备操作,此时请保持在 hadoop 用户下。使用 sudo apt install openjdk-8-jdk 安装好 OpenJDK(目前 Apache 官方推荐使用 OpenJDK 而不是 Oracle JDK)。不过这样安装的 OpenJDK 默认不会配置好环境变量,所以需要手动配置,将下列配置加入到 ~/.bashrc 文件中:

# Java Environment
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

保存之后,使用 source ~/.bashrc 使修改生效。继续输入 java -version,如果正确显示 JDK 版本,即说明配置完成。

然后继续使用下列命令安装 SSH:

sudo apt-get install openssh-server
ssh localhost
exit
cd ~/.ssh/
ssh-keygen -t rsa

执行 ssh-keygen 命令之后,连续三次回车。第一次是将 Key 存放于默认位置,第二次和第三次是 passphrase 相关的操作。完成之后继续执行:

touch authorized_keys
chmod 600 authorized_keys
cat ./id_rsa.pub >> ./authorized_keys
ssh localhost

这时会发现登录本机的 SSH 已经不再需要密码了。

Hadoop 的配置

切到保存有下载好的 hadoop-3.1.4.tar.gz 文件的文件夹,执行下列命令进行安装。这里为了方便,我们将解压出来的文件夹改名为 hadoop

sudo tar -zxvf hadoop-3.1.4.tar.gz -C /usr/local
cd /usr/local
sudo mv hadoop-3.1.4 hadoop
sudo chown -R hadoop ./hadoop

然后加入 Hadoop 的环境变量,方法与之前配置 JDK 环境变量相同:

# Hadoop Environment
export HADOOP_HOME=/usr/local/hadoop
export CLASSPATH=$($HADOOP_HOME/bin/hadoop classpath):$CLASSPATH
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

完成之后输入 hadoop version,如果出现 Hadoop 版本即说明成功。下面开始配置伪分布式环境。

切到 /usr/local/hadoop/etc/hadoop 文件夹,修改 hadoop-env.sh 文件,主要是指定 JAVA_HOME,在文件开头部分找到被注释掉的 export JAVA_HOME=,将其取消注释,并将等号后面的路径修改为之前的 JAVA_HOME 环境变量的值,在本文的示例中即为 /usr/lib/jvm/java-8-openjdk-amd64

然后修改 core-site.xml 文件:

<configuration>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>file:/usr/local/hadoop/tmp</value>
        <description>A base for other temporary directories.</description>
    </property>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://localhost:9000</value>
    </property>
</configuration>

修改 hdfs-site.xml 文件,在 <configuration> 节加入:

    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:/usr/local/hadoop/tmp/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:/usr/local/hadoop/tmp/dfs/data</value>
    </property>
    <property>
         <name>dfs.http.address</name>
         <value>0.0.0.0:50070</value>
    </property>

修改 yarn-site.xml 文件:

<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>

    <property>
        <name>yarn.nodemanager.env-whitelist</name>
        <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
    </property>
</configuration>

修改 mapred-site.xml 文件:

<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>

    <property>
        <name>yarn.nodemanager.env-whitelist</name>
        <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
    </property>
</configuration>

保存上述文件,然后开始准备格式化 NameNode。按照本文流程来说,到这里应该是第一次格式化,所以没有什么太大的问题。如果是在已有数据的情况下想要重新格式化,则需要删除所有的数据 data 和日志 log。否则会导致 NameNode 和 DataNode 的集群 ID 不一致。

cd /usr/local/hadoop/bin
hdfs namenode -format

完成之后,启动 Hadoop 检查我们的配置结果:

cd /usr/local/hadoop/sbin
./start-dfs.sh
./start-yarn.sh
jps

在输出中出现 JpsNameNodeDateNodeSecondaryNameNodeResourceManager 即为成功。此时打开浏览器,访问 localhost:50070 可以查看到下列页面:

访问 localhost:8088 可以查看到下列页面,这是 YARN 提供的:

点击左侧的 Nodes,可以查看到我们配置的节点信息:

接下来,我们运行一次经典的 WordCount 来测试 Hadoop。

hdfs dfs -mkdir /input # 创建 input 文件夹
hdfs dfs -put /usr/local/hadoop/LICENSE.txt /input/test.txt # 上传一个测试文件
hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.0.jar wordcount /input/test.txt /output/

此时会有类似于下列内容的输出:

完成之后执行 hdfs dfs -ls /output,可以看到有如下两个文件生成:

我们运行 hdfs dfs -cat /output/part-r-00000 查看一下 part-r-00000 文件的内容,即为 WordCount 的输出结果:

符合预期。当然我们还可以通过之前的网页控制台查看 HDFS 中的文件。

至此 Hadoop 配置完成。

HBase 的配置

继续保持在 hadoop 用户下。切到有下载好的 hbase-2.2.6-bin.tar.gz 文件的文件夹中,执行:

sudo tar -zxvf  hbase-2.2.6-bin.tar.gz -C /usr/local
cd /usr/local
sudo mv hbase-2.2.6-bin hbase
sudo chown -R hadoop ./hbase

配置环境变量:

# HBase Environment
HBASE_HOME=/usr/local/hbase

和之前 Hadoop 一样,切到 $HBASE_HOME/conf 文件夹,修改 hbase-env.sh,设置环境变量:

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

继续修改 hbase-site.xml

<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://localhost:9000/hbase</value>
  </property>
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
  </property>
  <property>
    <name>hbase.unsafe.stream.capability.enforce</name>
    <value>false</value>
  </property>
</configuration>

确保已经按照前文所述启动了 Hadoop。切到 /usr/local/hbase/bin 文件夹,执行 ./start-hbase.sh 启动 HBase。然后执行 jps 查看运行情况。

如果出现 HMasterHRegionServerHQuorumPeer,即为成功运行,如下图所示:

访问 localhost:16010,可以看到如下页面:

至此,HBase 配置完成。

实验二:HBase 的使用

之前实验一的内容写的有点多了,其实 HBase 的配置应该是实验二里的内容,不过问题不大。

首先确保 Hadoop 和 HBase 正在运行,运行方法参照实验一中提到的命令。然后使用以下命令进入 HBase 的 Shell 环境:

cd /usr/local/hbase/bin
./hbase shell

Shell 环境如下所示(可以忽略“无效的变量名”报错):

输入命令 list 可以查看所有的表。当然目前我们的数据库是空的,所以什么都没有:

下面开始建表过程。这里对于 HBase 的行键、列族等概念不再阐述。考虑如下数据表:

其中加粗的表头为列族,其下属为列。这里我们用工号作为行键。

然后开始创建数据表。命令格式为 create '<table_name>,'<column_family_1>','<column_family_2>'...

create 'bank','e_info', 'e_level', 'e_salary'

完成之后我们向表中插入数据。由于 HBase 的特性,我们需要逐个单元格进行添加。命令格式为 put '<table_name>','<row_key>','<column_family>:<column>','value'

put 'bank','10001','e_info:e_name','张三'
put 'bank','10001','e_info:e_sex','0'
put 'bank','10001','e_level','2'
put 'bank','10001','e_salary','3000'
put 'bank','10002','e_info:e_name','李四'
put 'bank','10002','e_info:e_sex','0'
put 'bank','10002','e_level','2'
put 'bank','10002','e_salary','3200'
put 'bank','10003','e_info:e_name','王五'
put 'bank','10003','e_info:e_sex','0'
put 'bank','10003','e_level','2'
put 'bank','10003','e_salary','3100'
put 'bank','10004','e_info:e_name','赵六'
put 'bank','10004','e_info:e_sex','1'
put 'bank','10004','e_level','1'
put 'bank','10004','e_salary','5000'
put 'bank','10005','e_info:e_name','孙敏'
put 'bank','10005','e_info:e_sex','1'
put 'bank','10005','e_level','0'
put 'bank','10005','e_salary','8000'

插入完成之后,就可以开始查询数据了。命令格式为 `get '<table_name>','<row_key>'{,<codition>}`,其中 <condition> 部分是可选的。比如在不设置条件的时候,我们查询的就是行键所代表的一整行数据:

get 'bank','10001'

当然也可以指定列族或者列进行查询,加上条件即可:

# 指定列族
get 'bank','10001',{COLUMN => 'e_info'}
# 指定列族和列
get 'bank','10001',{COLUMN => 'e_info:e_name'}

我们也可以一次性查询整张表的数据,命令格式为 scan '<table_name>'

scan 'bank'

如果需要更新数据,直接插入新的数据即可:

put 'bank','10001','e_salary','3300'

使用 delete '<table_name>','<row_key>','<column_family:column>' 删除某一行中,某一列族下的某一列的数据:

# 假定我们已经添加了下列数据
put 'bank','10006','e_info:e_name','测试'
put 'bank','10006','e_info:e_sex','0'
put 'bank','10006','e_level','2'
put 'bank','10006','e_salary','2000'
# 执行删除
delete 'bank','10001','e_info:e_sex'

当然也可以直接删除一行。命令格式为 deleteall '<table_name>','<row_key>'

deleteall 'bank','10001'

以上就是 HBase 的基本使用。

实验三:Redis 的安装和配置

因为 Ubuntu 的软件源里包含了 Redis 服务器,所以安装和配置还是比较简单的。安装的话直接一句 sudo apt install redis-server 就好。装好之后可以使用 ps -aux|grep redis 看到 Redis 已经开始运行了,如下图所示。

配置文件方面的话,没有太多要修改的地方。通过 Ubuntu 软件源安装的 Redis 默认已经启用了守护进程,我们需要修改的就是增加一下登录密码以提高安全性。打开 /etc/redis/redis.conf 文件,搜索 requirepass 字段,取消注释,并在后面设置密码,比如:

requirepass redis

保存之后,执行 sudo service redis-server restart 重启 Redis 服务器。然后我们可以借助先前安装 Redis 时自动装好的命令行工具 redis-cli 访问 Redis。

由于我们设置了密码,所以在运行命令行工具的时候需要传递密码参数,执行 redis-cli -a redis。进入命令行工具之后,输入 ping 可以查看连接情况,如果连接正常,会得到 PONG 的响应。如果没有提供密码,或是提供了错误的密码,将不会得到正确的响应。

这样 Redis 就算配置完成了。

实验四:Redis 的使用

考虑如下教师和学生信息表:

在上图中,已经列出了使用 Redis 组织数据的形式。使用下列命令插入数据:

set 'teacher:10000:name' '张三'
set 'teacher:10000:age' '30'
set 'teacher:10000:title' '讲师'
set 'teacher:10000:work_year' '2'
set 'teacher:10000:salary' '8000'
sadd 'teacher:10000:course' '编译原理' '面向对象程序设计' '计算机导论与程序设计'
set 'teacher:10001:name' '李四'
set 'teacher:10001:age' '35'
set 'teacher:10001:title' '讲师'
set 'teacher:10001:work_year' '5'
set 'teacher:10001:salary' '10000'
sadd 'teacher:10001:course' '计算机组成与设计' '操作系统'
set 'teacher:10002:name' '王五'
set 'teacher:10002:age' '40'
set 'teacher:10002:title' '副教授'
set 'teacher:10002:work_year' '15'
set 'teacher:10002:salary' '20000'
sadd 'teacher:10002:course' '数据库概论' '离散数学'
set 'teacher:10003:name' '刘六'
set 'teacher:10003:age' '38'
set 'teacher:10003:title' '教授'
set 'teacher:10003:work_year' '12'
set 'teacher:10003:salary' '40000'
sadd 'teacher:10003:course' '计算机网络' '通信技术基础'
set 'student:180001:name' '姚驰翰'
set 'student:180001:age' '20'
set 'student:180001:grade' '大三'
set 'student:180001:major' '软件工程'
sadd 'student:180001:course' '数据库概论' '计算机组成与设计'
set 'student:180002:name' '集飞白'
set 'student:180002:age' '20'
set 'student:180002:grade' '大三'
set 'student:180002:major' '计算机科学与技术'
sadd 'student:180002:course' '数据库概论' '计算机网络'
set 'student:190001:name' '世冬萱'
set 'student:190001:age' '19'
set 'student:190001:grade' '大二'
set 'student:190001:major' '信息科学'
sadd 'student:190001:course' '计算机导论与程序设计'
set 'student:190002:name' '忻天玉'
set 'student:190002:age' '19'
set 'student:190002:grade' '大二'
set 'student:190002:major' '电子信息工程'
sadd 'student:190002:course' '计算机导论与程序设计'

插入完成之后,使用 keys * 命令可以查看到所有的 Key。

使用 get 'teacher:10001:name' 可以获取到这个指定 Key 对应的值。中文在存储时会被编码。

对于 Set 类型的数据,可以使用 sadd <key> <value1> <value2> ... 命令追加数据,比如 sadd 'teacher:10001:course' '数据结构'

使用 srem <key> <value1> <value2> ... 可以 Set 中的值。比如 srem 'teacher:10001:course' '数据结构'

还可以求两个 Set 的差集,命令是 sdiff <set_name1> <set_name2>。比如 sdiff 'student:180001:course' 'student:180002:course'

差不多这些就是前面插入数据时涉及到的 Redis 数据结构的一些常用操作了。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇