BPStudy#25 「パフォーマンスとスケーラビリティのためのデータベースアーキテクチャ」
BPStudy#25、データベースの話ということで、
最近(えせ)データベース屋になりつつあった私、小見、さっそく行って参りました。
2009年9月25日
BPStudy#25
パフォーマンスとスケーラビリティのためのデータベースアーキテクチャ
by サイボウズ・ラボ 奥一穂 氏 Kazuho@Cybozu Labs
http://atnd.org/events/1484
話は、
1. いくつかの資料で、前提となる知識を入れる
2. デモ
3. まとめの話
という流れでした。
下記は、その内容まとめ、
小さな文字は、自分の感想、もしくは注釈です。無い頭を使って、必死に解釈したよ。
Happy Optimization
良い最適化のやり方について。
プロファイラを使おう、最適化作業の投資効果を考えて作業しよう
「30%速くなったよ」は駄目で、「理論上の最速値の70%に到達」は良い。
事前に最適化の効果を予測して、投資を回収できるか、考えて最適化すべき。
Scaling
マシン、メモリ、CPU、ハードディスクなどは、時間と共に劇的に高性能化していっているが、
HDDのレイテンシ、インターネットのレイテンシは、10年で倍程度にしか、性能が良くなっていない。
HDDはサービスのボトルネックになりやすい。
そこで、HDDをSSDに変更すれば、読み込みが速くなるので、速くできる。(ただし、金銭的に高くつく)
HDDの他には、CPUに負荷がかかる処理も遅くなる原因になりやすい。
参考資料
「4Gbpsを超えるWebサービス構築術」
http://www.amazon.co.jp/4Gbps%E3%82%92%E8%B6%85%E3%81%88%E3%82%8BWeb%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E6%A7%8B%E7%AF%89%E8%A1%93-%E4%BC%8A%E5%8B%A2-%E5%B9%B8%E4%B8%80/dp/4797354364
代表的なスケールアウト技術
RDB Sharding データベースでの対応 MapReduce Hadoop 分散処理の手法 Key Value Store KeyValueStoreなデータベースを使う Message Queue メッセージキューの機能を使う
これら技術と組み合わせてよく使われる、アプリケーションの構成が3層構成。
HTTPサーバ → アプリケーションサーバ → ストレージ
私も、この構成を良く使いますが、
何故、3層構成にするのか、開発者やコンサルタントから質問されることが割とあります。
どう答えたら良い?
ただし、この3層構成には限界があって、
このままだといずれ、スケールアウトからケールアップの流れに戻るだろう、ということです。
台数増やしても性能が上げづらくなっていく、ということですが、何故でしょう?
通信のコストが相対的に高くなっていくから?
Incline & Pacific
パフォーマンスチューニングのトレンド
アプリケーション毎のパーティショニング
→ ユーザ単位のパーティショニング
→ 複数サーバのキーバリューストア
RDBのパーティショニング
ロジックで、割り当てるデータベースを変える方法
良い点
- 簡単。コストが安い。
悪い点
- 事前の分割設計が難しい。
- 運用開始後の変更が難しい。
簡単かなぁ。計画の手間が割とかかるような。
複数サーバのキーバリューストア
良い点
- 台数を増やせば、スケールアウトする。
悪い点
- 機能が少ない。レンジクエリ、トランザクションなどは利用できない。
- データの局所性がない。
- データのConsistencyが弱い。
CAP定理
Consistency、Availability、Patition-toleranceの3つを同時に満たすことはできない。
CAP定理は、分散とか、データベース関連の勉強会では良く聞きますね。
- Consistency = データの一貫性を保つこと
- Availability = いつでも利用できること
- Patition-tolerance = 分散できること
A Clever Way to Scale-out a Web Application
開発中の Incline と Packfic というコマンド群の説明。
RDB shardingの欠点
RDB shardingでは、非正規化作業が必須になる。
結果、データ更新時、いくつかのテーブルにデータを書きにいかねばならなくなる。
例. テーブル t1 user 1 - 2000 を格納。 テーブル t2 user 2001 - 4000 を格納。 テーブル t3 user 4001 - 6000 を格納。 例えば、格納先テーブルを分けた時に、複数のユーザ間に関連する更新データがあると、 いくつかのテーブルを同時に更新しにいかねばならなくなる。 (この例は、ユーザ単位のパーティショニング)
RDB Shardingでのデータの更新方法
- eventual consistency
- 2-phase commit
の2種類の方法がある。
eventual consistency = 更新データが届けば、データの整合性がとれた状態になる。届くまでは、分散されたノード間のデータの整合性は取れない。
2-phase commit = 2相コミット。全ての分散されたノードが合意したら、データを更新する。
RDB Shardingの欠点。
- 更新時に複雑なクエリが必要になる。
テーブルt1を更新して、テーブルt2を更新して、、、
- データの一貫性を保つのが難しい。
複数の関連するテーブルを確実に更新する必要がでてしまうから。
- ダイナミックにスケールできない。
事前に計画した通り以外のケースでは、
プログラムなどに対応が必要なことも多いからか。
Inclineとは
そこで、Incline。
基本的な考えはトリガーを使い、自動的に他のデータベースを更新させることにより、
複雑なクエリを発行する必要を無くす、というもの。
あるテーブルを更新時に、eventual consistencyで、他の関連データをトリガーから発行されるクエリで更新する。
Inclineは実際にはトリガーを作り出すコマンドで、MySQLではトリガーを1テーブルあたり1つしか作れないが、
いくつかの条件をマージした複雑なトリガーを作り出すことで、その問題を回避する。
Inclineは、魔法(悪夢)のようなトリガーを生成するツール。
確かに、こんなトリガー、手で組んではいられない。
設定ファイルに、どの範囲のデータを、どのテーブルに入れるかを記述することで、RDB Shardingができるそうな。
Pacific
Inclineと共に作っているらしい、Pacificの話。
Pacificは、スレーブを簡単にセットアップする、mysql_jumpstartコマンドから実行される、一連の処理の実装のこと。(だと思う。)
独自形式の設定ファイルを利用して、マスタ、スレーブ環境を作り出す。
デモ
Pacific と、Inclineのデモ
MySQLでマスタとか、スレーブとかの設定を行ったことがないので、どれくらい楽なのかはわからなかった。便利そうなのはよくわかる。
時間のできたときに試してみよう、と思う。
A Better Cached
Memcachedの利点
- スケールアウトするキャッシュ
- 読み込みの負荷を下げられる。
Memcachedの欠点
- データベースの一貫性維持が面倒
- 問い合わせが複雑になる。キャッシュとデータベース双方に問い合わせる必要がある。
RDBMSがスケールアウトしないからMemcachedの利点が出てくるが、RDBMSがスケールアウトすればキャッシュいらないよね、
Pacific & Inclineを使えばOKだよ、という話。
感想
とても面白いお話でした。
データベース、インフラ周りは、もっと勉強したいですねぇ。
他にもやりたいことがたくさんあって、時間がいくらあってもまるで足りません。