大数据-hdfs技术
理论基础:GFS----HDFS;MapReduce---MapReduce;BigTable----HBase
项目网址:http://hadoop.apache.org/
下载路径:https://archive.apache.org/dist/hadoop/common/
主要模块
-
Hadoop Common
-
Hadoop Distributed File System
hdfs 分布式文件系统,存储数据
-
Hadoop YARN
资源协调框架
-
Hadoop MapReduce
大数据计算框架
-
Hadoop Ozone
对象存储框架
-
Hadoop Submarine
机器学习引擎
分布式文件系统hdfs
Hadoop Distributed File System文件管理工具,实现文件系统与硬盘的解耦,执行MapReduce计算的基础
hdfs中文件默认拆分为默认128M的块block(除了最后一块),通过偏移量确认块的顺序,每个块默认3个备份。
文件存储有无法修改,可以追加(不推荐),一般用于存储历史数据。
在文件存储时可以指定块大小和备份数,存储完成后只能对备份数进行修改
hdfs存储原理
基础版本
宏观方面
NameNode(NN)
-
接收客户端的数据请求
-
管理分布式文件系统,主要管理文件的映射关系。
-
分布式文件目录
-
文件目录与文件的对应关系
-
文件与块的映射关系,文件对应的块,块存放的DN节点
-
-
块与DN的映射存放在NN内存中
利于快速查找
掉电易失,内存占满会宕机
不适合存放小文件,小文件内存占用过大,
-
NN与DN保持心跳
-
启动状态,NN收集DN汇报的Block信息,建立block与DN的映射
-
启动后
DN默认3秒向NN汇报存活
若DN失联10min认为失联,则NN将失联DN的中的块备份到其他DN上
-
DataNode(DN)
-
存储真实数据文件,也就是block
-
每个block对应一份元数据,通过元数据校验block的是否损坏
-
与NN保持心跳
启动时:验证本地block完整性后向NN汇报所存储的块信息
启动后:3秒向NN汇报存活
-
DN的存储介质是硬盘
SecondaryNameNode
用于解决NN掉电易失的问题,主要方案是:日志+快照
日志及快照的路径为/var/sxt/hadoop/ha/dfs/name/current ,其中的VERSION文件存有集群信息
hdfs的每个操作都会存到日志文件中(edits_inprogress_0000000000000010924)
hdfs设置有日志文件的检查点(checkpoint),当满足任一检查点时,执行日志合并
-
fs.checkpoint.size 默认64M,日志文件大小
-
fs.checkpoint.period 默认3600秒,间隔时间
日志合并流程
-
SecondaryNameNode从NN拉取当前日志文件,NN创建新的日志文件来执行hdfs任务
-
SecondaryNameNode将拉取的日志文件与内部原有的快照文件合并,生成新的快照文件及其验证md5文件(fsimage_0000000000000010755和fsimage_0000000000000010755.md5)
-
SecondaryNameNode将生成的快照及验证返回给NN,使得SecondaryNameNode同时存在快照
-
NN验证接收的快照,并修改原有日志文件作为历史日志文件保存(edits_0000000000000010922-0000000000000010923)
这样开机时,只需要内存从镜像恢复,并重做最多64M日志文件,实现快速开机
nn会将当前(上次关机时)的fsimage与最新的日志进行合并产生新的fsimage
微观方面
HA版本
宏观方面
微观方面
下载
NN关闭时不会存储DN的映射记录,开机有依靠DN汇报机制重新生成映射
hdfs的环境搭建
基本配置(两种环境都搭建)
-
3台以上相互免秘钥的主机,安装jdk并配置JAVA_HOME与环境变量
-
主节点中预先准备:
-
将hadoop-2.6.5.tar.gz解压到/opt/sxt目录下
-
tar -zxvf hadoop-2.6.5.tar.gz
-
mv hadoop-2.6.5 /opt/sxt/
-
cd /opt/sxt/hadoop-2.6.5/etc/hadoop/
-
-
配置/opt/sxt/hadoop-2.6.5/etc/hadoop/目录下的
hadoop-env.sh的25行,mapred-env.sh的16行,yarn-env.sh的23行的java_home路径(mapred-env.sh和yarn-env.sh可以不用改)
-
hadoop1.0搭建
具备一个NN,一个SecondaryNameMode,三个DN
-
安装hadoop
-
修改/opt/sxt/hadoop-2.6.5/etc/hadoop下的配置文件
-
core-site.xml 配置NN与hadoop路径
<property>
<name>fs.defaultFS</name>
<value>hdfs://node1:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/var/sxt/hadoop/full</value>
</property> -
hdfs-site.xml hdfs配置
主要配置secondary与文件备份数
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>node2:50090</value>
</property>
<property>
<name>dfs.namenode.secondary.https-address</name>
<value>node2:50091</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property> -
slaves配置DN
node1
node2
node3
-
-
将Hadoop文件拷贝到其他节点,并创建hadoop目录/var/sxt/hadoop/full
-
配置环境变量vim /etc/profile,复制到其他节点,同步添加环境变量source /etc/profile
export JAVA_HOME=/usr/java/jdk1.7.0_67
export HADOOP_HOME=/opt/sxt/hadoop-2.6.5
export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH -
格式化NN节点 hdfs namenode -format
-
启动集群start-dfs.sh,通过jsp查看各节点进程
-
关机快照
hadoop2.x的HA集群搭建
ZooKeeper集群
-
解压zookeeper
-
tar -zxvf zookeeper-3.4.6.tar.gz
-
mv zookeeper-3.4.6 /opt/sxt/
-
cd /opt/sxt/zookeeper-3.4.6/conf
-
-
拷贝配置文件
-
cp zoo_sample.cfg zoo.cfg 将根据配置示例文件创建配置文件
-
修改zoo.cfg中以下内容:
-
dataDir=/var/sxt/zookeeper 指定zookeeper数据目录
-
clientPort=2181 指定zookeeper客户端的访问端口
-
server.1=node1:2888:3888 指定zookeeper客户机及内部的访问端口 server.2=node2:2888:3888 server.3=node3:2888:3888
-
-
-
配置Zookeeper的环境变量
vim /etc/profile
export JAVA_HOME=/usr/java/jdk1.7.0_67
export ZOOKEEPER_HOME=/opt/sxt/zookeeper-3.4.6
export PATH=$JAVA_HOME/bin:$ZOOKEEPER_HOME/bin:$PATH -
将zookeeper安装包和环境变量配置文件拷贝到其他主机
-
scp -r /opt/sxt/zookeeper-3.4.6/ root@node2:/opt/sxt/
-
scp -r /opt/sxt/zookeeper-3.4.6/ root@node3:/opt/sxt/
-
scp -r /etc/profile root@node2:/etc/profile
-
scp -r /etc/profile root@node3:/etc/profile
-
-
3节点统一执行
-
mkdir -p /var/sxt/zookeeper 创建zookeeper数据目录,与zoo.cfg 中指定路径一致
-
source /etc/profile 添加环境变量
-
-
指定各zookeeper节点的权值,权值越大分配可能越高
-
nide1执行echo 1 > /var/sxt/zookeeper/myid
-
nide2执行echo 2 > /var/sxt/zookeeper/myid
-
nide2执行echo 3 > /var/sxt/zookeeper/myid
-
-
启动Zookeeper集群并查看启动状态
-
zkServer.sh start
-
zkServer.sh status 结果为2个follower和1个leader
-
zkServer.sh stop
-
-
关闭拍快照
Hadoop-HA集群
-
配置core-site.xml核心xml文件
-
fs.defaultFS中配置hadoop集群名,与hdfs-site.xml中的dfs.nameservices对应
-
ha.zookeeper.quorum中配置zookeeper集群的主机和连接端口
-
hadoop.tmp.dir中配置hadoop文件存放路径
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://shsxt</value>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>node1:2181,node2:2181,node3:2181</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/var/sxt/hadoop/ha</value>
</property>
</configuration>
-
-
配置hdfs-site.xml hdfs的配置文件
-
dfs.nameservices配置NN集群名
-
dfs.ha.namenodes.shsxt配置NN集群各主机,属性名与NN集群名匹配,也就是其中的shsxt
-
dfs.namenode.rpc-address.shsxt.nn1与dfs.namenode.rpc-address.shsxt.nn2配置每个NN的主机名及内部连接端口,用于eclipse连接
-
dfs.namenode.http-address.shsxt.nn1与dfs.namenode.http-address.shsxt.nn2配置每个NN的主机名及外部连接端口
-
dfs.namenode.shared.edits.dir配置JournalNode的主机名与端口
-
dfs.journalnode.edits.dir配置JournalNode的文件目录
-
dfs.client.failover.proxy.provider.shsxt配置故障切换代理类,使用默认
-
dfs.ha.fencing.methods配置切换方式,sshfence通过ssh进行切换,shell(true)为避免脑裂指定设置断线NN
-
dfs.ha.fencing.ssh.private-key-files免密钥,使用dsa
-
dfs.ha.automatic-failover.enabled自动故障切换
-
dfs.replication文件的备份数
<property>
<name>dfs.nameservices</name>
<value>shsxt</value>
</property>
<property>
<name>dfs.ha.namenodes.shsxt</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.shsxt.nn1</name>
<value>node1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.shsxt.nn2</name>
<value>node2:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.shsxt.nn1</name>
<value>node1:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.shsxt.nn2</name>
<value>node2:50070</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node1:8485;node2:8485;node3:8485/shsxt</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/var/sxt/hadoop/ha/jn</value>
</property>
<property>
<name>dfs.client.failover.proxy.provider.shsxt</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
<value>shell(true)</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_dsa</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
-
-
配置slaves中的DN节点
node1 node2 node3
-
配置环境变量文件/etc/profile
export JAVA_HOME=/usr/java/jdk1.7.0_67
export HADOOP_HOME=/opt/sxt/hadoop-2.6.5
export ZOOKEEPER_HOME=/opt/sxt/zookeeper-3.4.6
export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$ZOOKEEPER_HOME/bin:$PATH -
将环境变量文件与hadoop安装文件拷贝到其他节点中
-
scp /etc/profile root@node2:/etc/profile
-
scp /etc/profile root@node3:/etc/profile
-
scp -r /opt/sxt/hadoop-2.6.5/ root@node2:/opt/sxt/
-
scp -r /opt/sxt/hadoop-2.6.5/ root@node3:/opt/sxt/
-
-
执行环境变量配置 [123] source /etc/profile
-
创建hadoop数据目录 [123] mkdir -p /var/sxt/hadoop/ha/jn
-
启动ZooKeeper
-
[123] zkServer.sh start
-
[123] zkServer.sh status
-
-
启动JournalNode
-
[123]hadoop-daemon.sh start journalnode
-
-
格式化NameNode
-
[1]hdfs namenode -format 格式化主NN
-
[1]hadoop-daemon.sh start namenode 单独启动主NN
-
[2]hdfs namenode -bootstrapStandby 格式化SNN
-
-
格式化ZKFC [1]hdfs zkfc -formatZK
-
启动集群 [1]start-dfs.sh
-
首次启动后,之后通过此命令启动hadoop,注意需要提前启动ZooKeeper
-
-
执行存储查看结果
hdfs dfs -mkdir -p /shsxt/java
hdfs dfs -D dfs.blocksize=1048576 -put jdk-7u67-linux-x64.rpm /user/root
-
关机快照
hdfs命令
网络访问地址
hdfs-site.xml中NN的http访问地址
-
192.168.163.201:50070与192.168.163.202:50070
-
node1:50070和node2:50070(需要配置win的hosts文件)
启动集群
启动集群
-
全部主机zkServer.sh start
-
选取一个NN执行 start-dfs.sh
关闭集群
-
NN节点执行:stop-dfs.sh
-
全部节点执行:zkServer.sh stop
查看集群运行状态jps
jps查看各主机中的运行进程:
1393 NameNode NN节点 1486 DataNode DN节点 1644 JournalNode JN节点 1799 DFSZKFailoverController ZKFC故障切换控制器 1274 QuorumPeerMain ZK(zookeeper节点) 1891 Jps
单独节点开关
-
hadoop-daemon.sh start namenode 单独开启某个NN
-
hadoop-daemon.sh stop namenode 单独关闭某个NN
上传下载命令
hdfs目录创建
hdfs dfs -mkdir -p hdfs目录
eg:hdfs dfs -mkdir -p /sxt/bigdata 在hadoop中创建/sxt/bigdata目录
文件上传
hdfs dfs -D 块大小 -put 上传的文件 hdfs目录
eg:hdfs dfs -D dfs.blocksize=1048576 -put tomcat /sxt/bigdata
eclipse访问
win配置
解压eclipse,将hadoop-eclipse-plugin-2.6.0.jar文件置入eclipse的plugins目录中。
解压hadoop-2.6.5.tar.gz将解压后的软件放在:D:\worksoft\目录下。解压bin.zip并将内容替换复制到D:\worksoft\hadoop-2.6.5.tar.gz\bin目录下。
配置环境变量
-
HADOOP_HOME
D:\worksoft\hadoop-2.6.5.tar.gz
-
HADOOP_USER_NAME
root
-
PATH中添加 %HADOOP_HOME%/bin;%HADOOP_HOME%/sbin
连接配置
打开eclipse,打开map-reduce视图。在map-reduce中创建新的连接,HA集群分别配置两个NN节点的连接
-
自定义连接名Location name
-
取消 DFS Master的勾选
Host修改为node1(NameNode)
Port修改为8020与hdfs-site.xml中的rpc-address属性匹配
-
User name修改为root
在侧边框中测试文件上传下载
java上传下载测试
-
创建java项目,导入IDE默认的JUnit4的jar包,导入hadoop的自定义jar包
-
从hadoop软件的share文件夹中拷贝各模块及其lib中的121个jar文件,到统一文件中,通过自定义依赖导入项目中
-
将集群的core-site.xml和hdfs-site.xml文件导入项目中作为资源文件
代码部分
使用测试用例在@Before配置hdfs和hadoop配置,在@After中断开hdfs连接
-
before
-
Configuration config =new Configuration(true)
-
fileSystem =FileSystem.get(config)
-
-
After
-
fileSystem.close()
-
通过hadoop提供的Configuration,FileSystem,Path,IOUtils实现上传下载
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IOUtils; public class MyHDFS { //将处理化的内容作为成员变量供使用 Configuration config; FileSystem fileSystem; @Before public void init() throws IOException{ //执行初始化 //读取皮配置 config =new Configuration(true); //获取分布式文件系统 fileSystem =FileSystem.get(config); } @After public void destory() throws IOException{ //执行连接销毁 fileSystem.close(); } //验证目录存在验证 @Test public void exists() throws IOException{ Path path=new Path("/shsxt/java"); System.out.println(fileSystem.exists(path)); } //文件上传验证 @Test public void upload() throws Exception{ //创建本地输入流,输入文本文件 InputStream in=new FileInputStream("D:\\123.txt"); //获取输出流,通过文件系统获取指定路径的输出流 OutputStream out=fileSystem.create(new Path("/shsxt/java/123.txt")); //通过hadoop的传输工具实现流的传输 IOUtils.copyBytes(in, out, config); } //文件下载验证 @Test public void download() throws Exception{ //声明字节流进行接收 ByteArrayOutputStream out=new ByteArrayOutputStream(); //从DFS获取指定文件或目录的输入流 InputStream in=fileSystem.open(new Path("/shsxt/java/123.txt")); //通过流传输获取字符串数据 int len = 0; byte[] buffer = new byte[1024]; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } String words = new String(out.toByteArray(), "GB2312"); } }