高トラフィックを想定したデータ層の話
初めまして!六本木で働くITエンジニアです
この記事は、Speee Advent Calendarの16日目です。
※遅れてすみません!!!!
初エントリーの記事としては高トラフィックのデータベース設計についてというお題だけど中身としては「データの鮮度」について語っていこうと思う
※テーブル設計とかそういうのは今回はでないので期待はずれの方はそっ閉じしてください
データの鮮度とは?
あまり聞きなれない表現かもしれないですが、BI業界なんかでは調査・分析するデータについて「精度」と「鮮度」という言葉で表現されることがあります。
- 精度:調査として適切な整合性がとれたデータになっているか?
- 鮮度:いつのデータか?いつ使うデータか?
私はWebアプリケーションのアーキテクチャとしてModel層を設計するに当たって、
構成するデータの鮮度を基準としてミドルウェアを選定しています。
生で食べたいなら刺身だし保存するなら干物に加工して食べますよね!
Webアプリケーションのデータも同じ感覚なんですけど、いつ使うか?や更新・参照頻度、データサイズなどによって加工(ミドルウェアの違い)を行うことが重要です
様々なデータ
このはてブ自体を構成するページもいろんなデータがあると思います。
- 記事のデータ
- テンプレート
- ユーザデータ
- アクセスログ
などなど多様なデータで構成されてますよね
これらをRDBで一括管理するならアプリケーション構築もインフラの運用や学習コストも楽でしょう。しかし、そのままではトラフィックが増えたりデータサイズが増えることで様々な問題が起きることは周知の事実ですよね。
では初めからある程度のアーキテクチャ設計が必要だよね!?ってのが私の思想です
それだと初期開発の工数ガーって話は後ほど
調理法を見極める
まずは各データの性質を見ていく必要がある
※前提となる性質は個人的な仮説でありはてブの仕様ではないです
ブログ記事
- 基本的には更新がほぼなく参照されるばかり
- サイトを構成する上で一番大事なデータ
- 記事はどんどん増えていく
テンプレート
- 更新はほぼなく参照ばかり
- データ量は1アカウントに1個のデータ
ユーザデータ
- 外部要因(お気に入りなど)による更新が多くデータとの連携が必要
アクセスログ
- 大量のアクセス数によるデータの蓄積と集計が必要
- ページ上には更新タイムラグがあっても問題がない
調理法の選択
細かいデータベース層のミドルウェアの説明は省きます
RDB(MySQL, Oracle, PostgreSQLなど)
トランザクションがあるのでデータの整合性はばっちりですよね。
各テーブルのJOINなど多様なデータの取得方法が可能でありSQLはやっぱり強力です。
しかしスケーラビリティの向上には工夫が必要でレプリケーションやパーティショニングを駆使する必要が出てきて結局アプリに手を加えるケースが出てきやすい
例:ユーザに関するデータ、記事のステータスとか
KVS、NoSQL(redis, MongoDB, Cassandraなど)
RDB以外ということで強引にまとめましたw
CAP定理をどれだけ満たしているか、データの検索方法によって各ミドルウェアで違うのでそれによって選択すべきだと思います。
例:記事のデータはMongoDB、PVのカウントはredis
MongoDBはレプリカセットによって可用性や耐障害性を向上しやすくクライアントによって参照先の制御ができるため、参照するデータが一意であり重要なデータの場合はベターな選択だと思います。また、ドキュメント指向なので記事の修正などによるデータの変更も柔軟に行える特徴にもマッチしている。
redisは多彩なデータセット(ソート済みやハッシュ)と一貫性のある処理をオンメモリで高速に行うことが特徴としてあげられるのでPVのカウントなどに適しているかと
簡単な例ではありましたが各ミドルウェアの特性とデータの特性を合わせることでミドルウェアを最大限のパフォーマンスを引き出せると考えています。
別にトラフィックやデータ数が少ないならRDB一本で問題ないですw
データ層で詰まらせない
データ層が詰まってしまったらいくらWebサーバをオートスケールしても意味がありません。またデータ層がオートスケールするにはアプリケーション側の工夫が必要なケースが多いため、改修工数が多くなることがあると思います。
弊社のサービスには立ち上げてから2年かからず大きくトラフィックを伸ばしたサービスがありますがデータ層で詰まったことは1度もありませんでした。
※Webサーバで詰まったことは何度か・・・
その為、開発に集中できサービス成長が早かったのかなと
データ層の設計次第で数年間のサービス開発のあり方が変わると経験上で覚えているので初期設計、実装のコストはトータルでは安いと思う
下記は実際に弊社サービスのモニタリング結果です
ね、DB系のサーバの負荷低いでしょ?
※諸事情によりサービス名などは公開できません。
データの持たせ方一つでインフラのコストも開発のコストも大きく変わると思います。
アプリケーションの作りやすさや学習コストとトレードオフになるところもありますが
サービスが成長することを、初めから意識することがビジネスにもエンジニアの技術力にも向上のきっかけになるのではないでしょうか。
サービスが失敗するかもしれないから「とりあえず」の仕様なんかで作りたくないし妥協なんかしたくないです。
それでは!