第9回 Cassandra 勉強会
川中 真耶 a.k.a. MAYAH
@mayahjp
Cassandra で WebApp を
基本にたちかえって、Cassandra を backend に WebApp を 作る場合に気をつけないといけないことを探ってみる
RDB で作った方がよいものを無理矢理 Cassandra で作って みて、何が問題になるかを探る
題材: イベント開催・参加管理
管理者がイベントを登録
参加者はイベントに参加 登録を出す
申し込みは早いものがち キャンセルとかも出来る 早い話が atnd.org のぱく(ry
UNDER CONSTRUCTION
作っていて問題になった点
データ構造 & Transaction ソート
Transaction again (別の問題)
データ構造 & Transaction
主要なデータ構造 (RDB 脳で)
イベントテーブル
ユーザーテーブル
この2つは Cassandra に直すのも簡単 (id を key にする)
id title date desc
event id タイトル 開催日 説明
id name
user id ユーザー名
参加テーブルは?
RDB 脳で作ると次のようになり、RDB ならこれで OK
これを Cassandra に落とす場合は何を key にして保持すれ ばいいの?
event_id user_id date
event id user id 申込日時
参加テーブル (contd.)
event_id を key に保持すると user から検索できなくなる user_id を key の保持すると event から検索できなくなる
➡
解決策は両方持つこと (当たり前ですね)Transaction の問題がッ
先生! 1つ書いた後も う1つを書くまでの間に サーバーが落ちたらどう したら良いですか!
CRASH!!
Cassandra
AP
Transaction の問題がッ
RDB では、データの書き込みは transactional にできたが、 Cassandra ではそうはいかない。
1つだけ書き込んだ後にエラーが発生する可能性があり、 そうすると不整合が発生
commit/rollback とかない
Transaction は出来なくとも
後でリカバリーはしたい
一瞬不整合が起きているのは許容
最終的には問題ない状態にしておきたい
没案:不整合を検出するため
に1日1回チェック
全部に不整合がある訳じゃない 処理量が多い
案:Redo log を持ってしまう
普通に書き込もうとする前に redo log を書き込み その後いくつか書き込み
全部うまくいけば redo log を削除
➡
redo log があるので落ちても後から整合性が取れた状態に 持って行ける他に良い方法あったら教
えてください
ソートの問題
イベントの開催日時で
ソートしたい
Cassandra では Column は name で自動的にソートされる Recall: Column = name + value + timestamp
イベント一覧の name を開催日時にしておけばいいんじゃな い?
value を event id にして、そこから引いてしまえば OK
開催日時を update すると?
当然対応する name 部分を書き換える必要がある
ユーザーが参加するイベントを
開催日時で並べたいときは?
ユーザーごとに、どのイベントに参加しているかを表す column を持つ
そのイベントに参加する人が 1000 人いたら、その人達の分 1000 個 name を変更しろということですか?
なんかすごい残念感があるが、実はあんまり開催日時を 変更することはないので OK かもしれない。
結論
なんか残念だったのでnameを開催日時にするのはやめた。 一人のユーザは 1000 個ぐらいまでしかイベントに参加しな いだろうから、表示時に毎回ソート。
表示時には全部イベントを取ってこないといけないの で、それにソートが加わってもたいしたことない。
nameを開催日時にして表示時に実際の開催日時と食い違っ ている場合は直すという様にしても良いかも知れない。
Transaction Again
参加人数を数えたい
参加者が増えたら[減ったら] atomic に1を足す[引く]だけの 簡単なお仕事
これさえ Cassandra だけだと出来ません
没案:1つのスレッドから
のみ書き込みをする
没案:1つのスレッドから
のみ書き込みをする
たんいつしょうがいてん つくっちゃってどーすんの
どうしようもないので
get_count() で O(N) 使って取ってくる N が小さければ問題ナシ
count にしか使えないのであまり汎用的な解決法ではない
Apache Zoo Keeper を使ってロックする
出来るけどロックするのでちょっと残念ではある
Cassandra に check and set
ぐらい実装できないか?
lock はしたくない。失敗したらもう一回やればいい
まず consistency level ALL で読み込み、データを持ってい るノードに順番を付けてその順番で CAS するとかすればな んとかなる? (まだ証明してない)
CAS 以外の操作が来たらなにも保証できない
DEMO
DEMO 8月リリー ス予定
只今 UI 実装中
さいごに
ASCII .technologies で
Cassandra 連載が始まります。 みんな見てね!