Columnのtimestampとか、transactionについての話

Cassandraをはじめたばっかりの時に自分の頭を整理するために書いたモデル図が他の人にも役に立ったようで、トラックバックがきていた。ありがたいことです。
で、トラックバック元のブログを読んでいたら、こんなことが書いてあった。

Columnの構成はシンプルで、name,valueとtimestampで構成されています。(中略)また面白いことにtimestampの時間は、クライアント型のtimestampを設定します。なので、サーバ側とちゃんと時間同期しておいてくださいねとのことです。思い切った割り切りですね。分散型DBってこんな感じなのでしょうか。

Cassandraのデータモデリング。或いはKeyspaceの設定方法 - プログラマになりたい

このtimestampの話って結構重要だと個人的には思っている。前からブログに書こうかなーと思ってたので、反射的に書いておく。

Cassandra Wikiにはtimestampについて以下のように書いてある。

タイムスタンプを含むカラムの全ての値はクライアントから渡されます。これはどういう事かというと、クライアントのクロックはCassandraサーバ環境間で同期が取れていなければいけないということです(カラムのタイムスタンプは衝突の解決に便利です)。

DataModel_JP - Cassandra Wiki

さらっと書いてあるけど、RDBMSからCassandraにくる人にとっては、かなり「寝言に近い」ことが書いてある。

  • Column更新時、timestampは必ずクライアント側のtimestampを渡す必要があり、この値でオプティミスティックロックがかかる
    • 「保存されているtimestamp」が「insert/deleteで渡すtimestamp」より大きくないと更新できない
  • Cassandra自体にクラスタノードのtimestampを同期をする仕組みはない
    • NTPなど他の手段で同期する必要があるが、クラスタ上のサーバ全てがミリ秒単位で同一時刻になる事は保障できないし、しようがない

Cassandraの実装上、単体ではシステム一意なtimestampを取りようがないので、ほぼ同時にColumn更新が発生した場合、結果がどうなるか不定となってしまう。

短絡的に考えると「1台タイムサーバを立てて、そこからtimestampを取ったら・・・」というのが思いつくが、それではそのタイムサーバが単一障害点になってしまうので、それもありえない。また、仮にタイムサーバを立てたとしても、そもそもtransactionに該当する機能を持っていないので、複数Columnの更新が厳密に行える訳ではない。

要は「CassandraのColumn更新(同時更新)はRDBMSのように厳密ではない」という事が、さらっと書かれている訳である。これは現状のColumn-Orientedなデータベース共通の特徴だったりするんだけど。

なので、Cassandraでtransactionが必要なシステムを構築する必要がある場合、ZooKeeperなどを利用して自前でtransactionを実装するか、運用でカバーするか(transactionをシステムで担保するのではなく運用でリカバリーできるようにする)、そもそもtransactionを諦めるか、となってくる。

ちなみにTwitterDiggがCassandraを採用した(検証している)のは、そのデータの特性がポイントになっている(はず)。というのも、writeのほとんどが追記で、更新があったとしても同時更新はまず発生しないし、仮に更新が衝突して結果が不定になってしまってもシステム的にはなんら問題がない事は念頭に置いておくべきである。

2010/05/10追記

そもそもCassandra Wikiにデータの一貫性は重視してないって明記してあった。

CAP定理

Eric Brewer(エリック・ブルーワー)のCAP定理 (PDF)に支配された状況では、Consistency(一貫性、コンシステンシー)、Availability(可用性、アベイラビリティー)、Partition-tolerance(分割耐性、パーティショントレランス)のうち2つを選択する必要があります。同時に3つの性質を満たすことはできないため、それらを得るにはレイテンシー(遅延)を許容する必要があります。(訳注:BASEの考えを適用する必要があります)

Cassandraは、可用性と分割耐性(AP)を重視しています。一貫性と遅延はトレードオフの関係にあり、Cassandraでは整合性レベルが調整可能(tunable)です。遅延を許容すればCassandraでは強い一貫性(Strong Consistency)を得ることができます。しかし、行ロックを取得することはできません。その点は、HBaseの方が優れています。

メモ: HBaseは、一貫性と分割耐性(CP)を重視しています

ArchitectureOverview_JP - Cassandra Wiki

Cassandraは、CAP定理のC(一貫性)を捨てる代わりに、A(可用性)を重視して「I/O(特にWrite)が高速」になっていることが特徴である。

逆に一貫性やtransactionを重視する必要がある場合は、HBaseやOracle RACなどを使えってことで。

2010/05/10追記2

どのデータベース(ストレージ)がCAP定理のどれを重視しているかは、Publickeyに良い記事がある。
NoSQL登場の背景、CAP定理、データモデルの分類 - Publickey