1. 程式人生 > >Zookeeper Api(java)入門與應用

Zookeeper Api(java)入門與應用

如何使用

Zookeeper 作為一個分散式的服務框架,主要用來解決分散式叢集中應用系統的一致性問題,它能提供基於類似於檔案系統的目錄節點樹方式的資料儲存,但是 Zookeeper 並不是用來專門儲存資料的,它的作用主要是用來維護和監控你儲存的資料的狀態變化。通過監控這些資料狀態的變化,從而可以達到基於資料的叢集管理,後面將會詳細介紹 Zookeeper 能夠解決的一些典型問題,這裡先介紹一下,Zookeeper 的操作介面和簡單使用示例。

常用介面列表

客戶端要連線 Zookeeper 伺服器可以通過建立 org.apache.zookeeper. ZooKeeper 的一個例項物件,然後呼叫這個類提供的介面來和伺服器互動。

前面說了 ZooKeeper 主要是用來維護和監控一個目錄節點樹中儲存的資料的狀態,所有我們能夠操作 ZooKeeper 的也和操作目錄節點樹大體一樣,如建立一個目錄節點,給某個目錄節點設定資料,獲取某個目錄節點的所有子目錄節點,給某個目錄節點設定許可權和監控這個目錄節點的狀態變化。

這些介面如下表所示:


表 1 org.apache.zookeeper. ZooKeeper 方法列表
方法名方法功能描述

String create(String path, byte[] data, List<ACL> acl,CreateMode createMode) 建立一個給定的目錄節點 path, 並給它設定資料,
CreateMode
 標識有四種形式的目錄節點,分別是 PERSISTENT:持久化目錄節點,這個目錄節點儲存的資料不會丟失;PERSISTENT_SEQUENTIAL:順序自動編號的目錄節點,這種目錄節點會根據當前已近存在的節點數自動加 1,然後返回給客戶端已經成功建立的目錄節點名;EPHEMERAL:臨時目錄節點,一旦建立這個節點的客戶端與伺服器埠也就是 session 超時,這種節點會被自動刪除;EPHEMERAL_SEQUENTIAL:臨時自動編號節點
Stat exists(String path, boolean watch) 判斷某個 path 是否存在,並設定是否監控這個目錄節點,這裡的 watcher 是在建立 ZooKeeper 例項時指定的 watcher,
exists
方法還有一個過載方法,可以指定特定的watcher
Stat exists(String path,Watcher watcher) 過載方法,這裡給某個目錄節點設定特定的 watcher,Watcher 在 ZooKeeper 是一個核心功能,Watcher 可以監控目錄節點的資料變化以及子目錄的變化,一旦這些狀態發生變化,伺服器就會通知所有設定在這個目錄節點上的 Watcher,從而每個客戶端都很快知道它所關注的目錄節點的狀態發生變化,而做出相應的反應
void delete(String path, int version) 刪除 path 對應的目錄節點,version 為 -1 可以匹配任何版本,也就刪除了這個目錄節點所有資料
List<String>getChildren(String path, boolean watch) 獲取指定 path 下的所有子目錄節點,同樣 getChildren方法也有一個過載方法可以設定特定的 watcher 監控子節點的狀態
Stat setData(String path, byte[] data, int version) 給 path 設定資料,可以指定這個資料的版本號,如果 version 為 -1 怎可以匹配任何版本
byte[] getData(String path, boolean watch, Stat stat) 獲取這個 path 對應的目錄節點儲存的資料,資料的版本等資訊可以通過 stat 來指定,同時還可以設定是否監控這個目錄節點資料的狀態
voidaddAuthInfo(String scheme, byte[] auth) 客戶端將自己的授權資訊提交給伺服器,伺服器將根據這個授權資訊驗證客戶端的訪問許可權。
Stat setACL(String path,List<ACL> acl, int version) 給某個目錄節點重新設定訪問許可權,需要注意的是 Zookeeper 中的目錄節點許可權不具有傳遞性,父目錄節點的許可權不能傳遞給子目錄節點。目錄節點 ACL 由兩部分組成:perms 和 id。
Perms 有 ALL、READ、WRITE、CREATE、DELETE、ADMIN 幾種 
而 id 標識了訪問目錄節點的身份列表,預設情況下有以下兩種:
ANYONE_ID_UNSAFE = new Id("world", "anyone") 和 AUTH_IDS = new Id("auth", "") 分別表示任何人都可以訪問和建立者擁有訪問許可權。
List<ACL>getACL(String path,Stat stat) 獲取某個目錄節點的訪問許可權列表

除了以上這些上表中列出的方法之外還有一些過載方法,如都提供了一個回撥類的過載方法以及可以設定特定 Watcher 的過載方法,具體的方法可以參考 org.apache.zookeeper. ZooKeeper 類的 API 說明。

基本操作

下面給出基本的操作 ZooKeeper 的示例程式碼,這樣你就能對 ZooKeeper 有直觀的認識了。下面的清單包括了建立與 ZooKeeper 伺服器的連線以及最基本的資料操作:


 ZooKeeper 基本的操作示例

複製程式碼
 // 建立一個與伺服器的連線
 ZooKeeper zk = new ZooKeeper("localhost:" + CLIENT_PORT, 
        ClientBase.CONNECTION_TIMEOUT, new Watcher() { 
            // 監控所有被觸發的事件
            public void process(WatchedEvent event) { 
                System.out.println("已經觸發了" + event.getType() + "事件!"); 
            } 
        }); 
 // 建立一個目錄節點
 zk.create("/testRootPath", "testRootData".getBytes(), Ids.OPEN_ACL_UNSAFE,
   CreateMode.PERSISTENT); 
 // 建立一個子目錄節點
 zk.create("/testRootPath/testChildPathOne", "testChildDataOne".getBytes(),
   Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT); 
 System.out.println(new String(zk.getData("/testRootPath",false,null))); 
 // 取出子目錄節點列表
 System.out.println(zk.getChildren("/testRootPath",true)); 
 // 修改子目錄節點資料
 zk.setData("/testRootPath/testChildPathOne","modifyChildDataOne".getBytes(),-1); 
 System.out.println("目錄節點狀態:["+zk.exists("/testRootPath",true)+"]"); 
 // 建立另外一個子目錄節點
 zk.create("/testRootPath/testChildPathTwo", "testChildDataTwo".getBytes(), 
   Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT); 
 System.out.println(new String(zk.getData("/testRootPath/testChildPathTwo",true,null))); 
 // 刪除子目錄節點
 zk.delete("/testRootPath/testChildPathTwo",-1); 
 zk.delete("/testRootPath/testChildPathOne",-1); 
 // 刪除父目錄節點
 zk.delete("/testRootPath",-1); 
 // 關閉連線
 zk.close(); 
複製程式碼

輸出的結果如下:

複製程式碼
已經觸發了 None 事件!
 testRootData 
 [testChildPathOne] 
目錄節點狀態:[5,5,1281804532336,1281804532336,0,1,0,0,12,1,6] 
已經觸發了 NodeChildrenChanged 事件!
 testChildDataTwo 
已經觸發了 NodeDeleted 事件!
已經觸發了 NodeDeleted 事件!
複製程式碼

當對目錄節點監控狀態開啟時,一旦目錄節點的狀態發生變化,Watcher 物件的 process 方法就會被呼叫。

ZooKeeper 典型的應用場景

Zookeeper 從設計模式角度來看,是一個基於觀察者模式設計的分散式服務管理框架,它負責儲存和管理大家都關心的資料,然後接受觀察者的註冊,一旦這些資料的狀態發生變化,Zookeeper 就將負責通知已經在 Zookeeper 上註冊的那些觀察者做出相應的反應,從而實現叢集中類似 Master/Slave 管理模式,關於 Zookeeper 的詳細架構等內部細節可以閱讀 Zookeeper 的原始碼

下面詳細介紹這些典型的應用場景,也就是 Zookeeper 到底能幫我們解決那些問題?下面將給出答案。

統一命名服務(Name Service)

分散式應用中,通常需要有一套完整的命名規則,既能夠產生唯一的名稱又便於人識別和記住,通常情況下用樹形的名稱結構是一個理想的選擇,樹形的名稱結構是一個有層次的目錄結構,既對人友好又不會重複。說到這裡你可能想到了 JNDI,沒錯 Zookeeper 的 Name Service 與 JNDI 能夠完成的功能是差不多的,它們都是將有層次的目錄結構關聯到一定資源上,但是 Zookeeper 的 Name Service 更加是廣泛意義上的關聯,也許你並不需要將名稱關聯到特定資源上,你可能只需要一個不會重複名稱,就像資料庫中產生一個唯一的數字主鍵一樣。

Name Service 已經是 Zookeeper 內建的功能,你只要呼叫 Zookeeper 的 API 就能實現。如呼叫 create 介面就可以很容易建立一個目錄節點。

配置管理(Configuration Management)

配置的管理在分散式應用環境中很常見,例如同一個應用系統需要多臺 PC Server 執行,但是它們執行的應用系統的某些配置項是相同的,如果要修改這些相同的配置項,那麼就必須同時修改每臺執行這個應用系統的 PC Server,這樣非常麻煩而且容易出錯。

像這樣的配置資訊完全可以交給 Zookeeper 來管理,將配置資訊儲存在 Zookeeper 的某個目錄節點中,然後將所有需要修改的應用機器監控配置資訊的狀態,一旦配置資訊發生變化,每臺應用機器就會收到 Zookeeper 的通知,然後從 Zookeeper 獲取新的配置資訊應用到系統中。


圖 2. 配置管理結構圖
 

叢集管理(Group Membership)

Zookeeper 能夠很容易的實現叢集管理的功能,如有多臺 Server 組成一個服務叢集,那麼必須要一個“總管”知道當前叢集中每臺機器的服務狀態,一旦有機器不能提供服務,叢集中其它叢集必須知道,從而做出調整重新分配服務策略。同樣當增加叢集的服務能力時,就會增加一臺或多臺 Server,同樣也必須讓“總管”知道。

Zookeeper 不僅能夠幫你維護當前的叢集中機器的服務狀態,而且能夠幫你選出一個“總管”,讓這個總管來管理叢集,這就是 Zookeeper 的另一個功能 Leader Election。

它們的實現方式都是在 Zookeeper 上建立一個 EPHEMERAL 型別的目錄節點,然後每個 Server 在它們建立目錄節點的父目錄節點上呼叫 getChildren(String path, boolean watch) 方法並設定 watch 為 true,由於是 EPHEMERAL 目錄節點,當建立它的 Server 死去,這個目錄節點也隨之被刪除,所以 Children 將會變化,這時 getChildren上的 Watch 將會被呼叫,所以其它 Server 就知道已經有某臺 Server 死去了。新增 Server 也是同樣的原理。

Zookeeper 如何實現 Leader Election,也就是選出一個 Master Server。和前面的一樣每臺 Server 建立一個 EPHEMERAL 目錄節點,不同的是它還是一個 SEQUENTIAL 目錄節點,所以它是個 EPHEMERAL_SEQUENTIAL 目錄節點。之所以它是 EPHEMERAL_SEQUENTIAL 目錄節點,是因為我們可以給每臺 Server 編號,我們可以選擇當前是最小編號的 Server 為 Master,假如這個最小編號的 Server 死去,由於是 EPHEMERAL 節點,死去的 Server 對應的節點也被刪除,所以當前的節點列表中又出現一個最小編號的節點,我們就選擇這個節點為當前 Master。這樣就實現了動態選擇 Master,避免了傳統意義上單 Master 容易出現單點故障的問題。


圖 3. 叢集管理結構圖
 

這部分的示例程式碼如下,完整的程式碼請看附件:


 Leader Election 關鍵程式碼

複製程式碼
 void findLeader() throws InterruptedException { 
        byte[] leader = null; 
        try { 
            leader = zk.getData(root + "/leader", true, null); 
        } catch (Exception e) { 
            logger.error(e); 
        } 
        if (leader != null) { 
            following(); 
        } else { 
            String newLeader = null; 
            try { 
                byte[] localhost = InetAddress.getLocalHost().getAddress(); 
                newLeader = zk.create(root + "/leader", localhost, 
                ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); 
            } catch (Exception e) { 
                logger.error(e); 
            } 
            if (newLeader != null) { 
                leading(); 
            } else { 
                mutex.wait(); 
            } 
        } 
    } 
複製程式碼

共享鎖(Locks)

共享鎖在同一個程序中很容易實現,但是在跨程序或者在不同 Server 之間就不好實現了。Zookeeper 卻很容易實現這個功能,實現方式也是需要獲得鎖的 Server 建立一個 EPHEMERAL_SEQUENTIAL 目錄節點,然後呼叫 getChildren方法獲取當前的目錄節點列表中最小的目錄節點是不是就是自己建立的目錄節點,如果正是自己建立的,那麼它就獲得了這個鎖,如果不是那麼它就呼叫exists(String path, boolean watch) 方法並監控 Zookeeper 上目錄節點列表的變化,一直到自己建立的節點是列表中最小編號的目錄節點,從而獲得鎖,釋放鎖很簡單,只要刪除前面它自己所建立的目錄節點就行了。


圖 4. Zookeeper 實現 Locks 的流程圖
 

同步鎖的實現程式碼如下,完整的程式碼請看附件:

同步鎖的關鍵思路

複製程式碼
加鎖:
ZooKeeper 將按照如下方式實現加鎖的操作:
1 ) ZooKeeper 呼叫 create ()方法來建立一個路徑格式為“ _locknode_/lock- ”的節點,此節點型別為sequence (連續)和 ephemeral (臨時)。也就是說,建立的節點為臨時節點,並且所有的節點連續編號,即“ lock-i ”的格式。
2 )在建立的鎖節點上呼叫 getChildren ()方法,來獲取鎖目錄下的最小編號節點,並且不設定 watch 。
3 )步驟 2 中獲取的節點恰好是步驟 1 中客戶端建立的節點,那麼此客戶端獲得此種類型的鎖,然後退出操作。
4 )客戶端在鎖目錄上呼叫 exists ()方法,並且設定 watch 來監視鎖目錄下比自己小一個的連續臨時節點的狀態。
5 )如果監視節點狀態發生變化,則跳轉到第 2 步,繼續進行後續的操作,直到退出鎖競爭。
 
解鎖: 
ZooKeeper 解鎖操作非常簡單,客戶端只需要將加鎖操作步驟 1 中建立的臨時節點刪除即可。
複製程式碼


同步鎖的關鍵程式碼

複製程式碼
 void getLock() throws KeeperException, InterruptedException{ 
        List<String> list = zk.getChildren(root, false); 
        String[] nodes = list.toArray(new String[list.size()]); 
        Arrays.sort(nodes); 
        if(myZnode.equals(root+"/"+nodes[0])){ 
            doAction(); 
        } 
        else{ 
            waitForLock(nodes[0]); 
        } 
    } 
    void waitForLock(String lower) throws InterruptedException, KeeperException {
        Stat stat = zk.exists(root + "/" + lower,true); 
        if(stat != null){ 
            mutex.wait(); 
        } 
        else{ 
            getLock(); 
        } 
    } 
複製程式碼

佇列管理

Zookeeper 可以處理兩種型別的佇列:

  1. 當一個佇列的成員都聚齊時,這個佇列才可用,否則一直等待所有成員到達,這種是同步佇列。
  2. 佇列按照 FIFO 方式進行入隊和出隊操作,例如實現生產者和消費者模型。

同步佇列用 Zookeeper 實現的實現思路如下:

建立一個父目錄 /synchronizing,每個成員都監控標誌(Set Watch)位目錄 /synchronizing/start 是否存在,然後每個成員都加入這個佇列,加入佇列的方式就是建立 /synchronizing/member_i 的臨時目錄節點,然後每個成員獲取 / synchronizing 目錄的所有目錄節點,也就是 member_i。判斷 i 的值是否已經是成員的個數,如果小於成員個數等待 /synchronizing/start 的出現,如果已經相等就建立 /synchronizing/start。

用下面的流程圖更容易理解:


圖 5. 同步佇列流程圖
 

同步佇列的關鍵程式碼如下,完整的程式碼請看附件:


同步佇列

複製程式碼
 void addQueue() throws KeeperException, InterruptedException{ 
        zk.exists(root + "/start",true); 
        zk.create(root + "/" + name, new byte[0], Ids.OPEN_ACL_UNSAFE, 
        CreateMode.EPHEMERAL_SEQUENTIAL); 
        synchronized (mutex) { 
            List<String> list = zk.getChildren(root, false); 
            if (list.size() < size) { 
                mutex.wait(); 
            } else { 
                zk.create(root + "/start", new byte[0], Ids.OPEN_ACL_UNSAFE,
                 CreateMode.PERSISTENT); 
            } 
        } 
 } 
複製程式碼

當佇列沒滿是進入 wait(),然後會一直等待 Watch 的通知,Watch 的程式碼如下:

複製程式碼
 public void process(WatchedEvent event) { 
        if(event.getPath().equals(root + "/start") &&
         event.getType() == Event.EventType.NodeCreated){ 
            System.out.println("得到通知"); 
            super.process(event); 
            doAction(); 
        } 
    } 
複製程式碼

FIFO 佇列用 Zookeeper 實現思路如下:

實現的思路也非常簡單,就是在特定的目錄下建立 SEQUENTIAL 型別的子目錄 /queue_i,這樣就能保證所有成員加入佇列時都是有編號的,出佇列時通過 getChildren( ) 方法可以返回當前所有的佇列中的元素,然後消費其中最小的一個,這樣就能保證 FIFO。

下面是生產者和消費者這種佇列形式的示例程式碼,完整的程式碼請看附件:


 生產者程式碼

複製程式碼
 boolean produce(int i) throws KeeperException, InterruptedException{ 
        ByteBuffer b = ByteBuffer.allocate(4); 
        byte[] value; 
        b.putInt(i); 
        value = b.array(); 
        zk.create(root + "/element", value, ZooDefs.Ids.OPEN_ACL_UNSAFE, 
                    CreateMode.PERSISTENT_SEQUENTIAL); 
        return true; 
    } 
複製程式碼


消費者程式碼

複製程式碼
 int consume() throws KeeperException, InterruptedException{ 
        int retvalue = -1; 
        Stat stat = null; 
        while (true) { 
            synchronized (mutex) { 
                List<String> list = zk.getChildren(root, true); 
                if (list.size() == 0) { 
                    mutex.wait(); 
                } else { 
                    Integer min = new Integer(list.get(0).substring(7)); 
                    for(String s : list){ 
                        Integer tempValue = new Integer(s.substring(7)); 
                        if(tempValue < min) min = tempValue; 
                    } 
                    byte[] b = zk.getData(root + "/element" + min,false, stat); 
                    zk.delete(root + "/element" + min, 0); 
                    ByteBuffer buffer = ByteBuffer.wrap(b); 
                    retvalue = buffer.getInt(); 
                    return retvalue; 
                } 
            } 
        } 
 } 
複製程式碼

總結

Zookeeper 作為 Hadoop 專案中的一個子專案,是 Hadoop 叢集管理的一個必不可少的模組,它主要用來控制叢集中的資料,如它管理 Hadoop 叢集中的 NameNode,還有 Hbase 中 Master Election、Server 之間狀態同步等。

本文介紹的 Zookeeper 的基本知識,以及介紹了幾個典型的應用場景。這些都是 Zookeeper 的基本功能,最重要的是 Zoopkeeper 提供了一套很好的分散式叢集管理的機制,就是它這種基於層次型的目錄樹的資料結構,並對樹中的節點進行有效管理,從而可以設計出多種多樣的分散式的資料管理模型,而不僅僅侷限於上面提到的幾個常用應用場景。

相關推薦

Zookeeper Api(java)入門應用(轉)

由於 sla 入隊 catch 其中 相同 獲得 保存 amp 如何使用 Zookeeper 作為一個分布式的服務框架,主要用來解決分布式集群中應用系統的一致性問題,它能提供基於類似於文件系統的目錄節點樹方式的數據存儲,但是 Zookeeper 並不是用來專門存儲數據的,它

Zookeeper Api(java)入門應用

如何使用 Zookeeper 作為一個分散式的服務框架,主要用來解決分散式叢集中應用系統的一致性問題,它能提供基於類似於檔案系統的目錄節點樹方式的資料儲存,但是 Zookeeper 並不是用來專門儲存資料的,它的作用主要是用來維護和監控你儲存的資料的狀態變化。通過監控這

Docker入門應用系列(六)Docker私有公共鏡像倉庫

nbsp one 默認 span epo refers 1.8 png list 1.搭建私有鏡像倉庫Docker Hub作為Docker默認官方公共鏡像;如果想搭建自己的私有鏡像倉庫,官方提供registry鏡像,使搭建私有倉庫非常簡單1.1.1下載registry鏡像並

Docker入門應用系列(八)Docker圖形界面管理之Shipyard

tps 數據庫 sock blog ocs body mage 代理 cell Shipyard基於Docker API實現的容器圖形管理系統,支持container、images、engine、cluster等功能,可滿足我們基本的容器部署需求可堆棧的Docker管理基於

Docker入門應用系列(七)Docker圖形界面管理之DockerUI

post 簡單的 技術分享 name mage src 入門 .com 系統 1.dockeruiDockerrUI是一個基於Docker API提供圖形化頁面簡單的容器管理系統,支持容器管理、鏡像管理。1.1 下載鏡像 docker pull abh1nav/doc

Docker入門應用系列(三)容器管理

輸出 clear tag 程序 ipaddr one 停止 1.2 標準 一、啟動容器   啟動容器有兩種方式,一種是基於鏡像新建一個容器並啟動,另一個是將終止狀態的容器重新啟動。 1.1 新建並啟動 主要命令為 docker run 下面的命令輸出一個&rd

Docker入門應用系列(四)網絡管理

效率 進行 oop 網絡隔離 style docker utc 同時 存在 一、Docker的五種網絡模式   在使用docker run創建docker容器時,可以用--net選項指定容器的網絡模式,Docker有以下5種網絡模式:   1. bridge模式

節假日api--java呼叫獲取資料

獲取指定日期的節假日資訊 1、介面地址:http://api.goseek.cn/Tools/holiday?date=數字日期,支援https協議。 2、返回資料:工作日對應結果為 0, 休息日對應結果為 1, 節假日對應的結果為 2 3、節假日資料說明:本介面包含

Redis 入門應用

目錄 一、Redis 安裝 1、下載 redis  2、安裝 redis  3、設定 redis 4、redis 服務常用的命令 5、測試 redis 二、RedisDesktopManager 的安裝與使用 1、下載與安裝 2、連線 redi

Redis的入門應用

con predis 判斷 strong make 集合 ash -h 安裝redis擴展 概念:   遠程   基於內存的   非關系型數據庫 應用場景   緩存   隊列   數據存儲 安裝   安裝環境:     服務器:linux>cen

Ajax入門應用

一、Ajax介紹 1. ajax是什麼? * asynchronous javascript and xml:非同步的js和xml * 它能使用js訪問伺服器,而且是非同步訪問! * 伺服器給客戶端的響應一般是整個頁面,一個html完整頁面!但在ajax中因

01:Docker入門應用實戰

學完這門課程會獲得什麼? 掌握Docker核心概念 熟悉Docker工作原理 獨立使用Docker部署應用程式 接入CI/CD,實現環境標準化 入門須知: 熟悉Linux作業系統 瞭解域名解析原理 瞭解網路 第 1 章: Docker概述 Docker是

【極客學院每日1課 】Java入門常用技巧

Java是Android開發者必學的基礎程式語言。你的基礎怎麼樣? 遙想當年,小喬還未出嫁,小編在大學裡面,啃書本,聽教授在課堂上面雲裡霧裡的講啊,始終沒太弄明白,每週請學習委員一頓飯,才順利把作業提交上去,期末考試成績61分,是不是和我送教授的那罐鐵觀音有點關係??

ubuntu docker簡單入門應用

本文使用ubuntu為底層環境,其他發行版除了安裝方式不一樣,別的基本都一樣。 安裝docker 因為ubuntu官方源的docker版本不是最新,所以這裡更新一下docker官方源,以獲取最新版

【redis】redis的入門應用【原創】

1-1 課程內容概要 1. 課程概要 Redis是php專案中使用到的主要快取服務,主要是參考慕課網的《redis的入門與應用_筆記》,這裡主要介紹: * redis的安裝使用 * PHP如何使用redis * redis最常也是必知必會的五大

新浪微博API使用入門:申請應用、授權、使用官方java版本SDK

p.s. 本文的工程採用java語言eclipse平臺開發,配置過程也是基於此。 開發總流程圖 讓你的應用在新浪微博開放平臺上運營,只需要通過簡單的六個步驟: 成為開發者 1.建立微博帳號 在開發者頁面http://open.weibo.com/development

java架構師課程、性能調優、高並發、tomcat負載均衡、大型電商項目實戰、高可用、高可擴展、數據庫架構設計、Solr集群應用、分布式實戰、主從復制、高可用集群、大數據

慢查詢 主從復制 難題 jms 整合 大數 數據庫設計 企業級 nginx網站 15套Java架構師詳情 * { font-family: "Microsoft YaHei" !important } h1 { background-color: #006; color:

【CC2530入門教程-05】CC2530的串行接口原理應用

max blog 模式 指數 open != tab bre 就會 第5課 CC2530的串行接口原理與應用 廣東職業技術學院 歐浩源 一、並行通信與串行通信 微控制器與外設之間的數據通信,根據連線結構和傳送方式的不同,可以分為兩種:並行通信和串行通信。

Zookeeper使用--Java API(轉)

包括 acl logs 新的 ack max false pen strong [轉載自作者leesf,原文鏈接] 操作示例   1 創建節點   創建節點有異步和同步兩種方式。無論是異步或者同步,Zookeeper都不支持遞歸調用,即無法在父節點不存在的情況下

zookeeper的c API 單線程多線程問題 cli_st和cli_mt

.lib libs tool .com tag gnu 編譯選項 watch || 同樣的程序,在centos和ubuntu上都沒有問題,在solaris上問題卻多多,據說是solaris管理更加嚴格。 zookeeper_init方法,在傳入一個錯誤的host也能初始