zookeeper疑問

4494 ワード

今年の初めに、Zoo Keeperの入門文章「初心者のZoo Keeper」を書きました。今週になってから、Zoo Keeperのソースコードを全部読みました。Zoo Keeperの仕事の原理と細かいところは完全に理解したとは言えませんが、これまでZoo Keeperについての疑問は全部説明されました。
今ネット上ではZoo Keeperに関する文章が多く、Leader選挙のアルゴリズムを紹介しています。Zoo Keeper Serverの内部原理を紹介しています。Zoo Keeper Cientも紹介しています。本文はまたこのような内容を書くつもりはなくて、一心に読者のZoo Keeperに対する疑問を解答します。
ZOOKEEPERはクライアントで何をしましたか?
Zoo Keeperを使ったことがある読者はご存知です。クライアントを初期化するコードは以下の通りです。
 
System.out.println("Starting ZK:");
zk = new ZooKeeper(address, 3000, this);
System.out.println("Finished starting ZK: " + zk);
 
お客様の初期化が完了したら、Zoo Keeperに対応した操作ができます。
 
if (zk != null) {
    try {
        Stat s = zk.exists(root, false);
        if (s == null) {
            zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE,
                    CreateMode.PERSISTENT);
        }
    } catch (KeeperException e) {
        System.out
                .println("Keeper exception when instantiating queue: "
                        + e.toString());
    } catch (InterruptedException e) {
        System.out.println("Interrupted exception");
    }
}
 
上のコードは簡単明瞭に見えますが、Zoo Keeperのクライアントはバックグラウンドで黙々として多くのことをしました。
  1 Zoo Keeperサーバと通信し、接続、メッセージ送信、メッセージ受信を含む。
  2心拍情報を送信し、Zoo Keeperサービスとの有効な接続とSessionの有効性を維持する。
  3エラー処理は、クライアントが現在接続されているZoo Keeperのサービスが失効すると、自動的に他の効果的なZoo Keeperサービスに切り替わります。
  4 Watchを管理し、異常呼び出しとWatchを処理する。
WATCHERのイベント通知メカニズムはどうやって実現されますか?
Googleの分布式ロック機構Chubby論文を見たら、Zoo Keeperの中に一つのイベント購読メカニズムが多くなっています。Watch。Watchの内部はどうやって実現されますか?
実は、Zoo Keeperクライアントには、メンバー変数(ZKWatch Manager)がすべてのWatchを管理しています。ユーザーが以下のコードを使う場合:
 
List<String> list = zk.getChildren(path, watcher);
 
Zoo KeeperはこのWatchをZKWatch Managerに格納し、同時にZooKeeperサーバにClient対応のSessionのPathに登録されているイベントの種類を記録するように通知します。Zoo Keeperサーバで指定されたイベントが発生したら、Zoo KeeperサーバからZoo Keeperクライアント、Zoo KeeperクライアントにZKWatch Managerから対応するコールバック関数を見つけて実行します。
全体のプロセスでは、クライアントはイベントの情報とWatchの実行ロジックを記憶し、サービス端末はイベントの情報のみを記憶する。
ZOOKEEPERクライアントの使い方
Zoo Keeperクライアントを実例化するごとに、Sessionが開かれます。Zoo Keeperクライアントはスレッドが安全であり、接続プールが実現されたとも考えられます。
したがって、各アプリケーションは、Zoo Keeperクライアントを実装するだけでよく、同じZoo Keeperクライアントのインスタンスは、異なるスレッドで使用することができる。
同じアプリケーションで複数のSessionをオープンしたい場合以外は、異なるWatchを使用して、この場合にこそ、複数のZoo Keeperクライアントを実装する必要があります。
ZOOKEEPERはZNODEに対してサイズ制限がありますか?
ZooKeeperの文書をよく見たら、文書の中でZNodeの大きさに制限があり、最大で1 Mを超えてはいけません。
この1 MのサイズはZooKeeperのクライアントとサービスに制限があります。
クライアント:
 
packetLen = Integer.getInteger("jute.maxbuffer", 4096 * 1024);

int len = incomingBuffer.getInt();
if (len < 0 || len >= packetLen) {
	throw new IOException("Packet len" + len + " is out of range!");
}
 
サービス:
 
static public final int maxBuffer = determineMaxBuffer();
private static int determineMaxBuffer() {
    String maxBufferString = System.getProperty("jute.maxbuffer");
    try {
        return Integer.parseInt(maxBufferString);
    } catch(Exception e) {
        return 0xfffff;
    }
    
}

if (len < 0 || len > maxBuffer) {
    throw new IOException("Unreasonable length = " + len);
}
 
Zoo Keeperは確かにデータのサイズに制限があります。デフォルトは1 Mです。もし1 M以上のデータを転送したいなら、環境変数「jute.maxbuffer」を修正すればいいです。
なぜZOOKEEPERのZNODEのサイズを制限しますか?
Zoo Keeperはスループットが高いシステムです。システムの読み込み速度を上げるために、Zoo Keeperはファイルから必要なデータを読み取ることができず、直接メモリから検索します。
また、Zoo Keeperクラスタのサーバごとにフル量のデータが含まれており、これらのデータはメモリにロードされます。ZNodeのデータとAppleの操作をサポートします。全部Replaceです。
したがって、上の分析からは、ZNodeが大きすぎると、ZNodeが不確定な遅延を引き起こす可能性があります。同時にZNodeが大きすぎて、Zoo Keeperサーバのメモリを使い果たしてしまいます。これはなぜZoo Keeperが大量のデータを格納するのに適しないのかという理由でもある。
ZOOKEEPERクラスタの性能を向上させるにはどうすればいいですか?
性能は,書き込みの性能と読み取りの性能の両方から考えられるという。
Zoo Keeperの書き込みはまずリーダーを通して、そしてこの書き込みのメッセージは半分以上のFellowerを通じて全体の書き込みを完了する必要があります。したがって、クラスタ全体の書き込みの性能は、サーバの数を増やすことによって達成できず、逆に、クラスタ全体にFellowerの数が多いほど、クラスタ全体の書き込みの性能が悪い。
Zoo Keeperクラスタ内のサーバごとにデータの読み取りサービスを提供することができますので、クラスタ全体のサーバ数が多いほど、読み取りの性能が良いです。しかし,Fellowerの増加はクラスタ全体の書き込み性能を低下させる。この問題を回避するために、ZooKeeperクラスタの一部のサーバをObserverに指定することができる。