hadoop:
hdfs:分布式存储
MR: 分布式计算
hdfs:
=========================
1、namenode(元数据)、datanode(真实数据)、2nn(检查点)
2、hadoop-daemon.sh start namenode //启动本机进程
hadoop-daemons.sh start datanode //启动slave机器进程
3、namenode:编辑日志(hdfs oev)和镜像文件(oiv)
编辑日志:hdfs对文件的写操作,读取文件不需要修改编辑日志
镜像文件:hdfs文件的元数据,即索引
4、datanode:真实数据、校验和(7字节的头部+每个chunk512字节进行的4字节校验)
5、2nn: 每个3600s对namenode中的数据进行备份
编辑日志和镜像文件的融合:
===============================
1、每进行一次写操作,编辑日志的id都会+1,保存在edits_inprogress中
2、在namenode启动的时候:
namenode处于安全模式状态(safemode),此模式下文件只可读不可写
edits_inprogress实例化为编辑日志文件
老镜像文件和比镜像文件id数大的编辑日志文件加载到内存,重新操作编辑日志的所有操作步骤,并产生新镜像文件
融合过后,safemode自动退出
3、2nn在进行日志滚动的时候
将namenode的edits_inprogress实例化为编辑日志文件
将此编辑日志和namenode中的镜像文件进行fetch(获取),在2nn中进行重新融合
融合之后将新的镜像文件发送给namenode
VERSION
===================================
namenode:
在hadoop工作目录中存在一种对节点的描述性文件
namespaceID=133742883 //namenodeID
clusterID=CID-126a68dc-a8c1-4517-8f28-60fb6af6c269
cTime=0
storageType=NAME_NODE
blockpoolID=BP-1464761855-192.168.23.101-1520907981134
layoutVersion=-63 //布局版本,每次格式化都-1
datanode:
#Sun Mar 25 09:02:26 CST 2018
storageID=DS-6068e606-1d2d-4865-aa62-1cd326ee3e64
clusterID=CID-126a68dc-a8c1-4517-8f28-60fb6af6c269
cTime=0
datanodeUuid=705f0e4e-a50b-4448-84ed-fc6e2f8d2923 //每个datanode的唯一标识
//若所有datanodeUUID都一样,namenode会仅识别所有的datanode的一个
storageType=DATA_NODE
layoutVersion=-56
hdfs文件:
====================================
串行化writable:永久存储和网络间传输
1、紧凑
2、快速
3、可扩展性 //升级
4、支持互操作 //跨平台
压缩:
gzip
deflate
bzip2 //逻辑可切割(在任何位置定位文件数据)
lz4
snappy
lzo //通过加索引的方式实现逻辑可切割
SequenceFile:序列文件(可切割)
扁平化的k-v
同步点:能够定位数据
压缩类型:
不压缩
记录压缩 //只压缩value
块压缩 //压缩k-v
hdfs文件写入流程:
block:块 //128M
packet:包 //block的基本单位,64K
chunk:小块 //packet的基本单位,512字节,是checkSum的校验单位
checksum:校验和 //CRC32C校验,大小4字节
header: //packet的头部,大小33字节
MR过程:
job提交流程:
资源调度机制
Hadoop:大象
Hive:
Hbase:
Zookeeper:
动物管理员
分布式协调框架:
分布式框架的好处:
可靠性:一个或几个节点的崩溃不会导致整个集群的崩溃
可伸缩性:可以通过动态添加主机的方式以及修改少量配置文件,以便提升集群性能
透明性:隐藏系统的复杂性,对用户体现为一个单一的应用
分布式框架的弊端:
竞态条件: 一个或多个主机尝试运行一个应用,但是该应用只需要被一个主机所运行
死锁: 两个进程分别等待对方完成
不一致性: 数据的部分丢失
zk,即分布式协调框架的作用:
名字服务: 标识集群中的所有节点,(节点能够向其注册并产生唯一标识)
配置管理: 存储配置文件,以便共享
集群管理: 添加或删除节点同时,事实更新集群信息
领袖推选机制:
锁和同步服务: 当文件进行修改,会将其进行加锁,防止多用户同时写入
高有效性数据注册:
zk中的文件是同步的:zk中的文件夹,统称为节点
文件内容是树形结构,相当于linux文件系统,只不过是逻辑系统,类似于hdfs
只存在路径和数据:
/ "aaa"
/a
/a/b "hello"
配置文件最大只能存储1M数据:
ZK集群搭建:
本地模式:
1、解压:
tar -xzvf zookeeper-3.4.10.tar.gz -C /soft/
2、创建符号链接
/soft]$ ln -s zookeeper-3.4.10 zk
3、配置环境变量
sudo nano /etc/profile,添加:
export ZK_HOME=/soft/zk
export PATH=$PATH:$ZK_HOME/bin
4、使环境变量生效
source /etc/profile
5、修改${ZK_HOME}/conf/zoo_sample.cfg
将其重命名为zoo.cfg
mv zoo_sample.cfg zoo.cfg
6、启动zk服务
zkServer.sh start
完全分布式:
1、修改zk配置文件
修改dataDir=/home/centos/zk
添加如下配置:
server.102=s102:2888:3888
server.103=s103:2888:3888
server.104=s104:2888:3888
//其中102、103、104称之为myid,在1~255之间的整数
//s102,s103,s104称为对应的ip地址
//2888是leader端口,负责和follower进行通信
//3888是领袖推选端口,负责所有节点进行开会(推选leader)的端口
//3888端口在leader节点也存在
2、修改完成后,分发zk解压目录和zk符号链接
/soft]$ xsync.sh zookeeper-3.4.10
/soft]$ xsync.sh zk
3、切换到root用户,分发环境变量
~]# xsync.sh /etc/profile
4、分别使s102~s104的环境变量生效
s102 ~]$ source /etc/profile
s103 ~]$ source /etc/profile
s104 ~]$ source /etc/profile
4.5、分别在~/zk/创建一个myid文件,内容如下:(提示没有文件夹,则创建zk文件夹)
s102 ~]$ echo 102 > ~/zk/myid
s103 ~]$ echo 103 > ~/zk/myid
s104 ~]$ echo 104 > ~/zk/myid
5、分别启动s102~s104的zk进程
s102 ~]$ zkServer.sh start
s103 ~]$ zkServer.sh start
s104 ~]$ zkServer.sh start
zk相关命令:
QuorumPeerMain是zk的主进程
zkServer.sh status //查看zk的状态
//mode:standalone 处于独立模式
zkServer.sh stop //关闭zk进程
客户端命令:
zkCli.sh //进入zk客户端
zkCli.sh -server s102:2181 //进入zk远程客户端
ls / //列出根下节点(必须用绝对路径)
get / //读取根节点数据(必须用绝对路径)
create /a tom //创建/a节点并添加数据tom
create /b '' //创建空节点
//create命令无法实现递归创建
set /a jerry //修改节点数据
stat /a tom //查看节点状态,和get的区别在于没有数据
//也可以说,在使用get命令同时,返回了stat命令
delete /a/b/c/d/e //删除节点不能有子目录
rmr /a //删除节点,递归删除
quit //退出
ACL:
access control list : 访问控制列表,相当于定义权限
入口点在Zoodef下的Ids接口
zk中三种节点:
持久节点:在zk客户端退出后,不会自动删除 //zkCli默认创建
临时节点:在zk客户端退出后,会自动删除 //可以通过此类型节点来判断分布式服务的连接或断开
序列节点:后缀添加一个自动增长的十位序列号 //可以通过此模式,重复注册相同的节点
编写xzk.sh 脚本: /usr/local/bin/xzk.sh
================================
#!/bin/bash
cmd=$1
if [ $# -gt 1 ] ; then echo param must be 1 ; exit ; fi
for (( i=102 ; i<=104 ; i++ )) ; do
tput setaf 2
echo ================ s$i $@ ================
tput setaf 9
ssh s$i "source /etc/profile ; zkServer.sh $cmd"
done
ZK客户端编程:
====================================
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
1、列出孩子节点:
@Test
public void testList() throws Exception {
//定义连接串:以,分隔 ip:port 客户端端口2181
String conn = "s102:2181,s103:2181,s104:2181";
//param1:连接串;param2:超时时间;param3:观察者,null
ZooKeeper zk = new ZooKeeper(conn, 5000,null);
//
List<String> children = zk.getChildren("/", false);
for (String child : children){
System.out.println(child);
}
}
2、添加节点:
@Test
public void testCreate() throws Exception {
//定义连接串:以,分隔 ip:port 客户端端口2181
String conn = "s102:2181,s103:2181,s104:2181";
//param1:连接串;param2:超时时间;param3:观察者,null
ZooKeeper zk = new ZooKeeper(conn, 5000,null);
//
String s = zk.create("/a", "tomas".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(s);
zk.close();
}
3、递归列出指定路径下所有节点:
public static void testLsChild(String path) {
try {
//定义连接串:以,分隔 ip:port 客户端端口2181
String conn = "s102:2181,s103:2181,s104:2181";
//param1:连接串;param2:超时时间;param3:观察者,null
ZooKeeper zk = new ZooKeeper(conn, 5000,null);
List<String> children = zk.getChildren(path, false);
if (path.endsWith("/")){
for (String child : children){
System.out.println(path+child);
testLsChild(path+child);
}
}
else {
for (String child : children){
System.out.println(path+"/"+child);
testLsChild(path+"/"+child);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
4、获取相应节点数据
5、修改(set)相应节点数据,并指定版本号
版本号version相当于mysql中的锁,字段是自增的
如果在修改时指定版本号和dataVersion不对应,会报badVersion异常
观察者模式:watcher
在get、ls、和stat中有watch参数,此参数设定观察者
如果在以上操作中制定的路径被修改(包括删除或修改数据),则出发watcher的事件
watcher在new Zookeeper的时候实例化,并在节点发生改变时使用回调机制来进行方法调用。
/**
* 测试观察者模式
* @throws Exception
*/
@Test
public void testWatcher() throws Exception {
//定义连接串:以,分隔 ip:port 客户端端口2181
String conn = "s102:2181,s103:2181,s104:2181";
//param1:连接串;param2:超时时间;param3:观察者,null
ZooKeeper zk = new ZooKeeper(conn, 5000, new Watcher() {
public void process(WatchedEvent event) {
Event.EventType type = event.getType();
System.out.println(type.getIntValue());
System.out.println("出事了");
}
});
//
List<String> children = zk.getChildren("/", true);
for (String child : children){
System.out.println(child);
}
for(;;){
Thread.sleep(1000);
}
}
zk的领袖推选机制:leaderElection