導航:首頁 > IDC知識 > zoo伺服器

zoo伺服器

發布時間:2021-02-06 18:32:24

1、犀牛無法自動偵測Zoo伺服器是什麼意思?

?

2、zookeeper集群部署和單機部署的區別和優缺點

Apache Zookeeper是我最近遇到的最酷的技術,我是在研究Solr Cloud功能的時候發現的。Solr的分布式計算讓我印象深刻。你只要開啟一個新的實例就能自動在Solr Cloud中找到。它會將自己分派到某個分片中,並確定出自己是一個Leader(源)還是一個副本。不一會兒,你就可以在你的那些伺服器上查詢到了。即便某些伺服器宕機了也可以繼續工作。非常動態、聰明、酷。

將運行多個應用程序作為一個邏輯程序並不是什麼新玩意。事實上,我在幾年前就已寫過類似的軟體。這種架構比較讓人迷惑,使用起來也費勁。為此Apache Zookeeper提供了一套工具用於管理這種軟體。

為什麼叫Zoo?「因為要協調的分布式系統是一個動物園」。

在本篇文章中,我將說明如何使用PHP安裝和集成Apache ZooKeeper。我們將通過service來協調各個獨立的PHP腳本,並讓它們同意某個成為Leader(所以稱作Leader選舉)。當Leader退出(或崩潰)時,worker可檢測到並再選出新的leader。

ZooKeeper是一個中性化的Service,用於管理配置信息、命名、提供分布式同步,還能組合Service。所有這些種類的Service都會在分布式應用程序中使用到。每次編寫這些Service都會涉及大量的修bug和競爭情況。正因為這種編寫這些Service有一定難度,所以通常都會忽視它們,這就使得在應用程序有變化時變得難以管理應用程序。即使處理得當,實現這些服務的不同方法也會使得部署應用程序變得難以管理。

雖然ZooKeeper是一個Java應用程序,但C也可以使用。這里就有個PHP的擴展,由Andrei Zmievski在2009創建並維護。你可以從PECL中下載,或從GitHub中直接獲取PHP-ZooKeeper。
要使用該擴展你首先要安裝ZooKeeper。可以從官方網站下載。
$ tar zxfv zookeeper-3.4.5.tar.gz
$ cd zookeeper-3.4.5/src/c
$ ./configure --prefix=/usr/
$ make
$ sudo make install

這樣就會安裝ZooKeeper的庫和頭文件。現在准備編譯PHP擴展。

$ cd$ git clone https://github.com/andreiz/php-zookeeper.git
$ cd php-zookeeper
$ phpize
$ ./configure
$ make
$ sudo make install

將「zookeeper.so」添加到PHP配置中。

$ vim /etc/php5/cli/conf.d/20-zookeeper.ini

因為我不需要運行在web服務環境下,所以這里我只編輯了CLI的配置。將下面的行復制到ini文件中。

extension=zookeeper.so

使用如下命令來確定擴展是否已起作用。

$ php -m | grep zookeeper
zookeeper

現在是時候運行ZooKeeper了。目前唯一還沒有做的是配置。創建一個用於存放所有service數據的目錄。
$ mkdir /home/you-account/zoo
$ cd$ cd zookeeper-3.4.5/
$ cp conf/zoo_sample.cfg conf/zoo.cfg
$ vim conf/zoo.cfg

找到名為「dataDir」的屬性,將其指向「/home/you-account/zoo」目錄。

$ bin/zkServer.sh start
$ bin/zkCli.sh -server 127.0.0.1:2181[zk: 127.0.0.1:2181(CONNECTED) 14] create /test 1
Created /test[zk: 127.0.0.1:2181(CONNECTED) 19] ls /[test, zookeeper]

此時,你已成功連到了ZooKeeper,並創建了一個名為「/test」的znode(稍後我們會用到)。ZooKeeper以樹形結構保存數據。這很類似於文件系統,但「文件夾」(譯者註:這里指非最底層的節點)又和文件很像。znode是ZooKeeper保存的實體。Node(節點)的說法很容易被混淆,所以為了避免混淆這里使用了znode。

因為我們稍後還會使用,所以這里我們讓客戶端保持連接狀態。開啟一個新窗口,並創建一個zookeeperdemo1.php文件。

<?php
class ZookeeperDemo extends Zookeeper {

public function watcher( $i, $type, $key ) {
echo "Insider Watcher\n";

// Watcher gets consumed so we need to set a new one
$this->get( '/test', array($this, 'watcher' ) );
}
}
$zoo = new ZookeeperDemo('127.0.0.1:2181');$zoo->get( '/test', array($zoo, 'watcher' ) );
while( true ) {
echo '.';
sleep(2);}

現在運行該腳本。

$ php zookeeperdemo1.php

此處應該會每隔2秒產生一個點。現在切換到ZooKeeper客戶端,並更新「/test」值。

[zk: 127.0.0.1:2181(CONNECTED) 20] set /test foo

這樣就會靜默觸發PHP腳本中的「Insider Watcher」消息。怎麼會這樣的?

ZooKeeper提供了可以綁定在znode的監視器。如果監視器發現znode發生變化,該service會立即通知所有相關的客戶端。這就是PHP腳本如何知道變化的。Zookeeper::get方法的第二個參數是回調函數。當觸發事件時,監視器會被消費掉,所以我們需要在回調函數中再次設置監視器。

現在你可以准備創建分布式應用程序了。其中的挑戰是讓這些獨立的程序決定哪個(是leader)協調它們的工作,以及哪些(是worker)需要執行。這個處理過程叫做leader選舉,在ZooKeeper Recipes and Solutions你能看到相關的實現方法。

這里簡單來說就是,每個處理(或伺服器)緊盯著相鄰的那個處理(或伺服器)。如果一個已被監視的處理(也即Leader)退出或者崩潰了,監視程序就會查找其相鄰(此時最老)的那個處理作為Leader。

在真實的應用程序中,leader會給worker分配任務、監控進程和保存結果。這里為了簡化,我跳過了這些部分。
創建一個新的PHP文件,命名為worker.php。

<?php
class Worker extends Zookeeper {

const CONTAINER = '/cluster';

protected $acl = array(
array(
'perms' => Zookeeper::PERM_ALL,
'scheme' => 'world',
'id' => 'anyone' ) );
private $isLeader = false;

private $znode;

public function __construct( $host = '', $watcher_cb = null, $recv_timeout = 10000 ) {
parent::__construct( $host, $watcher_cb, $recv_timeout );
}

public function register() {
if( ! $this->exists( self::CONTAINER ) ) {
$this->create( self::CONTAINER, null, $this->acl );
}

$this->znode = $this->create( self::CONTAINER . '/w-',
null,
$this->acl,
Zookeeper::EPHEMERAL | Zookeeper::SEQUENCE );

$this->znode = str_replace( self::CONTAINER .'/', '', $this->znode );

printf( "I'm registred as: %s\n", $this->znode );

$watching = $this->watchPrevious();

if( $watching == $this->znode ) {
printf( "Nobody here, I'm the leader\n" );
$this->setLeader( true ); }
else {
printf( "I'm watching %s\n", $watching );
}
}

public function watchPrevious() {
$workers = $this->getChildren( self::CONTAINER );
sort( $workers );
$size = sizeof( $workers );
for( $i = 0 ; $i < $size ; $i++ ) {
if( $this->znode == $workers[ $i ] ) {
if( $i > 0 ) {
$this->get( self::CONTAINER . '/' . $workers[ $i - 1 ], array( $this, 'watchNode' ) );
return $workers[ $i - 1 ];
}

return $workers[ $i ];
}
}

throw new Exception( sprintf( "Something went very wrong! I can't find myself: %s/%s",
self::CONTAINER,
$this->znode ) );
}

public function watchNode( $i, $type, $name ) {
$watching = $this->watchPrevious();
if( $watching == $this->znode ) {
printf( "I'm the new leader!\n" );
$this->setLeader( true );
}
else {
printf( "Now I'm watching %s\n", $watching ); }
}

public function isLeader() {
return $this->isLeader;
}

public function setLeader($flag) {
$this->isLeader = $flag;
}

public function run() {
$this->register();

while( true ) {
if( $this->isLeader() ) {
$this->doLeaderJob();
}
else {
$this->doWorkerJob();
}

sleep( 2 );
}
}

public function doLeaderJob() {
echo "Leading\n";
}

public function doWorkerJob() {
echo "Working\n";
}
}
$worker = new Worker( '127.0.0.1:2181' );$worker->run();

打開至少3個終端,在每個終端中運行以下腳本:

# term1
$ php worker.php
I'm registred as: w-0000000001Nobody here, I'm the leader
Leading
# term2
$ php worker.php
I'm registred as: w-0000000002I'm watching w-0000000001
Working
# term3
$ php worker.php
I'm registred as: w-0000000003I'm watching w-0000000002
Working

現在模擬Leader崩潰的情形。使用Ctrl+c或其他方法退出第一個腳本。剛開始不會有任何變化,worker可以繼續工作。後來,ZooKeeper會發現超時,並選舉出新的leader。

雖然這些腳本很容易理解,但是還是有必要對已使用的Zookeeper標志作注釋。
$this->znode = $this->create( self::CONTAINER . '/w-', null, $this->acl, Zookeeper::EPHEMERAL | Zookeeper::SEQUENCE );

每個znode都是EPHEMERAL和SEQUENCE的。

EPHEMRAL代表當客戶端失去連接時移除該znode。這就是為何PHP腳本會知道超時。SEQUENCE代表在每個znode名稱後添加順序標識。我們通過這些唯一標識來標記worker。

在PHP部分還有些問題要注意。該擴展目前還是beta版,如果使用不當很容易發生segmentation fault。比如,不能傳入普通函數作為回調函數,傳入的必須為方法。我希望更多PHP社區的同仁可以看到Apache ZooKeeper的好,同時該擴展也會獲得更多的支持。

ZooKeeper是一個強大的軟體,擁有簡潔和簡單的API。由於文檔和示例都做的很好,任何人都可以很容易的編寫分布式軟體。讓我們開始吧,這會很有趣的。

3、如何使用Zookeeper集群Tomcat

(1)解壓為zookeepertar -xf -C /home/myuser/zookeeper/
復制zookeeper文件夾3份,分別重名名為zookeeperA,zookeeperB,zookeeperC。 並且創建數據快照以及日誌存放文件夾,命名為zooA,zooB,zooC。 (2)編輯對應的zookeeper配置文件,復制zookeeperconf下zoo_sample.cfg為zoo.cfgcd /home/myuser/zookeeperA/conf
cp zoo_sample.cfg zoo.cfg
(3)修改zoo.cfg# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/home/myuser/zooA/data
# the port at which the clients will connect
clientPort=2181
# ZooKeeper server and its port no. # ZooKeeper ensemble should know about every other machine in the ensemble # specify server id by creating 'myid' file in the dataDir # use hostname instead of IP address for convenient maintenance
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2988:3988
server.3=127.0.0.1:2088:3088
#
# Be sure to read the maintenance section of the
# administrator guide before turning>tickTime:心跳時間,為了確保連接存在的,以毫秒為單位,最小超時時間為兩個心跳時間
initLimit:多少個心跳時間內,允許其他server連接並初始化數據,如果ZooKeeper管理的數據較大,則應相應增大這個值
clientPort:服務的監聽埠
dataDir:用於存放內存資料庫快照的文件夾,同時用於集群的myid文件也存在這個文件夾里(注意:一個配置文件只能包含一個dataDir字樣,即使它被注釋掉了。)
dataLogDir:用於單獨設置transaction log的目錄,transaction log分離可以避免和普通log還有快照的競爭
syncLimit:多少個tickTime內,允許follower同步,如果follower落後太多,則會被丟棄。
(4)創建myid文件
cd /home/myuser/zooA/data
sudo sh -c 'echo "1" >> myid'
其他文件夾類似創建myid文件,zookeeperB為2,zookeeperC為3
(5)啟動zookeeper
cd /home/myuser/zookeeperA/bin
sudo sh zkServer.sh start
查看zookeeper狀態[root@weibo bin]# sh zkServer.sh status
JMX enabled by default
Using config: /home/weibo/zookeeperA/bin/../conf/zoo.cfg
Mode: follower
啟動OK,依次啟動另外兩台zookeeper,啟動第一台zookeeper後,你可以觀察bin下的zookeeper.out可以看到報錯,connection
refused,沒有關系,zookeeper需要等待其他另個節點的加入,全部啟動之後就正常了。
(6)客戶端連接zookeeper
[root@weibo bin]# sh zkCli.sh
Connecting to localhost:2181
2013-05-10 15:00:25,363 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.5-1392090, built>configs:保存上傳的配置文件信息
clusterstate.json:集群狀態json
aliases:別名json
live_node:當solr伺服器啟動的時候,會注冊到這里
overseer:保存shard信息
overseer_elect:節點選舉
collections:所有的collection

4、zookeeper伺服器壞了,client還能獲取介面嗎

1:首先下載一個zookeeper,我下載的版本是zookeeper-3.4.6,(目前最新版本為3.5.0,但是啟動不了),解壓安裝包,解壓後的zookeeper安裝包我放置的路徑是:D:/zookeeper/zookeeper-3.4.6
2.:進入D:/zookeeper/zookeeper-3.4.6/conf,將zoo_sample.cfg文件復制一份,並將復制好的文件改名為zoo.cfg。打開新建的zoo.cfg文件,將裡面的內容進行修改,修改後的文件內容如下:
#initLimit=10
#syncLimit=5
tickTime=2000
dataDir=D:/zookeeper/zookeeper-3.4.6/data
clientPort=2181
3. 配置環境變數,在「我的電腦」上點擊右鍵,選擇屬性,再點擊高級系統設置,點擊環境變數按鈕,在系統變數這一欄,點擊新建,添加:

變數名:ZOOKEEPER_HOME

變數值:D:/zookeeper/zookeeper-3.4.6
還是在系統變數這一欄,找到path,點擊編輯path,在變數值里添加:% ZOOKEEPER_HOME %/bin; % ZOOKEEPER_HOME %/conf;

4. 啟動D:/zookeeper/zookeeper-3.4.6/bin/ zkServer.cmd
這里說下多個機器配置zookeeper (windows下偽集群沒有成功)
1:192.168.1.113, 192.168.1.111上D:/zookeeper分別解壓安裝zookeeper-3.4.6
2:D:/zookeeper/zookeeper-3.4.6/conf/zoo.cfg添加如下配置
initLimit=5
syncLimit=2
tickTime=2000
dataDir=D:/zookeeper/zookeeper-3.4.6/data
clientPort=2181
server.1=192.168.1.113:2888:3888
server.2=192.168.1.111:2888:3888
tickTime:這個時間是作為 Zookeeper 伺服器之間或客戶端與伺服器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳。
dataDir:顧名思義就是 Zookeeper 保存數據的目錄,默認情況下,Zookeeper 將寫數據的日誌文件也保存在這個目錄里。
clientPort:這個埠就是客戶端連接 Zookeeper 伺服器的埠,Zookeeper 會監聽這個埠,接受客戶端的訪問請求。
initLimit:這個配置項是用來配置 Zookeeper 接受客戶端(這里所說的客戶端不是用戶連接 Zookeeper 伺服器的客戶端,而是 Zookeeper 伺服器集群中連接到 Leader 的 Follower 伺服器)初始化連接時最長能忍受多少個心跳時間間隔數。當已經超過 5個心跳的時間(也就是 tickTime)長度後 Zookeeper 伺服器還沒有收到客戶端的返回信息,那麼表明這個客戶端連接失敗。總的時間長度就是 5*2000=10 秒
syncLimit:這個配置項標識 Leader 與 Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 2*2000=4 秒
server.A=B:C:D:其中 A 是一個數字,表示這個是第幾號伺服器;B 是這個伺服器的 ip 地址;C 表示的是這個伺服器與集群中的 Leader 伺服器交換信息的埠;D 表示的是萬一集群中的 Leader 伺服器掛了,需要一個埠來重新進行選舉,選出一個新的 Leader,而這個埠就是用來執行選舉時伺服器相互通信的埠。如果是偽集群的配置方式,由於 B 都是一樣,所以不同的 Zookeeper 實例通信埠號不能一樣,所以要給它們分配不同的埠號。(這里是摘抄- -!~)
3:D:/zookeeper/zookeeper-3.4.6/data下創myid文件 myid的文件內容分別為:1、2 上邊下邊配置文件中192.168.1.113servier.X中的X值,如ip113的電腦,myid為1)
4:分別啟動兩個zookeeper,在一台機器上創建節點,另一個機器能同步過去證明成功
5:zookeeper伺服器推薦用奇數個,半數以上服務正常,整個服務就正常,本人條件有限只配置兩個

5、如何啟動zookeeper-3.3.6

1、配置java環境
2、下載zookeeper3.4.6(http://zookeeper.apache.org/releases.html)
3、解壓 zookeeper-3.4.6.tar.gz
4、進入目錄,cp zoo_sample.cfg to zoo.cfg,根據你的要求進行修改

[plain] view plain copy
tickTime=2000
dataDir=/data/zookeeper/
clientPort=2181
initLimit=5
syncLimit=2
server.1=master:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888

如果是single模式下,只需要修改dataDir即可。
tickTime:這個時間是作為 Zookeeper 伺服器之間或客戶端與伺服器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳。

dataDir:顧名思義就是 Zookeeper 保存數據的目錄,默認情況下,Zookeeper 將寫數據的日誌文件也保存在這個目錄里。

clientPort:這個埠就是客戶端連接 Zookeeper 伺服器的埠,Zookeeper 會監聽這個埠,接受客戶端的訪問請求。

initLimit:這個配置項是用來配置 Zookeeper 接受客戶端(這里所說的客戶端不是用戶連接 Zookeeper 伺服器的客戶端,而是 Zookeeper 伺服器集群中連接到 Leader 的 Follower 伺服器)初始化連接時最長能忍受多少個心跳時間間隔數。當已經超過 10 個心跳的時間(也就是 tickTime)長度後 Zookeeper 伺服器還沒有收到客戶端的返回信息,那麼表明這個客戶端連接失敗。總的時間長度就是 5*2000=10 秒

syncLimit:這個配置項標識 Leader 與 Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 2*2000=4 秒
server.A=B:C:D:其中 A 是一個數字,表示這個是第幾號伺服器;B 是這個伺服器的 ip 地址;C 表示的是這個伺服器與集群中的 Leader 伺服器交換信息的埠;D 表示的是萬一集群中的 Leader 伺服器掛了,需要一個埠來重新進行選舉,選出一個新的 Leader,而這個埠就是用來執行選舉時伺服器相互通信的埠。如果是偽集群的配置方式,由於 B 都是一樣,所以不同的 Zookeeper 實例通信埠號不能一樣,所以要給它們分配不同的埠號。

除了修改 zoo.cfg 配置文件,集群模式下還要配置一個文件 myid,這個文件在 dataDir 目錄下,這個文件裡面就有一個數據就是 A 的值,Zookeeper 啟動時會讀取這個文件,拿到裡面的數據與 zoo.cfg 裡面的配置信息比較從而判斷到底是那個 server。(在/data/zookeeper/目錄下touch myid,vi myid 插入對應的server.id)

5、將整個 zookeeper-3.4.6 scp到其他機器上
6、啟動zookeeper
在每台機器上運行 bin/zkServer.sh start
查看運行狀態:bin/zkServer.sh status
Mode: leader

Mode: follower

可以看出哪台為leader了

6、zookeeper 用什麼開發的

由於zookeeper的client只有zookeeper一個對象,使用也比較簡單,所以就不許要文字說明了,在代碼中注釋下就ok 了。

1、測試用的main方法
package ClientExample;

public class TestMain {
public static void main(String[] args) {
/*
* 測試流程
* 1、創建sever1的連接client1,並且創建一個永久性的/test節點
* 2、創建一個針對server1的臨時節點
* 3、創建server2的連接client21,並創建一個針對server2的臨時節點
* 4、創建server3的連接client3,並創建一個針對server3的臨時節點
* 5、分別查看client1、client2、client3的三個節點的位元組點數量,確定是否同步成功
* 6、修改client1的臨時節點內容,然後在在client2和client3中查看
* 7、kill掉client3的線程,然後檢查是watcher是否有通知給client1和client2
*/

Thread t1= new ClientThread("127.0.0.1:2181","server1",false);
Thread t2= new ClientThread("127.0.0.1:2182","server2",false);
Thread t3= new ClientThread("127.0.0.1:2183","server3",false);
Thread t4= new ClientThread("127.0.0.1:2181","server4",false);

t1.start();
t2.start();
t3.start();
t4.start();
ControlThread c = new ControlThread(t1, t2, t3, t4);
c.start();
int i=0;
while(true)
{
i++;
i--;

}

/*
* 測試控制台輸出:
* connectIP:server4,path:null,state:SyncConnected,type:None
* connectIP:server3,path:/test,state:SyncConnected,type:NodeChildrenChanged
* connectIP:server4,path:/test/server4,state:SyncConnected,type:NodeCreated
* 。。。。。。。。。。。
*
* connectIP:server2,path:null,state:Disconnected,type:None
server2exception,KeeperErrorCode = ConnectionLoss for /test
connectIP:newServer1,path:null,state:SyncConnected,type:None
connectIP:server1,path:/test,state:SyncConnected,type:NodeChildrenChanged
connectIP:server4,path:/test/server2,state:SyncConnected,type:NodeDeleted
connectIP:server4,path:/test,state:SyncConnected,type:NodeChildrenChanged
connectIP:newServer1,path:/test,state:SyncConnected,type:NodeChildrenChanged
connectIP:server3,path:/test/server2,state:SyncConnected,type:NodeDeleted
connectIP:server3,path:/test,state:SyncConnected,type:NodeChildrenChanged
*/
}
}

2、zookeeper封裝的介面:

package ClientExample;

import java.io.IOException;
import java.util.List;
import org.apache.zookeeper.KeeperException;
/**
* zookeeper的操作封裝介面,實現了常用的操作
* 創建、銷毀、寫入、修改、查詢等。
* @author ransom
*
*/
public interface ServerOperation {
void init(String address,String serverName) throws IOException;
void destroy() throws InterruptedException;
List<String> getChilds(String path) throws KeeperException,
InterruptedException;
String getData(String path) throws KeeperException, InterruptedException;
void changeData(String path, String data) throws KeeperException,
InterruptedException;
void delData(String path) throws KeeperException, InterruptedException;
void apendTempNode(String path, String data) throws KeeperException,
InterruptedException;
void apendPresistentNode(String path, String data) throws KeeperException,
InterruptedException;

void delNode(String path) throws KeeperException, InterruptedException;
boolean exist(String path) throws KeeperException, InterruptedException;
}

3、介面的實現:
package ClientExample;

import java.io.IOException;
import java.util.List;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;
public class ServerConnector implements ServerOperation {
// 創建一個Zookeeper實例,第一個參數為目標伺服器地址和埠,第二個參數為Session超時時間,第三個為節點變化時的回調方法
private ZooKeeper zk = null;
public void init(String address,String serverName) throws IOException {
zk = new ZooKeeper(address, 500000,
new MultiWatcher(serverName));
}
@Override
public void destroy() throws InterruptedException {
// TODO Auto-generated method stub
if (zk != null) {
zk.close();
}
}
@Override
public List<String> getChilds(String path) throws KeeperException, InterruptedException {
// TODO Auto-generated method stub
if (zk != null) {
return zk.getChildren(path, true);
}
return null;
}
@Override
public String getData(String path) throws KeeperException, InterruptedException {
// TODO Auto-generated method stub
if (zk != null) {
// 取得/root/childone節點下的數據,返回byte[]
byte[] b = zk.getData(path, true, null);
return new String(b);
}
return null;
}
@Override
public void changeData(String path,String data) throws KeeperException, InterruptedException {
// TODO Auto-generated method stub
if (zk != null) {
// 修改節點/root/childone下的數據,第三個參數為版本,如果是-1,那會無視被修改的數據版本,直接改掉
zk.setData(path, data.getBytes(),-1);
}
}
@Override
public void delData(String path) throws InterruptedException, KeeperException {
// TODO Auto-generated method stub
if (zk != null) {
// 刪除/root/childone這個節點,第二個參數為版本,-1的話直接刪除,無視版本
zk.delete(path, -1);
}
}
@Override
public void delNode(String path) throws InterruptedException, KeeperException {
// TODO Auto-generated method stub
if (zk != null) {
zk.delete(path, -1);
}
}
@Override
public boolean exist(String path) throws KeeperException,
InterruptedException {
// TODO Auto-generated method stub
if (zk != null) {
return zk.exists(path, true)!=null;
}
return false;
}
@Override
public void apendTempNode(String path, String data) throws KeeperException,
InterruptedException {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
if (zk != null)
{
// 創建一個節點root,數據是mydata,不進行ACL許可權控制,節點為永久性的(即客戶端shutdown了也不會消失)
/*
* 創建一個給定的目錄節點 path, 並給它設置數據,
* CreateMode 標識有四種形式的目錄節點,分別是
* PERSISTENT:持久化目錄節點,這個目錄節點存儲的數據不會丟失;
* PERSISTENT_SEQUENTIAL:順序自動編號的目錄節點,這種目錄節點會根據當前已近存在的節點數自動加 1,然後返回給客戶端已經成功創建的目錄節點名;
* EPHEMERAL:臨時目錄節點,一旦創建這個節點的客戶端與伺服器埠也就是 session 超時,這種節點會被自動刪除;
* EPHEMERAL_SEQUENTIAL:臨時自動編號節點
*/
zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
}
}
@Override
public void apendPresistentNode(String path, String data)
throws KeeperException, InterruptedException {
// TODO Auto-generated method stub
if (zk != null)
{
// 創建一個節點root,數據是mydata,不進行ACL許可權控制,節點為永久性的(即客戶端shutdown了也不會消失)
/*
* 創建一個給定的目錄節點 path, 並給它設置數據,
* CreateMode 標識有四種形式的目錄節點,分別是
* PERSISTENT:持久化目錄節點,這個目錄節點存儲的數據不會丟失;
* PERSISTENT_SEQUENTIAL:順序自動編號的目錄節點,這種目錄節點會根據當前已近存在的節點數自動加 1,然後返回給客戶端已經成功創建的目錄節點名;
* EPHEMERAL:臨時目錄節點,一旦創建這個節點的客戶端與伺服器埠也就是 session 超時,這種節點會被自動刪除;
* EPHEMERAL_SEQUENTIAL:臨時自動編號節點
*/
zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
}
} 4、一個控制的線程,主要用來強制kill掉連接的線程

package ClientExample;

public class ControlThread extends Thread{
public ControlThread(Thread t1,Thread t2,Thread t3,Thread t4)
{
list[0]=t1;
list[1]=t2;
list[2]=t4;
list[3]=t4;
}

private Thread[] list = new Thread[4];
private int num=0;
public void run()
{
while(true)
{
if(num==7)
{
list[2].stop();
System.out.println("kill server3");
}
if(num==15)
{
list[3].stop();
System.out.println("kill server4");
}
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

5、watcher
的實現:

package ClientExample;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
/**
* 提供給多個client使用的watcher
* @author ransom
*
*/
public class MultiWatcher implements Watcher{
public MultiWatcher(String address)
{
connectAddress=address;
}

private String connectAddress=null;

@Override
public void process(WatchedEvent event) {
// TODO Auto-generated method stub
String outputStr="";
if(connectAddress!=null){
outputStr+="connectIP:"+connectAddress;
}
outputStr+=",path:"+event.getPath();
outputStr+=",state:"+event.getState();
outputStr+=",type:"+event.getType();

System.out.println(outputStr);
}
}

轉載

7、zookeeper-3.4.6怎麼啟動

1、配置java環境
2、下載zookeeper3.4.6(http://zookeeper.apache.org/releases.html)
3、解壓 zookeeper-3.4.6.tar.gz
4、進入conf目錄,cp zoo_sample.cfg to zoo.cfg,根據你的要求進行修改

[plain] view plain copy
tickTime=2000
dataDir=/data/zookeeper/
clientPort=2181
initLimit=5
syncLimit=2
server.1=master:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888

如果是single模式下,只需要修改dataDir即可。
tickTime:這個時間是作為 Zookeeper 伺服器之間或客戶端與伺服器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳。

dataDir:顧名思義就是 Zookeeper 保存數據的目錄,默認情況下,Zookeeper 將寫數據的日誌文件也保存在這個目錄里。

clientPort:這個埠就是客戶端連接 Zookeeper 伺服器的埠,Zookeeper 會監聽這個埠,接受客戶端的訪問請求。

initLimit:這個配置項是用來配置 Zookeeper 接受客戶端(這里所說的客戶端不是用戶連接 Zookeeper 伺服器的客戶端,而是 Zookeeper 伺服器集群中連接到 Leader 的 Follower 伺服器)初始化連接時最長能忍受多少個心跳時間間隔數。當已經超過 10 個心跳的時間(也就是 tickTime)長度後 Zookeeper 伺服器還沒有收到客戶端的返回信息,那麼表明這個客戶端連接失敗。總的時間長度就是 5*2000=10 秒

syncLimit:這個配置項標識 Leader 與 Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 2*2000=4 秒
server.A=B:C:D:其中 A 是一個數字,表示這個是第幾號伺服器;B 是這個伺服器的 ip 地址;C 表示的是這個伺服器與集群中的 Leader 伺服器交換信息的埠;D 表示的是萬一集群中的 Leader 伺服器掛了,需要一個埠來重新進行選舉,選出一個新的 Leader,而這個埠就是用來執行選舉時伺服器相互通信的埠。如果是偽集群的配置方式,由於 B 都是一樣,所以不同的 Zookeeper 實例通信埠號不能一樣,所以要給它們分配不同的埠號。

除了修改 zoo.cfg 配置文件,集群模式下還要配置一個文件 myid,這個文件在 dataDir 目錄下,這個文件裡面就有一個數據就是 A 的值,Zookeeper 啟動時會讀取這個文件,拿到裡面的數據與 zoo.cfg 裡面的配置信息比較從而判斷到底是那個 server。(在/data/zookeeper/目錄下touch myid,vi myid 插入對應的server.id)

5、將整個 zookeeper-3.4.6 scp到其他機器上
6、啟動zookeeper
在每台機器上運行 bin/zkServer.sh start
查看運行狀態:bin/zkServer.sh status
Mode: leader

Mode: follower

可以看出哪台為leader了

8、聯想G480IP地址的Zoo伺服器是什麼

筆記本電腦IP地址查看方法如下:
1、按下window+r鍵 打開運行框

2、輸入cmd命令回車

3、輸入查看ip地址命令:ipconfig,後回車,下拉即可查看ip地址

9、魔獸世界二區格瑞姆巴托是什麼服

二區格瑞姆巴托原為網通伺服器。
伺服器性質:PVP
CTM大伺服器合服後,基本再無網通電信說法,全伺服器都可以連接不卡。

格瑞姆巴托伺服器介紹:
自上次更新時間以來,該伺服器5343聯盟,5685部落,陣營比例非常平衡。
種族和其他伺服器基本一樣,聯盟人類一家獨大,部落血精靈略高,其餘平均。

國服 - 格瑞姆巴托 人數最多聯盟公會
排名 公會名稱 人數
1 Twinkle 291
2 zixia 205
3 xjtu 156
4 Encorelala 146
5 惡魔之魂 144
6 璀璨聖域 121
7 浮士德的傳奇 109
8 九仞 100
9 dragonsoul 81
10 殤丶會 69

國服 - 格瑞姆巴托 人數最多部落公會
排名 公會名稱 人數
1 焱淼 183
2 一殺戮一 163
3 絕美的星光 156
4 風飄緣隨 153
5 Addicted 144
6 灬四合院灬 132
7 皇朝 117
8 ZOO 109
9 奧杜爾傳奇之矛 104
10 榮耀之魂 92

該伺服器是一個不錯的伺服器,即便是在有些蕭條期的今天,也可以保證不錯的上線率和陣營人口比例,可以說是縮小版的安蘇。

10、如何連接到zookeeper伺服器

小鳥雲伺服器niaoyun實例創建好之後,您可以使用以下任意一種方式登錄伺服器:專

遠程桌面連接(,MSTSC):采屬用這種方式登錄,請確保實例能訪問公網。如果在創建實例時沒有購買帶寬,則不能使用遠程桌面連接。

管理終端VNC:無論您在創建實例時是否購買了帶寬,只要您本地有網頁瀏覽器,都可以通過管理控制台的管理終端登錄實例。

使用遠程桌面連接(MSTSC)登錄實例

打開開始菜單>遠程桌面連接,或在開始菜單>搜索中輸入mstsc。也可以使用快捷鍵Win+R來啟動運行窗口,輸入mstsc後回車啟動遠程桌面連接。

在遠程桌面連接對話框中,輸入實例的公網IP地址。單擊顯示選項。

輸入用戶名,如小鳥雲默認為niaoyun。單擊允許我保存憑據,然後單擊連接。這樣以後登錄就不需要手動輸入密碼了。

與zoo伺服器相關的知識