十八掌大數據之zk總結
zookeeper
---------------
動物園管理員。
開源框架,用於分布式協同。
集中式服務,配置信息、命名服務、分布式同步、分組。
架構簡單、API解決了分布式環境下復雜的協同配置。
安裝zk(本地模式,單機版)
--------------
1.下載
zookeeper-3.4.10.tar.gz
2.tar
$>tar -xzvf zookeeper-3.4.10.tar.gz -C /soft/
3.配置環境變量
ZOOKEEPER_HOME=/soft/zk
PATH=...:
配置zk(本地模式,單機版)
---------------
1.創建配置文件。
[zk/conf/zoo.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2
2.啟動zk服務器
$>zk/bin/zkServer.sh --help //幫助
$>zk/bin/zkServer.sh start //啟動服務器
$>zk/bin/zkServer.sh stop //停止服務器
$>zk/bin/zkServer.sh restart //重啟服務器
3.驗證服務器是否啟動ok
$>netstat -anop | grep 2181
4.啟動cli命令行
$>zkCli.sh
5.進入命令行
$zk>help //查看zk幫助
$zk>ls / //列出根目錄
$zk>get /zookeeper //查看節點數據
$zk>create /a tom //創建節點,不能越級創建多級節點。
$zk>set /a tomas //更新節點數據
$zk>delete /a //刪除節點,不可刪除非空節點
$zk>rmr /a //遞歸刪除節點
ACL
--------
//權限。
access control list,訪問控制列表。
通過API方式訪問zk
-----------------
1.創建模塊添加pom的依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.it18zhang</groupId>
<artifactId>MyZooKeeper</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
</project>
2.編寫
package com.it18zhang.zk.test;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.junit.Test;
import java.io.IOException;
/**
* Created by Administrator on 2017/6/6.
*/
public class TestCRUD {
/**
* 創建zk路徑
*/
@Test
public void createPath() throws Exception {
ZooKeeper zk = new ZooKeeper("s202:2181",5000,null);
//final String path, byte data[], List<ACL> acl,CreateMode createMode
//路徑
//數據
//ACL列表,控制權限
//節點類型,持久化節點。
String str = zk.create("/a/a2","tomson".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
System.out.println(str);
}
/**
* get路徑
*/
@Test
public void getPath() throws Exception {
ZooKeeper zk = new ZooKeeper("s202:2181",5000,null);
//final String path, byte data[], List<ACL> acl,CreateMode createMode
//路徑
//數據
//ACL列表,控制權限
//節點類型,持久化節點。
byte[] bytes = zk.getData("/a/a2",null,null);
System.out.println(new String(bytes));
}
}
在單機上配置zk集群
--------------------
[201]
1.創建多個配置文件,每個server對應一個.
[conf/zoo1.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data1
clientPort=2181
initLimit=5
syncLimit=2
server.1=localhost:2887:3887
server.2=localhost:2888:3888
server.3=localhost:2889:3889
[conf/zoo2.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data2
clientPort=2182
initLimit=5
syncLimit=2
server.1=localhost:2887:3887
server.2=localhost:2888:3888
server.3=localhost:2889:3889
[conf/zoo3.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data3
clientPort=2183
initLimit=5
syncLimit=2
server.1=localhost:2887:3887
server.2=localhost:2888:3888
server.3=localhost:2889:3889
2.創建每個服務器對應的myid文件,在各自的配置目錄下
$>echo 1 >> ~/zookeeper/data1/myid
$>echo 2 >> ~/zookeeper/data2/myid
$>echo 3 >> ~/zookeeper/data3/myid
3.啟動服務器集群
$>zk/bin/zkServer.sh start /soft/zk/conf/zoo1.cfg
$>zk/bin/zkServer.sh start /soft/zk/conf/zoo2.cfg
$>zk/bin/zkServer.sh start /soft/zk/conf/zoo3.cfg
4.查看進程
$>zk/bin/zkServer.sh status /soft/zk/conf/zoo1.cfg
$>zk/bin/zkServer.sh status /soft/zk/conf/zoo2.cfg
$>zk/bin/zkServer.sh status /soft/zk/conf/zoo3.cfg
5.leader切換演示
$>zk/bin/zkServer.sh stop /soft/zk/conf/zoo1.cfg
$>zk/bin/zkServer.sh status /soft/zk/conf/zoo2.cfg
搭建完全分布式的zk集群
-----------------------
1.選擇s202 ~ s204作為zk的集群
2.配置
2.1)s202
[zk/conf/zoo.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2
server.1=s202:2888:3888
server.2=s203:2888:3888
server.3=s204:2888:3888
[~/zookeeper/myid]
1
2.2)s203
[zk/conf/zoo.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2
server.1=s202:2888:3888
server.2=s203:2888:3888
server.3=s204:2888:3888
[~/zookeeper/myid]
2
2.3)s204
[zk/conf/zoo.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2
server.1=s202:2888:3888
server.2=s203:2888:3888
server.3=s204:2888:3888
[~/zookeeper/myid]
3
3.分別啟動zk服務器
zkServer.sh start //s202
zkServer.sh start //s203
zkServer.sh start //s204
4.驗證狀態
zkServer.sh status //s202
zkServer.sh status //s203
zkServer.sh status //s204
5.zk客戶端使用多臺主機連接串
$>zkCli.sh -server s202:2181,s203:2181,s204:2182
6.API編程方式
String hosts = "s202:2181,s203:2181,s204:2181";
ZooKeeper zk = new ZooKeeper(hosts, 5000, null);
zk架構
---------------------
Client-Server架構。
[組件]
1.client
client是集群中的一個節點,以固定的間隔時間向server發消息,表示自己還健在。
連接時,server會向client回傳ack確認消息。
如果client沒有收到ack消息,自動重定向到另外一臺server.
2.server
zk集群中的一個節點,向client提供所有服務。
向client發送ack消息,表明server還健在。
3.Ensemble
zk集群,成組的最小數是3.
4.leader
如果連接的節點掛掉,自動執行恢復工作。服務啟動是選舉出leader。
5.Follower
服務器節點,執行leader的指令。
zk中的名字空間等結構
---------------------
znode對應每個路徑。
1.根節點是"/",
2.每個節點的存放數據量上限1M.每個節點關聯數據,稱之為zookeeper data model.
3.每個節點都有stat信息,包含內容:
3.1)VERSION號
是數據版本,數據改變時,版本增加。
3.2)ACL(Action control list)
訪問控制列表。
權限控制,管理節點是否能夠read、write。。。
3.3)Timestamp:
從節點創建時逝去的時間,毫秒數,zxid記錄的操作次數。
3.4)存儲在節點上數據總長度。
節點類型
--------------------
1.Persistence
持久化節點。
2.Ephemeral
臨時節點。
只在client回話期間有效,client連接斷開,臨時節點自動刪除。
臨時節點不能有子節點。
leader推選時使用了臨時節點。
3.Sequential
序列節點。
序列節點可以是臨時的也可以是永久的,
創建序列節點,zk會關聯一個10個數位的序號到你的名字後面。
並發創建同名節點時,zk會自動加序號避免沖突。
類似於mysql的字段自增。
session
-------------------
zk中的請求以FIFO方式處理。client連接到server之後,就建立了session,並且server
指派一個sessionid給client.
client周期性發送心跳信息給server,保證session有效的。服務器超過周期時間仍然沒有
到心跳信息(session超時),表示client掛了。
session超時通常以毫秒數表示,session結束時,創建的臨時節點會被刪除。
Watches
---------------------
client在zk服務器狀態data發生改變時,收到通知。
client讀取特定節點時,可以設置觀察者。
在所觀測的path上發生了改變,zk會發送通知給設置了該path為觀測對象的client。
節點的數據發生了改變或者子節點改變。
觀察者只觸發一次。
如果client想再次收到通知,還需要再進行讀取設置。
session超時,client斷開連接,觀察解除了。
/**
* 測試觀察者
* @throws Exception
*/
@Test
public void testWatch() throws Exception {
String hosts = "s202:2181,s203:2181,s204:2181";
ZooKeeper zk = new ZooKeeper(hosts, 5000, null);
byte[] data = zk.getData("/a/a1", new Watcher() {
public void process(WatchedEvent event) {
System.out.println("有人改數據!!!");
}
},null);
System.out.println(new String(data));
while(true){
Thread.sleep(1000);
}
}
zk工作機制
-----------------
client連接到的server可以是leader也可以是follower,
連接一旦建立,server回傳ack和sessionid給client。
client沒有收到ack消息,嘗試重連其他node。
連接建立後,client周期性發送心跳信息給node,卻表session不會丟失。
1)client讀取指定服務器的數據,發送read請求給特定服務器,服務器讀取自己的數據庫返回信息。
速度較快。
2)client如果寫操作,client發送path和data給server,server轉發請求給leader,leader再派發請求
給所有follower,多數node成功響應的話,寫請求就是成功的。否則就是失敗的。
zk中的節點
---------------
1)一個節點,SPOF.
2)兩個節點,沒有過半,和(1)一樣。
3)三個節點,允許一臺機器掛掉,生產環境下可以配置的。
4)write
leader轉發給所有node,有過半響應就ok了。
5)read
和連接的node交互,不需要所有server參與。
6)副本數據庫
每個節點有自己的數據庫並且內容一致。
7)leader
負責寫操作。
8)follower
接受寫請求,轉發給leader.
9)請求處理器
只存在於leader節點,管理follower節點的寫請求。
10)原子廣播
leader向follower節點廣播響應消息。
leader推選
-------------------
1.所有node都以相同路徑創建臨時序列znode,/app/leader_election/guid_
2.zk追加數字串給path
/app/leader_election/guid_0000000001
/app/leader_election/guid_0000000002
3.znode序號最小的成為leader,其他就是follower
4.每個follower都觀察比自己小的znode.
例如節點0008觀察0007 , 007觀察006.
5.如果leader掛了,對應的znode刪除了。
6.下個follower會通過watcher機制收到通知,因為leader的node被刪除了。
7.該follower會查找是否有其他節點有著最小序號,如果沒有,自己就成為leader,
否則最小的成為leader.
8.所有其他節點也都會選擇最小序號的znode作為leader
改造hadoop HA實現自動容災
---------------------------
1.組件
zk集群和zk容災控制器(ZKFC,只在NN).
a)故障檢測
每個NN都維護了zk的持久化session,如果宕機,session就會超時,通知其他NN應該觸發容災。
b)active nn選舉
active節點宕機,另一個NN采用獨占鎖,表示將成為下一個active.
ZKFC,運行在NN上,責任如下:
a)健康狀態監控,zkfc周期使用health-check命令ping本地的NN,
zkfc收到回應,認為nn是健康態,否則是不健康,健康監視器會標記他為不健康
b)zk session管理,如果本地NN是健康的,zkfc就會持有zk集群的session。如果本地NN是active,
zkfc持有一個特殊lock,該鎖使用的zk的臨時節點,如果session超時,lock節點自動刪除。
c)基於zk的選舉,如果本地NN健康的,zkfc知道其他節點沒有持有該lock節點,他會嘗試進行鎖定。如果成功,
該節點就贏得了選舉,開始容災,本地NN成為Active,方式類似於手動容災,先保護上一個active nn,本節點進行狀態切換.
2.部署zk集群
略.
4.配置hadoop自動容災控制器
[hdfs-site.xml]
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
[core-site.xml]
<property>
<name>ha.zookeeper.quorum</name>
<value>s202:2181,s203:2181,s204:2181</value>
</property>
5.在其中的一個NN上運行如下命令,來完成在zk中初始化ha狀態。
該命令在zk中創建自動容災節點,存放數據。
$>hdfs zkfc -formatZK
6.啟動集群
a)可以通過start-dfs.sh開啟所有hdfs進程
$>start-dfs.sh
b)也可以單獨啟動zkfc進程
hadoop-daemon.sh --script /soft/hadoop/bin/hdfs start zkfc
實操
---------------
1.切換hadoop集群到ha配置
[s201]
$>xcall.sh "ln -sfT /soft/hadoop/etc/ha /soft/hadoop/etc/hadoop"
2.修改配置文件並分發
[hdfs-site.xml]
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
3.修改core-site.xml並分發
<property>
<name>ha.zookeeper.quorum</name>
<value>s202:2181,s203:2181,s204:2181</value>
</property>
4.格式化zk
$>hdfs zkfc -formatZK
5.啟動集群
$>start-dfs.sh
十八掌大數據之zk總結