第17回Cassandra勉強会: MyCassandra
-
Upload
shunsuke-nakamura -
Category
Technology
-
view
7.155 -
download
4
description
Transcript of 第17回Cassandra勉強会: MyCassandra
中村 俊介 東京工業大学 大学院 情報理工学研究科 数理・計算科学専攻
中村 俊介 (24) • @sunsuk7tp • 富山出身/P.A. WORKS好き/今季はシュタゲが一番 • 東工大大学院 CSのM2 • 研究内容: 分散システム
学部: HPC TSUBAMEのボスの研究室 MPI, Cell B.E., GPU CUDA, Hadoop on グリッド、スパコン
修士: クラウド 首藤研 分散データベース, P2P 最初の対外発表はNoSQL Afternoon in Japan (10.11.1, 楽天タワー) SACSIS 2011 優秀若手研究賞受賞
• Webエンジニアのアルバイトを6年間 PHP, Perl, JavaScript 現在は、はてなのインターンを経てインフラアルバイト
Apache Solr, MySQLの運用、監視ツール作成 NoSQL調査・運用
各NoSQLを負荷かけていじめまくって、世に出ていない問題点を洗いだすお仕事
• 趣味はJazz, 特技はtrumpet • Cassandraは0.6.0からのお付き合い
@railuteさん、@yutuki_rさん、@techmemoさんの ブログにお世話になりました
Itmediaさんの記事 第3回 「斜め上をいく発想」ができる学生求む!はてなのインターンは本格派 http://lab.jibun.atmarkit.co.jp/entries/1058
+
NoSQL, Key-Value Store (KVS), Document-Oriented DB, GraphDB 例: memcached, Google Bigtable, Amazon Dynamo, Amazon SimpleDB, Apache Cassandra, Voldemort, Ringo, Vpork, MongoDB, CouchDB, Tokyo Tyrant, Flare, ROMA, kumofs, Kai, Redis, LevelDB, Hadoop HBase, Hypertable, Yahoo! PNUTS, Scalaris, Dynomite, ThruDB, Neo4j, IBM ObjectGrid, Oracle Coherence,その他100種類以上
既存データストアと比較した特徴: 「省機能 ↔ 大容量・高性能」
• データのアクセスは主キーに制限 • join, transactionのような高級な機能はサポートしない • 大規模なデータ / ノード数についてスケーラブル
大規模なデータを高速に処理する分散データストア
小 大
• 分散はクライアント側で • キャッシュを想定
• master/slave • data/meta/proxyノード • 機能が豊富 • Map Reduceと連携しやすい
• decentralized • とにかく、 スケーラビリティと 性能にこだわる
同一ラック内 ラック/DCまたぎ
クラスタを構成する集合の規模が異なる
SPOFの無い非集中型クラウドストレージ 複数DCにまたがる数百ノードで動作
dc1 dc2
dc3
複数rack/dcに跨るクラスタ構築 regionを考慮した複製配置
クラウド • ネットワークを介して他地点の資源を連携して利用
クラウド環境で起こる故障 • (※) ハードウェア << ソフトウェア& ネットワーク
• 多重故障, correlated failure SPOF = “単一”故障点 単一のレベル
• 従来: 1ノード • クラウド: ラック/データセンターも考慮
(※) Daniel Ford et. al. (Google), “Availability in Globally Distributed Storage Systems”, OSDI 2010
単一のモジュールが故障したらデータノードの生死に関わらず問い合わせ不能 ⇒ プロキシもメタ鯖も冗長化すればいいよね!!
どのレベルでもSPOFが無いと言い張るには、 各モジュールの配置を利用者が管理する必要がある
世界中に散らばる数百~千ノードで SPOFの無いシステムを簡単に作れますか?
なぜなら、decentralizedだから • ノード全員がproxy/master/slaveである
利用者はリソースとレプリケーション配置方法を選択するだけ
Consistent Hashing (非集中分散アルゴリズム) データの主キーのハッシュ値から担当ノードが一意に定まる
A Z F
N V
key values
hash(key) = Q
Q
ノードID空間
primary
レプリカ数N := 3
secondary 1
secondary 2
全ノードが全部やる • request proxy • データのprimary node • 別データのsecondary node
(A~Zはハッシュ値)
MyCassandraとは?
map それぞれ SQL 他
relational data model
Megastore library
table (multi-dimentional
sorted map)
(sorted) records + indices
(sorted) map + indices
(sorted) map
アプリ
ストレージ
インタ フェース
データ モデル
物理 データ構造
RDB Bigtable 他 KVS
NoSQLは、その上で動かすアプリに応じて、 これらの構造を分解・再構築したもの
PNUTS (VLDB ‘08): MySQLをNoSQLとして使う分散データストア
YCSB (SOCC ’10): クラウドストレージ のベンチマーク
Write-Heavyワークロードの 遅延
Read-Heavyワークロードの参照遅延
Bet
ter
read-optimized
write- optimized
read-optimized
write-optimized
予測: クラウドストレージの読み書き性能の性質は、分散の仕組みではなく、中で使われるストレージ部分に依存する
⇒ 例えば、Cassandraのストレージ部分をMySQLに変えると読み書きの性能の性質はどうなるか?
読み書き性質 ストレージ部分 分散部分
Apache HBase write optimized Bigtable like centralized
Apache Cassandra write optimized Bigtable like decentralized
Sharded MySQL read optimized MySQL centralized
Yahoo! Sherpa read optimized MySQL centralized
MyCassandraとは?
= Dynamo + Bigtable
= Dynamo + Bigtable
分散の部分 (P2P/decentralized) ストレージの部分
= Dynamo +
分散の部分 (P2P/decentralized) ストレージの部分
ウェブで世界的に幅広く使われるRDBMS ストレージエンジンというTable単位で選択自由なコンポーネント
query
• 永続/キャッシュの選択 • インデックスの選択 • 拡張性の高さ
このようなモジュラリティは NoSQLにも当然活かせる!!
MyCassandraとは?
= Dynamo +
分散の部分 (P2P/decentralized) ストレージの部分
= Dynamo + MySQL
Bigtable Redis
: ストレージエンジン
に
のようなストレージエンジンを
導入したモジュラークラウドストレージ
分散のしくみ (master/worker, sharding,
consistent hashing)
物理データストア
• cache / persistence • index • write/read-optimized • ノウハウ
1つの分散データストア
分離
+
11.6.24 MyCassandra 25
クエリの受理とストレージの間に インタフェースを用意
基本的には分散部分はノータッチ
インタフェースを 実装することで
ストレージエンジンを追加可能
選択
InnoDB (MySQL 5.1~デフォルト) MyISAM Memory Merge Archive Federated NDB CSV Blackhole (笑) FALCON MariaDB Drizzle solidDB :
InnoDB/MyISAMが主流 クラウド向けストレージエンジンもある MySQL Cluster
MySQL: 中のストレージエンジン選択は自由 Bigtable: 既存のCassandra Redis: オンメモリ/非同期snapshot MongoDB: 多機能ドキュメント指向DB
今後いろいろ採り入れていく予定 できればそのストレージに詳しい人に 作ってもらいたいです!!
任意のデータベースをdecentralized化 • クラウドに対応しきれていないデータベース
RDB (MySQL / PostgreSQL) • master/slave型をdecentralizedに
MongoDB / Redis
同じデータセットに対して異なる要求がある場合に有効 • MapReduce
データをMySQLにロードしておいて、中間データを一時的にBigtableに MySQL (InnoDB)はINSERTが不得意 逆にBigtableは更新が発生しなければ、INSERT/GETは早い
• 全文検索 クローラ/インデックス構築/検索
EC2+RDSによるMyCassandraクラスタ
永続化 / キャッシュの選択 I/O性質に応じたインデックスの選択
• Bigtable (LSM-tree) • MySQL (B-trees/他) • Redis (Hash) • MongoDB (B-tree) • KyotoCabinet (B+ tree/hash)
インデックス hash B-Trees LSM-Tree
write 定数オーダー 1回のrandom I/O append
read 定数オーター 1回のrandom I/O N回のrandom I/O + merge
性能の性質 小規模・cache 読み出し性能重視 書込み性能重視
例 Memcached, Redis, KyotoCabinet
MySQL, MongoDB, KyotoCabinet
Cassandra, HBase, LevelDB
永続化する場合、読み出しと書込みの性能はトレードオフの関係にある
ストレージエンジン単体では両立できないので、 アプリのデータサイズや読み書き比率に応じて選択が必要
+
データの差分をディスクにsequential write ディスクへのランダムI/Oが発生しないので高速
Always writable ディスク書き込み時にwrite-lockが不要
書き込み処理が速い: O(1)
memory
disk
Commit Log
Memtable
SSTable 1 SSTable 2 SSTable 3
write path sync async flush
sequential write
<k1, obj (v1+v2)>
<k1, v1>, <k1, v2>
<k1,obj1>
<k1,obj3>
<k1,obj2>
LSM-Tree [P. O’Neil ‘96]
disk mem
SSTableごとに木を構成
+
Keyに対して • Memtable上の最新value • SSTable上の複数の古いvalueをマージ
ディスクへの複数回のランダムI/Oが発生するため、読み出し性能は犠牲になる
読み出し処理は遅い
Commit Log
Memtable
SSTable 1 SSTable 2 SSTable 3
merge client
<k1,obj>
<k1,obj1>
<k1,obj2>
<k1,obj3>
<k1,obj+obj1~3>
複数回のランダムI/O 複数回のランダムI/O
memory
disk mem disk
disk上の各部分木を探索
+ベンチマーク実行時の読み書きの遅延 (平均 / 99.9%)
Nu
mb
er o
f qu
erie
s
Latency (ms)
Better read
avg. 6.16 ms
write
avg. 0.69 ms
書き込み遅延の平均が読み出し遅延の1/9
累積グラフ write
read
Latency (ms)
99.9 percentile
write: 2.0 ms read: 86.9 ms
0
5000
10000
15000
20000
25000
30000
35000
40000
Write Only Write Heavy Read Heavy Read Only
Max. QPS for 40 Clients Bigtable
MySQL
Redis
(qps)
Better
読み出し/書き込み/範囲検索 平均/99%/Max/遅延のばらつき データ総サイズとメモリ・ディスク 省データサイズ レコードサイズ (数KB~数十MB) HDD/SSD アクセス分布 (zipfian, uniform, latest)
他のストレージエンジン • Embedded InnoDB, KyotoCabinet
# 修論を書くプロセスの一環として(笑)
select
client • o.a.c.cli • o.a.c.avro/thrift
proxy • o.a.c.service.StorageProxy
server • o.a.c.service.StorageService
• o.a.c.db.ReadVerbHandler/RowMutationVerbHandler engine
• o.a.c.db.Table (keyspaceごと) o.a.c.db.commitlog o.a.c.db.ColumnFamilyStore (columnfamilyごと) o.a.c.db.engine.StorageEngineInterface ← 追加 o.a.c.db.engine.MySQLInstance, RedisInstance, MongoDBInstance, …
client proxy
server
engine
現在サポート • put (key, cf) 追加・更新・削除
• get (key) • getRangeSlice (startWith, engWith, maxResults) • truncate/dropTable/dropDB
今後 • secondaryIndex • expire • counter (Cassandra-0.8以降)
最低限、この2つを実装すればOK
Cassandraのデータモデル • 次元: keyspace – columnfamily – column • データはkey/value(オブジェクト)型 • データの格納方式 ColumnFamily単位でSSTableに<key, value>形式で格納 value: columnFamilyをオブジェクトシリアライズしたもの
key visits plan
sato 18 Gold
suzuki 214 Bronze
key gender age region
sato male 17 [null]
suzuki female 21 Tokyo
Bigtable (Cassandra)
col col ColumnFamily A ColumnFamily B
Keyspace
基本はCassandraのデータモデルをそのまま • Super Columnは今のところサポートしない
SSTableと同じkey-value形式で格納 • 任意ストレージエンジンに対して、多次元のスキーマレスモデルを対応づける
複数のテーブルを管理できないKVSの場合、 keyにprefixを付ける • 検索効率を考えると本来は避けたい
Cassandra MySQL Redis
keyspace database db
column family table record
column field
key visits plan
sato 18 Gold
suzuki 214 Bronze
key gender age region
sato male 17 [null]
suzuki female 21 Tokyo
Bigtable (Cassandra)
col col columnfamily A columnfamily B
keyspace
key values
sato gender;male;age;17
suzuki gender;female;age;21;region;Tokyo
table A table B key values
sato visits;18;plan;Gold
suzuki visits;214;plan;Bronze
RDB (MySQL)
key values
A:sato …
B:ito …
A:suzuki …
B:tanaka …
db
KVS (Redis)
database
データモデルの対応付けで異なる • MySQL database = keyspace :=> 行指向 MyCassandra (MySQL)はこちらを採用
• MySQL table = keyspace :=> やや列指向 Cassandra自体はこちらを想定
key visits plan
sato 18 Gold
suzuki 214 Bronze
key gender age region
sato male 17 [null]
suzuki female 21 Tokyo
Bigtable (Cassandra)
col col columnfamily A columnfamily B
gender age region visits plan
sato male 17 [null] 18 Gold
suzuki female 21 Tokyo 214 Bronze
keyspace
Table
MySQL
オブジェクトシリアライズは嫌っ!! スキーマレスでは無くなるが、 事前にスキーマを定義し、カラムを1対1で割り当て
単一で参照頻度が高いカラムや secondary indexで用いるカラムを別途用意
rowKey CF counter secondary index
token
主キー Serialized Object
特別な カラム
検索用 カラム
範囲検索用カラム
Key Value
シンプルなKey-Value型KVSの対応は考えていない…
非均一なクラスタ • 異なる種類のストレージエンジンを連携してクラスタを組む
• ストレージエンジンごとにレプリカを配置 • クエリの種類別に、それを効率良く処理できるストレージエンジンに処理を割り振る
W R
sync async
write query
Bigtable MySQL
W R
sync async
read query
Bigtable MySQL
異なる種類のストレージエンジンに複製を配置 クエリの種類に応じて、それを得意とするストレージエンジンに クエリを同期的に割り振る → 性能のいいとこ取り
既存クラウドストレージの整合性の強さを保つ Quorum Protocol: (書き込み合意数) + (読み出し合意数) > (複製数)
• 最新のデータを最低一つを取得できることを保証
読み書き両方を同期的に行うノードが必要 → メモリベースのストレージエンジンを使う
W R
W R
sync async
RW
write read
write query
• W: 書き込み性能重視 • R: 読み出し性能重視 • RW: メモリベース
1) データ担当ノードにリクエストをマルチキャスト
2) W, RWから成る合計 ノード
への書き込みを待ち、成功すればクライアントにACKを返す
3a) 成功時、残り ノードに
は非同期で書きこむ
3b) 失敗時、Rも含めた合計ノードからの書き込みを待ってから、クライアントにACKを返す
WR
Proxy
2ノードの書き込みACKを確認して成功とみなす
非同期書き込み
RW
Client =3, =2
W:RW:R = 1:1:1の場合
データ担当ノード
• : 書き込み性能重視 • R: 読み出し性能重視 • RW: メモリベース
書き込み遅延: max (W, RW)
1) データ担当ノードにリクエストを マルチキャスト
2) R, RWから成る合計 ノードから
データを取得し、整合性を確認 3a) 整合性がとれていれば結果を返す 3b) 失敗 or 不整合があれば、
Wも含めた整合性のとれた ノード
のデータを待ち、結果を返す 4) 残り ノードからのデータの取得. 不整合があれば、非同期で解決 (Cassandraのread repair機能)
Client
整合性をチェックして 結果を返す
非同期で整合性をチェック
Proxy
データ担当ノード
• : 書き込み性能重視 • R: 読み出し性能重視 • RW: メモリベース
=3, =2 W:RW:R = 1:1:1の場合
読み出し遅延: max (R, RW)
W R RW
0 2000 4000 6000 8000
10000 12000 14000 16000 18000 20000
Write-Only Write-Heavy Read-Heavy Read-Only
max. qps for 40 clients Cassandra MyCassandra Cluster
(query/sec)
Read Heavy Write Heavy
Better
1.54倍
6.49倍
0.93倍
0.90倍
[100:0] [50:50] [5:95] [0:100] [write:read]
• YCSB / Zipfian • 読み出し比率の高いワークロードで最大6.49倍のスループット • 書き込み比率が高くなるとスループットが出ない
https://github.com/sunsuk7tp/MyCassandra MyCassandra-0.2.0 (最新版)
• based on Cassandra-0.7.5 • Baseic CRUD on a simple record • RangeSlice • keyspace単位のエンジン選択
1. cassandra.yamlに設定を書く • 各engineのhost, port, … • default engine
2. ストレージエンジンの起動 (デーモンの場合)
3. MyCassandraの起動 (Cassandraと同じ)
4. スキーマのロード or 動的にkeyspace, columnfamilyを追加
• engineの種類を選択 (keyspaceごと) • スキーマ定義 (column familyごと)
Embedded InnoDB • HailDB: 並列に立ち上げると落ちる… • Handler Socket: バイナリをサポートしていない… • ExtraDB • APIとしては既に用意してあるので、本体の対応待ち
DBM (KyotoCabinet) • KyotoCassandra/Kyossandra/京ssandra (笑) • 構造がシンプルで、性能オーバヘッドが少ない • 他NoSQLよりもデータサイズがコンパクト • QDBM, TC同様にHash or B+Treeのdbクラスを選択可
class persistence algorithm lock unit
ProtoHashDB volatile hash whole (rwlock)
ProtoTreeDB red black tree whole (rwlock)
StashDB hash record (rwlock)
CacheDB hash record (mutex)
GrassDB B+ tree page (rwlock)
HashDB persistent hash record (rwlock)
TreeDB B+ tree page (rwlock)
DirDB undefined record (rwlock)
ForestDB B+ tree page (rwlock)
• キャッシュ/永続化 • hash/B+tree • ロックの粒度
MyCassandra-0.2.2 • secondaryIndex MySQLやMongoDBなど
MyCassandra-0.3.0 • Based on Cassandra-0.8 • Atomic counter • Brisk (Hadoop + Cassandra)…
1. 非同期削除 2. 部分故障の対応 3. アドホックな対応
Cassandraの削除/expire • tombstoneによる論理削除 • 実際の削除はSSTableのコンパクション時で • Bigtable likeな構造に依存
MyCassandraのBigtable以外 • 同期削除 • expireは機能するが、実際のデータは残ったまま • 非同期削除はコストが大きい 1つのTable全体を舐める必要がある
ストレージエンジンだけが死んだ時の 故障検知とインスタンスの挙動
複数のストレージエンジンをもつ場合、 一部のエンジンのみが故障したときの挙動
engine
instance
detect
どうする?
instanceを落とす? 他のエンジンが肩代わり? リモートエンジンに フェイルオーバー?
instance
engine
定期的な ping
instance
engine
node down
アドホックなクエリやデータモデルの対応 • 分散に依存しないものであれば、手軽に追加できるように Redisのデータ型 MongoDBのドキュメント指向モデルやリッチなクエリ などなど
• 分散の仕組み上、実現不可能なものサポートさせない 複数keyに跨るアトミックな処理 Join
機能別に分散に依存するか否かを区別する
アプリを書く上で必須な機能が無い • 分散のしくみ上、実現が難しい
ただ、リリースノートを眺めると • Cassandra-0.6以前: 主に性能周りの改善が多い
メモリ・GC効率改善 コンパクションの改善
• Cassandra-0.7, 0.8: 機能追加 セカンダリインデックス 動的なスキーマ変更 一貫性レベルの種類 分散カウンタ
基本的な読み書き性能への影響が気になる…
Issue報告 • https://github.com/sunsuk7tp/MyCassandra/issues
Twitter • @MyCassandraJP • @_MyCassandra # @MyCassandraは取られてたorz • @sunsuk7tp # 個人のアカウント
Google Groups • https://groups.google.com/group/my-cassandra
冨田 和孝 / @railute 様 • 本勉強会の運営やCassandraドキュメント
Gemini Mobile Technologies / @geminimobile 様 • 会場提供、Hibari
椎名 俊輔 / @yutuki_r 様 • Cassandraのブログ、twitter
dann / @techmemo 様 • Cassandraのブログ
河野 達也 / @tatsuya6502 様 • YCSBの翻訳, Hibari
平林 幹雄 / @mikio1978 / @fallabs 様 • KyotoCabinet
西澤 無我 / @muga_nishizawa 様 中田 敦 / @Nakata_itpro 様 首藤 一幸 / @shudo 様 Cassandraユーザー会の皆様 会場の皆様 USTの視聴者の皆様 (順不同)
長丁場、どうもありがとうございました!!