「データベース技術実践入門」とタイトルにはありますが、この本は入門ではなく「おぼえがき」のようなものだと読んで感じました。データベースの設計を行う際の注意点や、こういう点は押さえておくべきということを広く確認できる構成になっていたからです。
例えば、インデックスの種類を挙げ、データ数が増えてきた際にどのようにインデックスが効いてくるか、逆に効かなくなってくるかをまとめてあったり、データベースが吐き出すログにはどのようなものがあり、障害時の復旧手順のなかでどのログがどのような役割をになっていたりするかをまとめてあったりします。
また、最近のストレージ動向にも目を向け、データベースのパフォーマンスを上げるためにはどうすればよいかを解説していたりもします。
本書はつまるところ、「データベースを自分で構築し、(大規模なデータを扱う)サービスと絡めて運用する人向け」の本だと思います。「Webエンジニアのための」と書いてありますが、全てのエンジニアではなく、昨今話題のスマートフォン向けソーシャルゲームや、大量ログを扱わなければならないようなサービスを運営する中小規模の開発会社の開発者向けです。
DBの設計や、エンタープライズシステム向けのデータベースを扱う際に読むような本ではないですが、サラッと読んで知識を蓄える感じで読むのにステキなまとめられかたをしていると思います。
ちなみに、本書で扱っているデータベースは MySQL になります。
おぼえがき
片方向/非同期レプリケーション
片方向レプリケーションは、「マスタ」に更新した結果が「スレーブ」に「非同期」で伝搬するというタイプのレプリケーションである。マスタで実行した更新系 SQL 文がバイナリログというログファイルに記録され、このログファイルの中身がスレーブ側で順次実行される。
スレーブでは「バイナリログの受信」と「バイナリログの実行」の2段階で行われる。「バイナリログの受信」は I/O スレッド、「バイナリログの実行」は SQL スレッドが実行する。
このレプリケーションでは、バイナリログの受信よりも、バイナリログの実行の部分で遅延が発生しやすくなる。これは、ネットワークよりもディスクがボトルネックになることが多いからである。
障害の状況パターン
- マスタで生成したバイナリログがスレーブで最後まで受信出来ていない
- スレーブでバイナリログの実行が最後まで行われていない
の場合はマスタを復旧させ、最新のバイナリログをスレーブに更新しなければ、最新のバイナリログ分のデータロスになる。
の場合は、スレーブがマスタの代わりに処理を継続する(マスター昇格)することで障害対応が可能だが、バイナリログを最後まで実行し終わったことを確認してから処理しなければ、データ不整合が発生することになる。
片方向/準同期レプリケーション
「バイナリログの受信」を同期処理するようにしたもの。障害パターンの1. の状況が限りなく発生しなくなるメリットがある。デメリットとしては、マスタ→スレーブの通信を同期するため、スレーブからのレスポンス分スループットが悪くなる。
片方向/同期レプリケーション
「バイナリログの実行」までを同期処理するようにしたもの。MySQL では実装されていない。
双方向レプリケーション
双方向レプリケーションは、マスタを複数用意しそれぞれのマスタを更新できるようにするもの。マルチコア CPU や、SSD などのハードウェアの性能をより引き出すことができる。
ただし、それぞれのマスタに対して同時に更新を行った際の分散排他制御の仕組みが不可欠で、DBMS によって実装方法はまちまち。
障害からの復旧方法
トランザクション対応のデータベースの多くは、REDO ログという更新対象列の変更情報を記録したファイルを使って一貫性を保っている。
MySQL は更新されたデータをすぐにディスクに書き込むのではなく、キャッシュ領域に保持しており定期的にディスクに書き込むという処理を行なっている。そのため、データベースがクラッシュするとキャッシュ領域がクリアされ、ディスクに書かれたデータが古い状態ということが起きる。
そこで、クラッシュから回復するときには、最初に REDO ログからディスクの状態を最新の状態に戻す(進める)必要がある。
MySQL のレプリケーションはシングルスレッド
MySQL のレプリケーションはシングルスレッドで行われる。そのため、マスタが並列で大量に処理をさばいたとしても、レプリケーション処理が詰まってしまうということが大規模サービスでは起きてしまう。
遅延の主な要因はディスク I/O が低速なことであるため、スレーブには SATA SSD などの高速なディスクを使うことでこの問題を解決するのが現実的。
最近では、PCI-Express インターフェースをもつ FusionIO社の ioDrive や Virident社のFlashmax などが使われている。
運用の勘所
CPU 使用率で監視すべき点が3つある。
- ディスクI/O(%iowait)
- システム空間での使用率(%system)
- ユーザ空間での使用率(%user)
- ディスクI/O(%iowait)
ディスクI/Oがボトルネックになっている場合、この値が跳ね上がる。
- システム空間での使用率(%system)
OS 内の処理で使用されている CPU 率。スワップが発生したり、ネットワーク周りでトラブルがおきている場合この値が跳ね上がることがある。
- ユーザ空間での使用率(%user)
CPU を使うような処理が多いことを表す。DB サーバではあまり大きな値になることはないが、大きくなった場合はテーブルスキャンを連発しているなどの問題があることが多い。
リストアとリカバリ
リストア(バックアップの結果を戻す)だけでは、障害直前の状態に復旧することはできない。バックアップ以降にも処理が行われており、その更新結果はバイナリログに記録されている。
リストアしたあとに、バイナリログの中身を順番に当てていくことで、障害直前の状態に戻すことができる。
NoSQL
「SQL文のような複雑な言語を使わずにプログラミング言語のライブラリ関数を使って直接データアクセスするほうが高速になるのではないか?」このような背景から生まれたのが NoSQL。
NoSQL では、テーブル/ファイルを開っぱなしにして処理性能を高めるようにしている。
一般的な NoSQL では、トランザクションをサポートしていない。また、スキーマレスなため主に XML や JSON を格納して扱う。インデックスは主キー以外使えないと思ったほうがよい。