首先先介绍下集群。就是现在是大数据时代嘛。生活中每天无时无刻都在产生着海量数据,这些数据都是很有价值的,比如分析用户数据可以掌握用户喜好,进行针对推荐之类,医学上分析病人数据可以训练机器人学会看病。那么庞大的数据量用一台机子去计算,无论你的配置有多好,都跟不上撑不住。所以一个任务要有多台机子一起完成,一个任务由多台机子进行计算。这些机子就组成一个集群。而Hadoop中的HDFS模块,也就是Hadoop的分布式文件系统就是专门用的做存储的,就好像一个可以无限扩展的大硬盘,将数据分块存在多台机子,为了防止数据丢失,还冗余多份存储了相同的数据。标红的三个词就是存放在HDFS上的数据的特点。理解了HDFS是个分块冗余的大硬盘,接下来我们就进入正题了。先上图
==================网络配置等环境配置============================
首先就是要让几台机子彼此之间可以通信,这里使用仅主机模式,第一步就是配置各台机子的ip地址等信息,当采用仅主机模式后本机windows会出现一个虚拟网卡,如下图,VMnet1对应的就是仅主机模式,自动分配了192.168.23.1这个ip,因此各台机子ip可以设置成192.168.23.0这个网段,保证处于同一网络通信。
编辑网卡,输入vim /etc/sysconfig/network-scripts/ifcfg-eno16777736,(ifcfg-eno16777736这个名称不一定一样,可以在上层目录先查看下具体名称),删除无用的信息,保留最简单的配置
TYPE=Ethernet |
vim /etc/sysconfig/network配置网关
NETWORKING=yes GATEWAY=192.168.23.2 |
配置完之后systemctl restart network重启网络生效,可以ping下192.168.23.1验证下网络是否通了
hostnamectl set-hostname master1修改主机名
网络通了,就可以通过xshell远程登录到192.168.23.100服务器,更方便操作,可以通过集成的ftp将jdk和hadoop压缩包传输到master机子上
到对应文件目录执行 rpm -ivh jdk-8u91-linux-x64.rpm 解压安装jdk, tar -xvf hadoop-2.7.3.tar.gz解压,会多出hadoop-2.7.3文件夹 mv hadoop-2.7.3 hadoop改个名。
上面是hadoop的配置文件,用的哪个说那个,首先要在hadoop-env.sh指明jdk路径,第一行修改成
export JAVA_HOME=/usr/java/default
再把hadoop执行命令的路径加到环境变量里 vim /etc/profile最后一行加上
export PATH=$PATH:/usr/local/hadoop/bin:/usr/local/hadoop/sbin
到这,我们就把单台机子的Hadoop环境安装好了,接下来就是复制这台配好的机子修改ip,主机名作为 slave1,slave2。
这样就可以通过xshell远程登录到这三台机子,点选项卡排列,我选择垂直排列,如下图
点“工具”》》发送键到所有会话 就可以实现同时在所有窗口输入相同命令,先停止禁用防火墙
systemctl stop firewalld systemctl disable firewalld |
接下来就正式开始了。。。。。。。。。。。。。
========================集群启动=================================
从物理架构上来说,有一个master机器节点与两个slave机器节点。从逻辑架构来说,有一个NameNode和两个DataNode,与master与slave相对应。NameNode是一个管理者,管理着整个文件系统的元数据,包括各种映射信息、文件位置、权限等,管理着DataNode各种活动,不直接存储数据,而是类似于一个文件目录,记录着文件的各个块的数据节点的存储位置,而真正的数据存储包括读取都是在DataNode节点上进行的。HDFS的分块就是指文件被分割成固定大小的块储存在DataNode上,同时每一块通过NameNode会获得一个唯一的id标识,每一块又是冗余存储,默认拷贝三份,每份128M,即使一个节点崩溃也不会造成数据丢失,大大提升了系统的可靠性。当然我们可以通过配置文件修改备份数目。
cd /usr/local/hadoop/etc/hadoop 然后编辑 core-site.xml 记录master所在的位置 slave机器也要知道master在哪台机子上,所以也要编辑
<property> <name>fs.defaultFS</name> <value>hdfs://master1:9000</value> </property> |
修改 /etc/hosts文件
192.168.23.100 master1 192.168.23.101 slave1 192.168.23.102 slave2 |
然后在master上启动namenode,slave上启动datanode,先格式化namenode,在master上执行(Hadoop会将默认将数据存入\tmp目录中,所以当系统重启之后,这些信息可能会丢失,所以重启时需要执行hadoop namenode -format命令。为了避免这种情况,可以在core-site.xml文件中添加一个属性,属性名为dfs.name.dir,值为你想存的目录,只要不保存在\tmp下,就不会遇到重启之后元数据丢失的情况。)
修改好,同样需要格式化一下
hdfs namenode -format |
hadoop-daemon.sh start namenode |
slave1和slave2上执行
hadoop-daemon.sh start datanode |
jps命令查看,如下图则说明namenode datanode启动成功
hdfs dfsadmin -report | more |
可查看集群整体情况
9000是NameNode与DataNode通信用,500070是对外提供的web端口
访问http://192.168.23.100:50070 可查看集群情况
overview是集群总结情况,包含比如存活节点之类的,如下图
DataNode是DataNode具体的情况,utilities中的browser the file system可以查看hdfs文件目录情况,logs则是集群的启动日志
==========================集中式管理slave=================================
用先前方式在每个连接slave窗口同时敲命令,窗口一多可能就观察不过来,因此用集中式管理
master机子上: cd /usr/local/hadoop/etc/hadoop 编辑slaves文件, 记录所有slave机器
这样就能实现统一管理,在master敲命令时自动读取slaves列表 然后依次把命令放到对应机器上执行 ssh slave1也能登录到slave1
master: start-dfs.sh 就能启动一整个集群,stop-dfs.sh关闭整个集群 但是这个过程需要依次输入每个机器(包括master)的密码,所以要先进行免密登录
1 cd 先回到根目录
2 cd .ssh
3 用rsa算法生成公钥和私钥对
ssh-keygen -t rsa |
id_rsa是私钥,id_rsa.pub是公钥。公钥是要发给所有的slave。这样登录信息用私钥加密,如果对方可以用公钥解密那就验证通过
4 拷贝公钥到slave
ssh-copy-id slave1 ssh-copy-id slave2 ssh-copy-id master |
现在无需输入密码了
==============================基本操作============================================
hadoop fs -ls / 查看hdfs储存文件目录 hadoop fs -rm /xxx 删除某根目录下的文件 hadoop fs -put ./xxx / 把当前目录的某文件放入根目录下 |
我把hadoop安装包放到根目录 可以看到块大小128M 因为一共204.17MB所以分为两块 复制三份 点击可查看详情 具体分布在哪台机子上
默认情况下是复制三份,但是因为我就两台从机,因此就只有两份。replication的值可以在hdfs-site.xml中配置,一般情况数据都会往多的备份,我这边示例就改成2
hdfs-site.xml、core-site.xml、yarn-site.xml等默认配置可通过查阅官方文档
- core-default.xml
- hdfs-default.xml
- yarn-default.xml
然后重启集群,改了以后新放入的文件才会根据这个值去复制份数 原有的不会改变
如果有三个从机的话 可以试试让某个从机从集群中移除(模拟宕机),可以发现因为这台从机冗余备份的数据又会到其他机子上存储(就是固定存储2份,其中有一块冗余存储了一份在slave3里,slave3挂掉后,其他机子会备份那一份)
=========================java程序访问=============================
创建java项目,hadoop安装包解压后有相应的jar包,导入\share\hadoop\common\hadoop-common-2.7.3.jar、\share\hadoop\common\lib下的包和\share\hadoop\hdfs\hadoop-hdfs-2.7.3.jar。程序实现读取存放在hdfs的文本文件内容
import java.io.InputStream;
import java.net.URL;
import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
import org.apache.hadoop.io.IOUtils;
public class HelloHDFS {
public static void main(String[] args) throws Exception {
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
URL url = new URL("hdfs://192.168.23.100:9000/hello.txt");
InputStream in = url.openStream();
IOUtils.copyBytes(in, System.out, 4096, true);
}
}
import java.io.InputStream;
import java.net.URL;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
public class HelloHDFS {
public static void main(String[] args) throws Exception {
/* URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
URL url = new URL("hdfs://192.168.23.100:9000/hello.txt");
InputStream in = url.openStream();
IOUtils.copyBytes(in, System.out, 4096, true);*/
Configuration conf = new Configuration();
//对应core-site配置,还能做其他配置,通过java客户端访问hdfs不依赖于原有core-site等配置
//在客户端程序重新写,否则还是按照默认的来
conf.set("fs.defaultFS", "hdfs://192.168.23.100:9000");
FileSystem fs = FileSystem.get(conf);
boolean success = fs.mkdirs(new Path("/yan"));
System.out.println(success);
success = fs.exists(new Path("/hello.txt"));
System.out.println(success);
success = fs.delete(new Path("/yan"),true);
System.out.println(success);
success = fs.exists(new Path("/yan"));
System.out.println(success);
}
}
下面的这种功能更强大,直接对hdfs进行增删查改
接下来将本地文件传到HDFS,涉及到上传下载的功能,先访问namenode节点,由namenode节点管理,比如负载均衡,真正的数据读写由datanode和客户端交互
FSDataOutputStream out = fs.create(new Path("/test.data"),true);
FileInputStream fis = new FileInputStream("D://hello.txt");
IOUtils.copyBytes(fis, out, 4096,true);
用hadoop fs -text /test.data命令查看内容,看看是否和本地的一致
======================yarn资源调度===========================
yarn是hadoop 2.0新增的,统一为上层计算模型做资源调度,主要做CPU资源和内存资源调配,在Hadoop 1.0中不存在,hdfs上一层就是MapReduce计算引擎
引入yarn后,弥补了MapReduce本身的缺陷,还支持多种计算引擎。类似于HDFS由一个namenode管理着多个datanode,yarn也是由一个resourcemanager管理着多个nodemanager。nodemanger通常和datanode放在一起,具体看开篇的那幅图。因为云计算其实就是移动计算,而不是移动数据。移动数据将所有数据集中计算,移动数据过程耗时,而且没有那么大的存储空间,计算更加耗时耗资源,所以采取移动计算,将计算程序移动到各个机子上做计算然后进行汇总。nodemanger就是管理各机子计算的资源分配,所以要和数据放一块可以避免移动数据。resourcemanager管理着所以job(计算任务),nodemanager真正执行计算
开始配置,vim yarn-site.xml,三台机子都要配置
<property>
<name>yarn.resourcemanager.hostname</name>
<value>192.168.23.100</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
配置resourcemanager的位置,我这里放在和namenode同一个物理机。start-yarn.sh启动集群
HDFS与yarn逻辑上是分离的 启动yarn也可以不启动HDFS,8088是对外提供的web端口,访问可查看yarn集群情况
=======================MapReduce==========================
MapReduce是计算引擎,配置mapred-site.xml文件
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
配置运行在yarn上,默认运行单机上,接下来运行hadoop提供的示例wordcount,计算单词数目
- find /usr/local/hadoop -name *example*.jar 查找示例文件
hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar wordcount /hello.txt /wcout1.txt
可以看到计算结果,_success指计算成功,part-r-00000指的一个MapReduce的结果 因为数据较小只有一个文件
=========================================================
惭愧 工作了 两年没写博客了 还是要坚持不能懒。。。。。点个赞支持下