Aug 1, 2014

Coordination Service(ZooKeeper,etcd ,consul) の比較

概要


最近,consul,etcd,ZooKeeper といった,いわゆる Coordination Service(この名前は ZooKeeper の論文から拝借した)の実装が頻繁に行われている.本記事では,開発が盛んな背景を踏まえた上で,オープンソース実装の Coordination Service の比較を行う.

Chubby から現在まで


Paxos が Google の手によって Chubby という形で実用化された後,故障検出+分散合意アルゴリズムを用いた高可用KVSという組み合わせによる Coordination Service のオープンソース実装がいくつが出てきた.そのはしりが ZooKeeper である.ZooKeeper は Hadoop ファミリではデファクトスタンダードの Coordination Service であり,Hadoop を初めとして HBase,Mesos,Flume などのプロジェクトや,多くの企業で実際に使われている.その後,しばらく新しい Coordination Service のオープンソース実装はでてきていなかった.それが,2013年に Raft という分散合意アルゴリズムが公開されて以降,一気に情勢が変わった.consuletcd などが公開されたのである.Raft は,ざっくばらんに言うと実装が簡単な Paxos である.実装がどれくらい容易であるかは,実装数を見れば明らかであろう

ZooKeeper と etcd と consul


複数の実装が出てくることで競争が発生しソフトウェアが成熟してくれるのは喜ばしいことである.しかしながら,利用する側から見ると,どういった観点で何を利用したら良いのかが自明ではない.そこで本節では,分散処理基盤の開発者という視点で比較を行う.

ZooKeeper は,以下の特徴を持つ Coordination Service である.まず,Paxos ベースの分散合意アルゴリズムである Zab  を利用しており,サーバ側の台数の増加に対し,読み込みがスケールする形で設計されている.また,Chubby の持っているファイルシステムのような API を拡張し,その API の上で様々な分散コンポーネントが構成可能である.特に,ephemeral node(クライアントが故障した際に消滅するznode) や sequential node(連番生成機能を行うためのznode),watcher(特定のznodeおよびその子のznodeに対する変更を通知する仕組み),multi(複数のznodeをアトミックに操作する仕組み) を用いることで幅広いアプリケーションを構築可能となっている.サーバ側で起きた全てのイベント(ephemeral node の消滅,増加およびその他 znode への書き込み)はどのクライアントから見て同じ順番で通知されることが保証されているため,妙なコーナーケースについて考える必要がない.
Server-Client は jute というシリアライゼーション形式と TCP コネクションに基づいた RPC で行われているため,実装コストが他の実装に比べて高いという欠点がある(この問題を解消するため,4.0.0 リリースに向けて protobuf などで置き換えようというチケットがある).

etcd, consul は,Paxos ベースの分散合意アルゴリズムである Raft を利用しており,台数を増やしても書き込みも読み込みもスケールしない.また,ZooKeeper の API を踏襲しつつも,クライアントの実装コストを減らすために RESTful API が提供されている.これにより,クライアントの実装コストを大幅に削減できている.etcd, consul は両方とも,ephemeral node がないので,定期的にポーリングしてメンバシップの変更があったかどうかを自分で検出する必要がある(etcd も consul も,ephemeral node は fat client の原因になるので入れたくないと述べている.etcd のgithub issueconsul のHP参照.).このため,分散ロックなどの複雑な機能をバグなく作成する用途では,ZooKeeper の方が優れているように思う.もしくは,etcd,consul 版の Curator (ZooKeeper で使いたくなるような機能をまとめたライブラリ.当初は Netflix が作成し現在は Apache プロジェクト化) が出てきて,利用されるようになる可能性はある.

これに加え,consul にはいくつか大きな特徴がある.死活監視機能と DNS インタフェースである.まず死活監視機能だが,gossip protocol によるクライアントの死活監視機能とRaftベースの高可用KVSにregistrationすることによる死活監視機能の2つがあるという点である.gossip protocol によるクライアントの死活監視は一貫性が弱く,クライアント数の増加に対してスケーラブルである.この情報にアクセスするには, agent endpoint と利用する.一方で,高可用KVSによる死活監視機能は一貫性が強く,クライアントの増加に対しては gossip protocol による死活監視と比較してスケーラブルではない.この情報にアクセスするには catalog endpoint にアクセスをする.consul では,この2つを使い分けることで,強い一貫性を必要とする分散システムの構築(分散ロックなど)と,スケーラビリティを必要とする分散システムの構築(Web サービスのデプロイなど)の両方に対応しようとしているようにみえる.DNS インタフェースについては,register したノードに対して dig や nslookup でアクセスできるというものである.Chubby の論文の中でも,DNSライクに利用することについて触れられているので,この使い方は Coordination Service としては王道なように思える.

まとめ


本記事では,Chubby から ZooKeeper,そして Raft ベースの Coordination Service の流れをまとめて説明した上で,機能の比較を行った.ZooKeeper,etcd/consul の大きな違いは API(RESTful API が提供されているか否か)と ephemeral node の有無である.さらに,consul には,従来の Coordination Service の機能に加え,gossip protocol を用いた弱い一貫性のクライアント死活監視と,DNS インタフェースが用意されている.これらの特性の違いから, Coordination Service はAPIやスケーラビリティによって使い分けることが必要であるため,用途をよく理解した上でどれか1つを選択する必要がある.

知っている情報を,ソースを明らかにした上で述べたつもりですが,もし誤っている箇所などありましたら,ご指摘お願いします.