Upload
lamanh
View
228
Download
3
Embed Size (px)
Citation preview
第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 nameuser 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!!
CassandraAP
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
DEMO8月リ
リース予定
只今 UI 実装中
さいごに
ASCII .technologies でCassandra 連載が始まります。
みんな見てね!