分佈式協調技術
1、分佈式協調技術主要用來解決分佈式環境中多個進場之間的同步控制,讓他們有序的去訪問某種臨界資源,方式早餐"髒數據的後果"。
2、爲了防止分佈式系統中各個進程之間相互干擾,我們需要一種分佈式協調技術進行調度,這個分佈式協調的核心是分佈式鎖技術。
分佈式鎖應該具有的特性
1、在分佈式環境中應該能保證一個方法在同一時間只能被一個線程執行。
2、高可用的獲取和釋放鎖。
3、高性能的獲取和釋放鎖。
4、具備可重入的特性。
5、具備鎖失效機制,防止死鎖。
6、具備非阻塞特性,即沒有獲取到鎖則直接返回獲取鎖失敗。
什麼是ZooKeeper?
1、zookeeper是一種分佈式協調服務,用於管理大型主機。他能是開發人員可以專注於實現邏輯,而不用擔心實現特性。
2、數據模型很想數據結構中的二叉樹,也很想文件系統中的目錄。
3、樹是由節點所組成,zookeeper也是基於節點,名稱爲znode。
4、但是不同於樹,而是使用路徑來訪問,類似目錄 如 /動物/貓
5、znode的組成
- data:znode存儲的信息。
- ACL:控制的權限。即那些人或者那些ip可以訪問到。
- child:當前節點的子節點引用。
- stat:包含znode的各種元數據。如時間戳、事務id、版本號等。
6、zookeeper規定,每個節點最多隻能存儲1Mb數據。
7、zookeeper操作
- 創建節點
create
- 刪除節點
delete
- 是否存在
exist
- 獲取數據
getData
- 獲取節點
getChild
8、事務實現,時間通知,watch
,類似觀察者模式。發生操作的時候,會觸發客戶端的異步通知。
Zookeeper的事件通知
可以把Watch看成是特定操作的事件通知,當我們執行zookeeper的操作命令時,會自動觸發反饋。
具體的操作如下,如調用 getData
方法,watch參數是true
,服務端接收到請求,並且獲取相關數據,在哈希表中插入相應的路徑。
Zookeeper的數據一致性
1、爲了防止單機模式宕機的風險,集羣的Zookeeper採用的一主多從的工作模式。在更新數據時,請求首先會更新到主節點,然後再同步到各個子節點。
2、Zookeeper採用ZAB(Zookeeper Atomic Broadcast)的方式進行數據同步。
3、ZAB模式下的三種狀態
- following:從節點所處的狀態
- looking:選舉狀態
- leading:主節點所處的轉改
4、最大ZXID:節點本地最大的事務編號。包含epoch和計數兩部分。
5、ZAB的奔潰恢復。假如主節點奔潰了,Zookeeper會自動選舉新的主節點。此時集羣中的節點處於Looking狀態,它們會各自發起投票,投票中包含自己的服務器ID和最新的事務ZXID。節點會將接收到的ZXID與自己的ID進行比較,如果比自己大,說明對方的數據比較新,然後繼續進行投票。投給目前自己已知的最大節點ID。每次投票完了之後,Zookeeper會自動統計票數,得到票數至少達到一半以上,則選擇其成爲準Leader。只有超過半數的子節點回復已經知道ACK的信息,正式確認準Leader爲Leader。
ZAB數據寫入
-
首先客戶端發送寫入數據給任意一個Follower。
-
Follower請求寫入數據轉發給Leader。
-
Leader 採用二階段提交的方式,發送purpose廣播給Follower。
-
Follower接收到 Purpose,寫入日誌,發送ACK給Leader。
-
Leader接收到半數以上的ACK,返回成功給客戶端,並且廣播Commit請求給Follower。
什麼是臨時順序節點
Znode分爲四種節點,包括臨時節點、臨時順序節點、持久節點、持久順序節點。順序節點的意思是自動給節點添加一個編號,使之有序。
Zookeeper的部署
Zookeeper有三種部署方式,包括單機部署、集羣部署、僞集羣部署。
注:集羣僞大於等於三個節點,如3,5,7,9,爲奇數。
單機模式
docker-compose.yml
version: '3.1'
services:
zoo1:
image: zookeeper
restart: always
hostname: zoo1
ports:
- 2181:2181
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=zoo1:2888:3888
僞集羣模式
version: '2'
services:
zoo1:
image: zookeeper
restart: always
container_name: zoo1
ports:
- "2181:2181"
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
zoo2:
image: zookeeper
restart: always
container_name: zoo2
ports:
- "2182:2181"
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
zoo3:
image: zookeeper
restart: always
container_name: zoo3
ports:
- "2183:2181"
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
驗證是否安裝成功
# docker exec -it zookeeper_zoo1_1 /bin/bash
查看當前節點的狀態
# cd bin/
# ls -al
# ./zkServer.sh status
Mode: follower
基本配置
1 、配置文件路徑 /conf/zoo.cfg
clientPort=2181
dataDir=/data
dataLogDir=/datalog
tickTime=2000
- clientPort:這個端口是客戶端連接Zookeeper服務器端的端口,Zookeeper會監聽這個端口,接收客戶端發送的請求。
- dataDir:Zookeeper保存數據的目錄。
- dataLogDir:Zookeeper存放日誌的目錄。
- tickTime:Zookeeper心跳檢查的時間間隔。每個tickTime會發送一次心跳。
Zookeeper集羣模式
配置文件路徑 /con/zoo.cfg
clientPort=2181
dataDir=/data
dataLogDir=/datalog
tickTime=2000
initLimit=5
syncLimit=2
autopurge.snapRetainCount=3
autopurge.purInterval=0
maxClientCnxns=60
server.1=192.169.0.1:2888:3888
server.2=192.169.0.2:2888:3888
server.3=192.169.0.3:2888:3888
- initLimit:客戶端接受客戶端初始化連接的初始能夠忍受接受的時間間隔。
- Leader與Follower交換信息時間長度最多不能超過的時間間隔。指定保留的個數,purgeInterval表示不清理。
客戶端連接服務端命令
# zkCli.sh -server localhost:2181