InnoDBのすゝめ(仮)を読んで或いはAppendix(前半)

注意

この記事の内容は完全に一部のエンジニアむけ、それもかなりニッチで高度な話題を取り上げます。エンジニア以外の人が読んでも意味が分からないだろうし、理解に必要な労力に対し、得られるものは多くはありません。

 

はじめに

www.slideshare.netz

私の尊敬するエンジニアである瀬島さんが力作スライドを公開されました。

 

前述の資料はDBAである瀬島さんの目線で書かれており、また内容としても比較的MySQLへの理解がある人向けであるため、アプリケーションエンジニアである私の目線から特に重要な点について解説・考察を補足いたします。

そもそものはなし

よほど激しい更新や、よほど大きいデータ量を扱わない限り、MySQLはデフォルトの設定で、常識の範囲内のコストで動作します。特にAWSなどのパブリッククラウドではかなり柔軟にリソースを確保することができます。MySQLは怖くない。

 

ではこの資料は何の役に立つのかという話ですが

  • よほど激しい更新やよほど大きいデータ量を扱う
  • とても非効率的な使い方をしてしまった
  • 予算に大きな制限がある

このようなエッジケースに直面した場合に助けになります。そのようなエッジケースにどのようなシナリオがあり得るかというと

  • 計画よりもサービスの成長が異常に速い
  • アプリケーションで使用しているORMのクエリの効率が悪い
  • 最初にサービス規模を大きく見積もっていたが実際は厳しく、コストカットが求められる

例えばこんな感じです。

ゲームの DB とゲーム以外の DB は、 考え方を変えて良い

ここで理解すべきことは、目的に合わせて合理的選択をすることでかかるコストが抑えられるということです。合理的選択を行うためには目標の設定とともにMySQLへの理解が必要です。つまるところMySQLのことをよくわかっているとコストを下げられる!

sharding のメリット

ここでは暗黙的にinnodb_file_per_tableが有効であるという前提で話がされています。この設定値はMySQL5.6あたりでデフォルト有効になったので、最近のMySQLを使っている場合、勝手に有効になっているでしょう。この設定について詳しい情報が知りたい場合、

MySQL :: MySQL 5.6 リファレンスマニュアル :: 14.5.2 InnoDB File-Per-Table モード

を参考にしてください。

 

テーブルのデータサイズは大きくなりすぎると運用上いくつかのデメリットがあります(具体的な例は資料を参照)。これはテーブルを分割する(sharding)ことである程度回避できます。ただし、これはクエリの自由度を下げることにもつながるので、シャーディングのキーを工夫することでその影響を最低限にとどめるとよいでしょう。

 

資料にないデメリットとしては、テーブルの数が多くなるので結果的にファイルシステム上に配置されるibdファイルの数が増えます。どの程度shardingを行うかにもよりますが、innodb_open_filesの設定値を実態に合うようにしましょう。

 

どうでもいい話ですが、私はalter tableに最大で3日かかったことがあります。

MySQL の機能を活かして、 Transaction はほどほどに考える

ここはぐっと高度な話になります。頑張ってついていくか、読み飛ばすかしましょう。

 

多くのSQLドライバーでは更新系クエリの返り値から、更新されたレコード数を得ることができます。改めてselect count(*)~whereで取得するよりも低コストかつ確実に数を数えることができるので、活用しましょう。

 

初回だけinsertして以降updateの場合~というのは、insertしようとして失敗、その後updateという動作が非効率的になるからです。insertするべき確率よりもupdateするべき確率が圧倒的に高い場合、いきなりupdateからのほうが効率的です。

MySQL 以外の データストアやキャッシュと、 うまく組み合わせる

これは最初の段落の発展形です。MySQLInnoDB)は非常に堅牢なデータストアですが、アプリケーションのすべての場面で同一の堅牢性が要求されるわけではありません。MySQLの特性を理解し、不得意なもの(超高頻度更新・超リアルタイムなど)はそれにあったデータストアを組み合わせることでコストが下げられます。

 

資料に挙げられていないものでいえば、アプリケーションそのもののメモリの中にキャッシュとして保持するのもよい方法です。また、いくつかの方法を組み合わせてキャッシュを多段にすることもままあります。

アプリケーションエンジニアとしてはどのデータがどこに、どの程度の寿命でキャッシュされているかを把握することが重要です。

 

また、メモリ内キャッシュ(memcachedやローカルメモリ)はリスタートでデータが吹き飛ぶ可能性があり、その際にDBの負荷が急激に上がる場合があります。アプリケーションのつくり次第では連鎖的な障害を発生させる場合もあるので、そこも考慮したうえでDBの性能を見積もりましょう。

 

長くなったので残りは後半に回します。

年収が100万円下がる事象について

我々は以前より特定の業界、特定の企業によらず複数の事象を観測しており、この事象について「虎舞竜」と呼んでおります。


虎舞竜と名前が付けられた経緯について、私の知る限り以下のように伝え聞いております。


あるところに某(仮名)という社員がいた。

某は毎年の評価のたびに年収が変わらないことを嘆いていた。

そんな某であるが、ある年の評価面談で、唐突に年収が100万円下がることを告げられた。


某は大いに嘆いた。

これまでは年収が変わらないことを嘆いていたが、今を思えば変わらないことが、何でもないようなことが幸せだったのだ。某はもう二度と戻れない日々を思い、ため息をつくことしかできなかった。


この話を聞いた人々は、名曲「ロード」になぞらえて、年収が急激に低下することを「虎舞竜」と呼ぶようになった。


以上、よろしくお願いいたします。