Cassandraソースコードリーディング その1

Cassandraは言わずとしれたNoSQL型データベース。もともとFacebookで開発されたものが、Apacheに寄贈され、オープンソースプロジェクトとして今も開発が続けられている。Cassandraに関するドキュメントは山のようにあるので*1、ここから新しい情報は得られないと思うけど、個人メモとして残しておく。対象バージョンは1.0.9。

まず、gitからコードをもってくる。

$ git clone http://git-wip-us.apache.org/repos/asf/cassandra.git
$ cd cassandra
$ git checkout -b cassandra-1.0.9 cassandra-1.0.9
$ find . -name "*.java" | etags -

最初はCassandraデーモンの起動部分から追ってみる。

bin/cassandraという起動スクリプトを見ると、最終的に「org.apache.cassandra.thrift.CassandraDaemon」ってのを実行していることがわかる。Thriftってのがあやしい。Thriftは多言語に対応したRPCフレームワークとある。RPCとはクライアントからサーバの手続きを遠隔呼出しする仕組みだけど、両者がおしゃべりする部分のコードは定型的である。そこでインタフェースやデータ構造をIDL(インタフェース定義言語)という一種のDSLで記述し、コードを自動生成する。RPCを同期でやるか非同期でやるかという制御もあるが、cassandra.yamlによるとデフォルトは同期型である。

ThriftのIDLファイルはinterface/cassandra.thriftである。namespace、struct、enum、exception、serviceなどの定義が並んでいる。serviceの中にget、insert、add、removeといういかにもKVS的なメソッドが並んでいる。interface/thrift/gen-java以下には自動生成されたソースコードがある。これを読むのは時間の無駄なので、デーモン(サーバ)側のメソッドの実体を探すことにする。

src/java/org/apache/thrift/CassandraServer.javaにサーバ側のメソッドの実体があるようだ。insert、add、remove、batch_mutateなど、データの更新を行う処理はすべてdoInsert()メソッドに帰着する。データの更新操作はmutationというデータ構造として表し、このリストをdoInsert()の引数として渡す。実際の書き込み操作はStorageProxyを介して行い、ここで一貫性レベルを考慮したレプリカ制御も行っているようだ。

ということで、今日はここまで。

蛇足:Emacs + etagsで読んでいるが、やっぱりクラス階層を認識してくれないのがきつい。かといってEclipseをインストールするのは気が進まない。。。

次は今回使ったEmacsの設定。

; 複数人で読むときは行数が表示されていた方が便利なので、linum.el使った。
(require 'linum)
(global-linum-mode)

; Javaのソースコードは横に長いので折り返しをトグルで切り替えられるようにした。
; Javaモードの場合は折り返さないようにフックを入れてしまうのもありかも。
(defun toggle-truncate-lines ()
    "Toggle truncate lines"
    (interactive)
    (if truncate-lines
        (setq truncate-lines nil)
        (setq truncate-lines t))
    (recenter))

(global-set-key "\C-c\C-k" 'toggle-truncate-lines)

*1:例えば、「Cassandra入門と、さらに詳しく知るためのリソース集」。そこからもリンクがあるが、Wikiの「Architecture Internals」も参考になる。