金利0無利息キャッシング – キャッシングできます

2009-03-03

FriendFeedの事例についてのメモ

13:31 | FriendFeedの事例についてのメモ - 金利0無利息キャッシング – キャッシングできます を含むブックマーク はてなブックマーク - FriendFeedの事例についてのメモ - 金利0無利息キャッシング – キャッシングできます

http://hyuki.com/yukiwiki/wiki.cgi?HowFriendFeedUsesMySqlToStoreSchemaLessData

  • 項目が不定の雑多なデータを格納するのに、YAMLJSONでダンプした文字列で保存することは、割と良くある手法だと思う。
  • 目新しい(?)のは、カラムが不定なデータを検索可能にするために、非同期でインデックスを生成することだろう。

これと似たようなことをやるとして、MySQLじゃなくてハッシュデータベース使う前提で、簡潔に説明するとこういうことになるだろう。MySQLハッシュデータベースとして使ってもよい。

  • データはJSONでダンプして圧縮して、UUIDをキーにしてkey-value-storageに保存する。
  • PrimaryKey=AUTO_INCREMENTなテーブルを作って、最近追加されたキーを管理しておく。タイムスタンプも付けておくといいだろう。
  • 非同期でインデックスを作成する
  • クエリMySQLで処理して、UUIDを取得し、データをkey-value-storageから読み込む。
  • インデックスは最新の状態を反映してないかも知れない。データを読み込んだ後でクライアント側で整合性を検査する。

メリット

  • インデックスの追加、削除でテーブルがロックされない。任意のタイミングで行える。
  • インデックスの作成を後回しにするため、DBへの書き込みが高速化する。
  • 場合によっては、過去一週間分の検索が出来れば十分かも知れない。一週間分だけのインデックスを作成できる。
  • etc, etc

インデックスの整合性に関する問題

  • データ追加直後はインデックスが使えない
    • 追加した直後は、UUIDでのアクセスしかできない。
  • インデックスが最新ではないために、20件引いたのに19件しか返ってこない、というようなことがあり得る。
    • 本来のlimitよりも多く取得する or 目的の数になるまでページングを繰り返す。
    • あるいは、フロントのUIが「いい加減さを許容するように」設計されていれば、問題ないのではないか。
    • 例えばAutopagerizeのようなものがあれば、何件表示されているかは問題にならない。
  • ユニーク制約に関する問題

既存のシステムからの移行プラン

(自分の関わっているプロダクトで実際にこういう事をやりかけている)

  • 書き込みのタイミングでkey-value-storageにも並列して保存しておく。
  • MySQLのデータストレージとしての性能には期待しないで、インデックスだけを使用するクエリ(Covering Index)をメインで使う
  • まずはキャッシュとして利用して、徐々にMySQL側のデータ実体を削除しても問題ないようにする。
  • 書き込み順序は MySQLkey-value-storage
  • 全てのレコードkey-value-storageに格納してしまう。
  • テーブル構成を変更、インデックスで使用するcolumn以外を削除してしまう。
  • データ実体を追い出してしまえば、MySQLにより多くのレコードを格納することが出来る。
  • MySQLインデックスのみ使用する状態になった。性能に問題がなければこの状態で構わないだろう。
  • MySQLへの書き込みを非同期化する。書き込み順序は key-value-storage → MySQLに変更される。

雑感

  • 書き込まれたデータがすぐに読み出されるとは限らない。インデックスの更新は非同期で良い。
  • クローラを作るとそう言うことが良くある。
  • データベースを更新するのはユーザーではなく、バックグラウンドで動くクローラープロセス
    • だから、データの更新がすぐに反映されなくても良い。インデックスが更新されたタイミングで、初めてユーザーに反映されれば良い。
  • ユーザーからのリクエストによるデータの更新は、多くの場合で、すぐに反映される必要がある。
    • 通常通り、インデックスの作成を同期的に行う必要があるだろう。
    • UI上の工夫で何とかなりそうなことも多いと思う。書き込みが成功したかどうかなんて、その場で分からなくても良い。
  • 正確さのために無駄なロックが発生したり、インデックスを肥大化させて、速度を犠牲にしてしまう。(よくあるパターンだと思う)
    • 細かいことを気にしなければコンピューターの性能はもっと引き出せるはず。