Cassandra実践入門―Twitter,Facebookが採用するNoSQLシステム

この記事を読むのに必要な時間:およそ 10.5 分

CassandraとBigtable,Dynamo

CassandraはBigtableとDynamo双方の影響を強く受けたシステムです。どのような影響を受けているのかを見ていきましょう。

データモデル

Cassandraのデータモデルは「カラムファミリ」Column Familyと呼ばれる構造を基本としています図2⁠。この構造はカラムファミリという名前も含めてBigtableから取り入れられたものですが,後述するように,より複雑なデータを扱えるように拡張されています。図2の一番外側の「キースペース」Keyspaceはカラムファミリの属する名前空間を管理するものですが,これはCassandra独自の機構です。

図2 Cassandraのデータモデル

図2 Cassandraのデータモデル

http://d.hatena.ne.jp/terurou/20100411/1270912571に掲載されている図の改訂版をterurouさんより提供いただき,許可を得て掲載

一方Dynamoは単純なキーと値のペアであるキー・バリュー型のデータモデルを採用しています。Cassandraのほうが,より高度なデータ管理機能を持っていると言えます。

キースペースとカラムファミリ

Cassandraではクラスタ内に複数のキースペースを定義することができ,RDBMSでいうデータベースと同じような役割を果たします。カラムファミリはRDBMSにおけるテーブルにあたります。キーとそれに紐づく行Rowは,RDBMSでのプライマリキーや行と同じような位置づけになります。

カラムファミリの行部分は,プログラミング言語におけるHashMapや連想配列などのように,{名前:値}の組を複数格納するデータ構造です注3⁠。1つの{名前:値}の組を「カラム」Columnと呼びます。RDBMSとは異なり,カラム名を事前に定義する必要がなく,任意に追加や削除ができます。

カラムファミリのデータ構造は次のようなJSON形式で表現できます。

AddressBook = {
  "yamada taro": {
    "name": "山田太郎",
    "address": "東京都品川区****",
    "phone": "03-xxxx-xxxx"
  },
  "sato hanako": {
    "name": "佐藤花子",
    "address": "東京都墨田区****",
    "mobile": "090-xxx-xxxx",
    "email": "hsato@xxxx.ne.jp"
  }
};

この例ではAddressBookというカラムファミリを表現しています。山田さんの行にはmobile,emailというカラムがなく,佐藤さんの行にはphoneというカラムがありません。このように,行によってカラムが不ぞろいなデータ構造を表現できます。

スーパーカラム

AddressBookの例で示したデータ構造はBigtableとほぼ同様ですが,Cassandraではさらに「Super」と呼ばれるタイプのカラムファミリを定義できます。

AddressBook2 = {
  "仕事": {
    "yamada taro": {
      "name": "山田太郎",
      "address": "東京都品川区****",
      "phone": "03-xxxx-xxxx"
    }
  },
  "プライベート": {
    "sato hanako": {
      "name": "佐藤花子",
      "address": "東京都墨田区****",
      "mobile": "090-xxx-xxxx",
      "email": "hsato@xxxx.ne.jp"
    }
  }
};

AddressBook2では,データを「仕事」「プライベート」に分け,ネストを一段深くしています。このような二重のハッシュ構造を「スーパーカラム」Super Columnと呼びます。

注3)
実際には名前と値に加えてタイムスタンプも格納されます。

分散アーキテクチャ

Cassandraの分散システムとしてのアーキテクチャを図3に示します。クラスタ内の各ノードとなるサーバは論理的なリング(ノードを一定の順序で並べ,先頭ノードを末尾ノードの後続とみなして終端をなくす構造)を構成し,キーに対応するデータを分担して保持します。ノード同士はそれぞれ対等で,マスタやスレーブといった役割の違いはなく,お互いに通信し合って自律的に動作するP2PPeer to Peer型のシステムです。

このようなアーキテクチャは,リングの構成に関するアルゴリズムやノード同士の通信プロトコルなどの理論基礎を含め,すべてDynamoから受け継いでいます。

図3 Cassandraの分散アーキテクチャ

図3 Cassandraの分散アーキテクチャ

一方Bigtableは,クラスタ全体を統括する1台のマスタサーバと,データの実体をタブレットというファイルに分割し管理するタブレットサーバと呼ばれるサーバ群によって構成されています。

CassandraやDynamoはリング上のどのノードが障害を起こしても全体としては動き続けますが,Bigtableはマスタサーバがダウンするとクラスタ全体が止まってしまいます。これはSPOFSingle Point of Failure単一障害点)と呼ばれるアーキテクチャ上の弱点です。

ノードとトークン

Cassandraではノード同士はお互いにGossipと呼ばれるプロトコルで通信し,クラスタ内の各ノードの状態を共有します。

また,ノードはそれぞれトークンTokenと呼ばれる固有番号を割り振られます。トークンはシステムによって自動で割り振ることも,管理者が手動で割り振ることもできます。トークンはリングの並び順や,ノードとキーの対応関係を決めるのに使われます。

パーティショニングとレプリケーション

Cassandraでは,データをキーに基づいて各ノードに分散して格納します。このことをパーティショニングPartitioningと呼びます。どのキーがどのノードの受け持ちになるかは,分散ハッシュテーブルDistributed Hash Table, DHTの一種であるコンシステントハッシュ法Consistent Hashingと呼ばれるアルゴリズムによって決定されます。

また冗長化のために,データを別のノードにレプリケーションさせることができます。レプリカ(複製)の数を決めるパラメータをレプリケーションファクタReplication Factorと呼び,レプリカ数+1(本来のデータ分)を指定します。

パーティショニングとレプリケーションはクラスタの構成を決める重要な要素で,Cassandraではデザインパターンの一つであるストラテジーパターンを使ってアルゴリズムを選択できるようになっています。詳しい設定方法については後述します。


Cassandraのアーキテクチャについて概観してきました。以降はCassandraを使用したシステム構築に必要な事柄について見てみましょう。

著者プロフィール

島田慶樹(しまだけいき)

株式会社ケイビーエムジェイ コマースソリューション事業部 シニアエンジニア。

主にRuby on RailsによるWebシステム開発に従事。大規模ASPサービスの開発・保守を通じてシステムのスケーラビリティやパフォーマンスの問題に取り組み,NoSQLを始めとしたさまざまな技術と格闘する日々。好きなプログラミング言語はSmalltalkとLisp。いつかはPrologをマスターしたいと思いつつ,今はScalaをかじっている。

Twitter:@_shimada