1. 程式人生 > >十八掌大數據之zk總結

十八掌大數據之zk總結

zk hadoop 大數據

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總結