搭建虚拟机集群
配置ZooKeeper
只有MapReduce,将代码放在一个独立的JVM进程中运行,一般用作测试代码的逻辑。
只有1台机器的分布式,貌似只会用于机器性能极差的艰苦学习环境的测试。
多台机器构成的分布式,这才是生产环境中实际工作的分布式环境。
ZooKeeper中谁作Leader,谁作Follower并不由人决定,且ZooKeeper是公平节点架构,一般不会穷到只用1台ZooKeeper服务器,也不会豪到用7台以上的ZooKeeper服务器,那么3台/5台组成的ZooKeeper集群,其实谁作Leader是无所谓的,并不需要关心。
HDFS中有2种节点:NameNode和DataNode。
YARN中有2种节点:ResourceManager和NodeManager。
分布式存储与分布式计算,Worker节点的可替代性很强,所有机器都做Worker节点也无妨。但是Manger节点具有决策作用,笔者手头只有3个虚拟机搭建的机器,显然都得同时是2种Worker节点,但是不能允许同一个虚拟机同时是2种Manager节点和2种Worker节点(单节点负载太高容易卡死,负载过于不平衡也就失去了分布式的意义,不管是从性能讲,还是从宕机的影响讲,这种做法都是不合理的)。
安装具有主从架构的工具,需要进行节点规划。
HDFS事实上有3种节点。NameNode会将元数据存储到内存,并在SecondaryNameNode协助下获取快照到硬盘,故NameNode很消耗内存。
参考:SecondaryNameNode
千万不要被字面内容误导!!!
SecondaryNameNode可不是作为备份的NameNode,这就像可锻铸铁(malleable cast iron)实际不可以锻造(会崩碎),高速钢(high speed steel,只能用于低速切削)实际上并不能承受高速切削(3w rpm,这时候一般用粉末冶金/带涂层的硬质合金,或干脆使用PCD刀具)时的高温。。。
进程/节点 | node1 | node2 | node3 |
---|---|---|---|
NameNode | √ | ||
DataNode | √ | √ | √ |
SecondaryNameNode | √ |
node1作为NameNode使用后相对负载已经变高,为了均衡负载,ResourceManager应该放在node2或者node3,笔者放在node3。
进程/节点 | node1 | node2 | node3 |
---|---|---|---|
ResourceManager | √ | ||
NodeManager | √ | √ | √ |
将编译好的Hadoop的安装包上传到node1的/export/software
目录下,并解压到/export/server
:
cd /export/software
rz
tar -zxvf hadoop-2.7.5.tar.gz -C /export/server/
切换到Hadoop解压目录:
cd /export/server/hadoop-2.7.5/
sbin:服务端管理的命令脚本,如果没有sbin,这些管理脚本也会放在bin目录中。
etc:配置文件目录。
lib:依赖库,Hadoop的依赖库不在这个目录中。
share:Hadoop实际的依赖包的存放位置。
logs:服务端运行的日志。
在node1创建配置时需要的目录:
mkdir -p /export/server/hadoop-2.7.5/hadoopDatas/tempDatas
mkdir -p /export/server/hadoop-2.7.5/hadoopDatas/namenodeDatas
mkdir -p /export/server/hadoop-2.7.5/hadoopDatas/datanodeDatas
mkdir -p /export/server/hadoop-2.7.5/hadoopDatas/nn/edits
mkdir -p /export/server/hadoop-2.7.5/hadoopDatas/snn/name
mkdir -p /export/server/hadoop-2.7.5/hadoopDatas/dfs/snn/edits
切换目录,准备修改配置文件:
cd /export/server/hadoop-2.7.5/etc/hadoop/
这些env.sh结尾的文件都是用来配置环境变量的,都要配置JAVA_HOME
环境变量。
echo $JAVA_HOME
查看到之前配置的JAVA_HOME环境变量的位置:/export/server/jdk1.8.0_241
。
vim hadoop-env.sh
vim mapred-env.sh
export JAVA_HOME=/export/server/jdk1.8.0_241
vim yarn-env.sh
export JAVA_HOME=/export/server/jdk1.8.0_241
这一步非常麻烦。。。
以site.xml
结尾的文件都是用户自定义配置(个性化设置)的配置文件。Hadoop有default.xml
结尾的默认配置文件,启动时会先加载这些默认配置文件,加载所有的默认配置(在Hadoop自带的jar包中),再加载所有的用户自定义配置文件,默认配置会被用户自定义配置取代。
要修改的内容很多,继续使用VIM修改会显得很愚蠢。。。笔者使用Notepad++来修改。。。稍微容易些。
这是Hadoop全局属性配置文件,可以进行IO、权限等的配置。
插入:
<property>
<name>fs.defaultFS</name>
<value>hdfs://node1:8020</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/export/server/hadoop-2.7.5/hadoopDatas/tempDatas</value>
</property>
<property>
<name>io.file.buffer.size</name>
<value>4096</value>
</property>
<property>
<name>fs.trash.interval</name>
<value>10080</value>
</property>
按ctrl+s
保存。最好到命令行cat core-site.xml
看看有木有保存成功。
fs.defaultFS
:指定了HDFS入口的地址,用于读写请求,代表了NameNode的机器的地址,8020
是读写内部请求端口,走RPC
协议。
hadoop.tmp.dir:Hadoop的临时数据存储目录。
fs.trash.interval:回收站的自动清理时间,如果为0,表示不开启回收站。
这是HDFS配置文件。
相同的方式插入内容,不再赘述:
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>node1:50090</value>
</property>
<property>
<name>dfs.namenode.http-address</name>
<value>node1:50070</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///export/server/hadoop-2.7.5/hadoopDatas/namenodeDatas</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///export/server/hadoop-2.7.5/hadoopDatas/datanodeDatas</value>
</property>
<property>
<name>dfs.namenode.edits.dir</name>
<value>file:///export/server/hadoop-2.7.5/hadoopDatas/nn/edits</value>
</property>
<property>
<name>dfs.namenode.checkpoint.dir</name>
<value>file:///export/server/hadoop-2.7.5/hadoopDatas/snn/name</value>
</property>
<property>
<name>dfs.namenode.checkpoint.edits.dir</name>
<value>file:///export/server/hadoop-2.7.5/hadoopDatas/dfs/snn/edits</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
<property>
<name>dfs.blocksize</name>
<value>134217728</value>
</property>
保存。
dfs.namenode.secondary.http-address:SecondaryNameNode进程的地址和HTTP协议端口。
dfs.namenode.http-address:NameNode进程开放的HTTP协议端口。
50070:NameNode开放的HTTP协议端口,用于网页访问。
这是MapReduce的配置文件。但是路径下只有mapred-site.xml.template
模板。先改名:
cd /export/server/hadoop-2.7.5/etc/hadoop
mv mapred-site.xml.template mapred-site.xml
再插入:
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.job.ubertask.enable</name>
<value>true</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>node2:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>node2:19888</value>
</property>
mapreduce.framework.name:将MapReduce程序运行在YARN上。
这货是YARN的配置文件。
插入:
<property>
<name>yarn.resourcemanager.hostname</name>
<value>node3</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>8192</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>2048</value>
</property>
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>2.1</value>
</property>
yarn.resourcemanager.hostname:指定ResourceManager所在的机器。
yarn.nodemanager.aux-services:YARN上运行的程序的类型。
slaves决定了DataNode和NodeManager启动在哪台机器,默认为localhost(也就是127.0.0.1,显然不是集群)。修改内容为:
node1
node2
node3
都切换目录:
cd /export/server/
使用ll -ah
查看3个节点的目录内的内容正常(之前有相关路径或文件需要想办法干掉,防止出问题)。
scp -r hadoop-2.7.5 node2:$PWD
scp -r hadoop-2.7.5 node3:$PWD
使用node1分发给node2和node3。
再次使用ll -ah
查看3个节点的目录内的内容,确保成功分发。
3个节点同时:
vim /etc/profile
#HADOOP_HOME
export HADOOP_HOME=/export/server/hadoop-2.7.5
export PATH=:$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
source /etc/profile
同时在命令行执行,3个节点都重置环境变量。
只有集群搭建好之后首次启动才需要格式化HDFS。
在node1使用hdfs namenode -format
执行格式化命令:
出现这个状态0的正常退出,说明格式化成功。
如果报错,大概率是配置文件写错了,但是不能直接重新格式化(元数据已经存储了一些信息,重新格式化会导致映射关系等出错)。正确的重新格式化顺序:
先删除原先的数据文件夹:
rm -rf hadoopDatas/
再重新创建所有目录:
mkdir -p /export/server/hadoop-2.7.5/hadoopDatas/tempDatas
mkdir -p /export/server/hadoop-2.7.5/hadoopDatas/namenodeDatas
mkdir -p /export/server/hadoop-2.7.5/hadoopDatas/datanodeDatas
mkdir -p /export/server/hadoop-2.7.5/hadoopDatas/nn/edits
mkdir -p /export/server/hadoop-2.7.5/hadoopDatas/snn/name
mkdir -p /export/server/hadoop-2.7.5/hadoopDatas/dfs/snn/edits
最后重新格式化:
hdfs namenode -format
在node1的命令行:
hadoop-daemon.sh start namenode
集群的3个节点都需要:
hadoop-daemon.sh start datanode
浏览器输入:node1:50070
在node3的命令行:
yarn-daemon.sh start resourcemanager
3个节点都需要:
yarn-daemon.sh start nodemanager
浏览器访问:node3:8088
8032
:内部任务提交端口,走的RPC
协议。
8088
:网页服务端口,走的HTTP
协议
实现WordCount词频统计,统计文件中每个单词出现的次数。
上传文件到node1:
cd /export/data/
hdfs dfs -mkdir -p /wordcount/input
将存储在node1的Linux系统存储的文件上传到HDFS中:
hdfs dfs -put /export/data/wc.txt /wordcount/input/
查看是否成功:
hdfs dfs -ls /wordcount/input
Hadoop中自带了这个MapReduce程序:
/export/server/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.5.jar
yarn jar /export/server/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.5.jar wordcount /wordcount/input/wc.txt /wordcount/output1
使用win10自带的记事本打开wc.txt,好家伙。。。数据量再扩充几倍,单机性能不足宿主机就要挂了。。。
切换目录:
cd /export/server/hadoop-2.7.5/
开始写入:
yarn jar share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -write -nrFiles 10 -size 10MB
计算完成后可以看到报表:
这还是扔SSD盘,写入居然只有6M/s!!!这也太尼玛慢了。。。
开始读取:
yarn jar share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -read -nrFiles 10 -size 10MB
hdfs dfs -rm -r -skipTrash /benchmarks
顺带把之前wc.txt也干掉:
使用:
hdfs dfs -rm -r /wordcount
显示:
[root@node1 hadoop-2.7.5]# hdfs dfs -rm -r /wordcount
21/04/23 20:53:00 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 10080 minutes, Emptier interval = 0 minutes.
21/04/23 20:53:00 INFO fs.TrashPolicyDefault: Moved: 'hdfs://node1:8020/wordcount' to trash at: hdfs://node1:8020/user/root/.Trash/Current/wordcount
Moved: 'hdfs://node1:8020/wordcount' to trash at: hdfs://node1:8020/user/root/.Trash/Current
握草!!!扔回收站了!!!
顺着找到这个文件:
hdfs dfs -ls /user/root/.Trash/Current/wordcount
hdfs dfs -rm -r -skipTrash /user/root/.Trash/Current/wordcount
hdfs dfs -rm -r -skipTrash /wordcount/input
使用了-skipTrash
后可以不经过回收站直接删除。可能Hadoop默认扔回收站的做法是安全的。。。但是删2遍有时候很麻烦。