zookeeper
什麼是zookeeper?
分布式一緻性協調服務架構
換言之,也可以zookeeper看成一個小型的分布式檔案系統,
但是與FastDFS不同,zookeeper隻适合用來存儲一些小型的資料或者配置資訊
提供配置資訊管理,命名服務,分布式同步
zookeeper安裝
1.zookeeper是純java的是以需要JDK環境
2.單機安裝-配置data/log路徑後啟動即可
zookeeper的檔案系統
檔案系統的資料結構
zookeeper底層是一個樹形結構,用來存儲資料
和Linux,Window等系統不同,Linux和Window中有檔案和檔案夾的概念,檔案夾下面才能有檔案,檔案下面不能有檔案,檔案夾本身不存放資料,檔案本身用來進行資料存儲;
zookeeper中的結點,沒有檔案夾和檔案之分,所有結點都可以進行資料存儲,同時也可以擁有子節點;
每個結點稱之為ZNode
ZNode的分類
1.臨時節點-ephemeral:
臨時節點由某個用戶端建立,如果該用戶端斷開了和zookeeper伺服器的連接配接,則該臨時節點就會自動删除;
注意:臨時節點不能有子節點
2.持久性節點-persistent:
持久化的節點會永久存在于檔案系統中,除非用戶端顯示的删除該節點;該節點是最常見的節點;
3.順序節點:
3.1臨時順序節點-ephemeral_sequential:
和臨時節點有相同的特點,唯一的差別在于該節點名稱會自動維護一個編号
3.2持久順序節點-persistent_sequential:
和持久化的節點由相同的特點,唯一的差別在于該節點名稱會自動維護一個編碼
zookeeper檔案系統操作指令
1…/zkCli.sh ip -p port;
進入指令行
2.ls path;
檢視某個路徑下的子節點情況,在zookeeper中隻能寫絕對路徑,所有的路徑都必須從/出發
3.create -s(順序節點) -e(臨時節點) path(路徑) data(資料) acl(權限);
建立新節點,資料不能為空
4.get path;
檢視指定路徑對應的節點資料(資料部分+描述部分)
5.set path data [version]
修改指定節點的資料
6.delete path data
删除指定節點的資料
Java如何操作zookeeper
引入依賴然後,建立 zookeeper對象操作即可
zookeeper的通知(watch)機制
什麼是通知機制?
用戶端可以選擇對某個ZNode進行監聽,當這個ZNode發生變化時(本身的添加删除,修改以及子ZNode的變化),會主動通知監聽了這個ZNode的用戶端,zookeeper的通知機制有一次性觸發原則,ZNode發生變化後,一旦通知了用戶端,則斷開用戶端的監聽,如果需要繼續監聽節點的變化,則必須重新發起監聽
監聽方法
自定義類MyWatch實作Wathcer接口,實作zookeeper的通知回調方法
//判斷abc是否存在,并設定一個監聽
//可以監聽到節點建立,節點的内容修改,節點的删除
//但是不能監聽到子節點的變化
zookeeper.exists("/abc",new MyWatch());
//無法監聽到節點的建立,如果abc不存在則報錯
//可以監聽目前節點的内容修改,删除
zookeeper.getData("/abc",new MyWatch(),null);
//無法監聽到節點的建立,如果abc不存在則報錯
//無法監聽節點本身的變化
//可以監聽子節點的變化,子節點的添加和删除
//但是不包含内容變化,也不包括孫子節點的變化
zookeeper.getChildren("/abc",new MyWatch());
watch類型
1.資料watch
exists();
getData();
2.孩子watch
getChildren();
注意:不同的API監聽的動作不同
事件類型
None:斷開連接配接
NodeCreated:t添加
NodeDeleted:删除
NodeDataChanged:隻和版本号有關
NodeChildrenChanged:子節點建立或删除
ZooKeeper的運用場景(重點)
1.配置檔案統一管理
對分布式系統來說,有很多服務部署在不同的伺服器上,不同的伺服器有自己一套配置,如果需要配置進行調整,則需要對多台伺服器逐個的修改,是不便于管理的
在zookeeper中建立/Configuration持久化節點,将配置資訊放在其中
每個用戶端都監聽(Watch機制)該持久節點,如果有新的配置資訊,開發者隻需要上傳到zookeeper這個節點上(更新節點的配置資料),一旦節點内容修改,每個應用都會得到zookeeper的通知,然後從中獲得新的配置資訊,在系統中完成配置更新;
2.叢集管理
所謂叢集管理無在乎兩點:是否有機器退出和加入,選舉master
在某些叢集中可能需要其他叢集伺服器的狀态,比如有機器加入或退出叢集等,這個時候就可以通過zookeeper進行叢集的統一管理
所有機器約定在父目錄/GroupMembers下建立臨時節點,每一個節點就代表一台機器,然後監聽父目錄節點的子節點的變化消息
一旦有機器添加和删除,每個機器都會收到通知,接受通知後,每個機器可以在查詢節點資訊,就可以知道哪個節點添加或者删除,就知道哪個機器進入或退出了,然後進行叢集的配置
master選舉的話我們一般通過在父節點建立順序臨時節點,選擇編号最小的機器即可
3.分布式鎖
實作方式:
1.保持獨占:單程序
我們把zookeeper上的一個znode看做一把鎖,所有的用戶端同時建立一個lock臨時節點,通過createNode()方法,誰建立成功,誰就獲得鎖了;業務操作結束後,釋放鎖删除該節點即可,就算用戶端斷開臨時節點也會删除是以不用擔心會形成死鎖;
2.控制時序:加鎖排隊
建立一個父節點,所有的用戶端在它下面建立順序臨時節點,我們保證編号最小的獲得這個鎖就可以了
4.命名服務(服務的發現和注冊)
Dubbo使用的就是這個場景,基于ZooKeeper注冊中心,命名服務
假設有一個A服務需要調用B服務,但是AB是兩個互相獨立的服務,A先完成,B還沒有完成
A就可以主動獲得zookeeper某個節點"/name",A就可以不需要再管了,B一旦完成,B直接去"/name"節點上将位址加入其中,A服務就監聽到了節點内容的修改,就能夠調用該位址
對于叢集的負載均衡在父節點下面添加子節點就可以實作
Dubbo+ZooKeeper
在zookeeper的根目錄下有/dubbo節點
/dubbo節點下面就是我們釋出的服務節點
各個服務節點下面就有我們的服務資訊,消費者,提供者,配置資訊各種節點…
服務者節點中就存放了我們需要的調用位址,消費者一旦啟動就會去其中獲得調用位址,并且消費者也有位址但沒有實際作用;
ZooKeeper叢集,leader-follower
ZooKeeper叢集由N台機器搭建,這些機器中一定會存在一個leader,其他的機器都是follower,所有用戶端都可以随意連接配接叢集中的任一機器;
對于内容修改操作,所有的follower都會收到leader的指令,由leader發起投票,票數超過一半以上則送出指令
叢集搭建兩種方式
僞叢集模式
單機機器中啟動多個ZooKeeper程序,并組成叢集
步驟:
1.将單機裝的zookeeper檔案複制兩份
2.在zookeeper/data中建立myid檔案并編寫id編碼
3.修改zookeeper/conf/zoo.cfg核心配置檔案port,以及data/log路徑,還要配置
server.1=127.0.0.1:2888:3888
server.2=127.0.0.2:2889:3889
server.3=127.0.0.3:2890:3890
(這兩個端口是叢集内部通訊的端口)
真實叢集就是不需要修改配置port和data路徑
然後配置server的時候ip不一緻
4.啟動叢集
./zkServer.sh status 檢視服務狀态,可知道leader/follower角色
叢集模式
過半數存活原則
在zookeeper叢集中,當存活的機器數量超過總機器的一半的時候,整個叢集才能正常工作,否則拒絕通路
基于過半數存活原則,zookeeper的叢集機器數量一定是奇數台,因為2N+1和2N+2的容災能力是一樣的,基于成本考慮2N+1台的選擇方案更優
為什麼zookeeper需要設計一個過半數存活機制?
為了防止網絡腦裂,保證資料的強一緻性
因為整個叢集中,有可能因為網絡問題"腦裂",導緻整個叢集分為2個甚至多個叢集,如果沒有過半數存活機制,那麼整個zookeeper會變成多個叢集,那麼zookeeper提供的資料無法再保證資料一緻性;
zookeeper叢集角色
1.Leader上司者
2.Learner學習者:
Follower跟随者:
ObServer觀察者:功能和追随者一緻,響應用戶端的指令,不能參加選舉和投票環節
3.Client用戶端
ZAB協定-原子消息廣播協定
ZooKeeper作為高可用的一緻性協調架構
自然的ZooKeeper也有着一緻性算法的實作,ZooKeeper使用的是ZAB協定作為資料一緻性的算法,ZAB(ZooKeeper Atomic Broadcast )
ZAB基礎
Leader選舉;
在ZooKeeper中所有的事務請求都由一個主伺服器也就是Leader來處理,其他伺服器為Follower,Leader将用戶端的事務請求轉換為事務Proposal,并且将Proposal分發給叢集中其他所有的Follower,然後Leader等待Follwer回報,當有過半數(>=N/2+1)的Follower回報資訊後,Leader将再次向叢集内Follower廣播Commit資訊,Commit為将之前的Proposal送出;
ZAB協定的狀态
Looking:選舉狀态
Leading:上司狀态
Following:跟随狀态
zookeeper配置詳解
核心配置檔案zoo.cfg
tickTime:心跳間隔時間,預設為2000ms
zookeeper中使用的基本時間機關, 毫秒值。
dataDir:資料目錄。
修改為zookeeper安裝目錄下的data目錄,data目錄自己建立,當然也可以指定為别的目錄。
initLimit:連接配接逾時時間
Follower初始化連接配接時和Leader連接配接的逾時時間。預設為10(10 * 2000ms(tickTime))
zookeeper叢集中的包含多台server,其中一台為leader,其餘的server為follower。
initLimit參數配置初始化連接配接時,follower和leader之間的最長心跳時間。
syncLimit:消息通信逾時時間
該參數配置leader和follower之間發送消息,請求和應答的最大時間長度。
此時該參數設定為2,說明時間限制為2倍tickTime,即4000ms
叢集配置詳解
server.serverid=serverhost:leader_listent_port:quorum_port
serverid:myid
是目前zookeeper伺服器的id(myid檔案中寫的編号)。
leader_listen_port:上司監聽端口
通常叫做原子廣播端口,是該伺服器一旦成為leader之後需要監聽的端口,用于接收來自follower的請求。
quorum_port:選舉端口
通常叫做選舉端口,是叢集中的每一個伺服器在最開始選舉leader時監聽的端口,用于伺服器互相之間通信選舉leader。