オライリー社にて2019年に出版の『Database Internals』のChapter1を読んだ際の読書メモです。
Database Internals: A Deep Dive into How Distributed Data Systems Work
- 作者:Petrov, Alex
- 発売日: 2019/10/15
- メディア: ペーパーバック
Chapter1. Introcution and Overview
第1章で話すこと
- DBMS Architectureの話
- メモリvsディスクベースDBの話
- 行志向vs列志向DBの話
- バッファリング、不変データ、オーダリングなどのパフォーマンス最適化技術の話
DBMS Architecture
- 以下のコンポーネント図に従い、各コンポーネントの説明がなされていく
- Storage Engine の責務とそれ以外の部分の責務は頭の中で整理して明快にしておきたい
- 「トランザクションとロックの責務はconcurrency controlである」的な話をしていて適格な要約だと思った。詳細は第5章で語られるとのこと。k8sでもお馴染みの楽観的ロックや、MVCCなんかの話題が出てくる模様。ここは平行システムをやるときの必須科目なので理解したい。セマフォとかクリティカルセクションとかも出てくるんだろうか
Memory Versus Disk-Based DBMS
- DBレコードがon memoryの場合、プログラミング言語から変数として(serializeせずに)操作したり、ポインタを使ったアクセスできて便利とのこと。そうするとRedisの場合は内部的にHashMapを持って終わりなのかなと想像した。文献探して答えあわせしたい。
- ディスクアクセスのコストを最適化したい場合はB-treeが最適とのことだけど、これは例えばHashMapだと挿入や削除の計算量が多大になってしまうということだろうか。
Column Versus Row-oriented DBMS
Row-Oriented Data Layout / Column-Oriented Data Layout
- 行志向と列志向の差はDisk上に実データを書き込むときに、「行」という単位でデータを同じセクタにできるだけ集中させて、局所性(locality) を持たせるのか、あるいは「列」という単位で同じことを行うのか?という違いから説明できるという話だと理解した
- あと、行は水平的(horizontal)な概念で、列は垂直的(vertical)な概念というのは直感的に理解しやすいのでいい形容だと思う
行志向DBの例として、MonetDB, Vertica などがあげられているがどれも初めて聞く名前
distinctions and optimizations
行志向と列志向の特性の差は、データのstore方法以外の観点でも語ることができる、とのこと。観点の具体例として、
- キャッシュの話
- ディスク領域資源の利用効率性
- アクセスパターンが行なのか列なのかで最適なプロダクトが変わってくる話
など
Wide Column Stores
Cloud Bigtable@GCP や Apache Cassandra などのように、カラムファミリをもつデータベースは Wide columns store といって、普通の行志向データベースとは明確に別のものとして分類されるとのこと
参考文献内にあった、2006年に書かれたBigtableの論文が面白そうだった。時間を見つけて読みたい
Data Files and Index Files
この辺りからRDBMSの実装の話題が増えてきて楽しくなる
「モダンなDB Storageの大半はDELETE命令に対し、データをストレージ上から完全に削除するということはしない、代わりに単に deletion marker を置く」という話を聞いてApache Cassandraの Tombstone を思い出したり。deletion and garvage collector model は頻出パターンっぽいなぁ。 k8sにもGarvage Collectorは存在する。改修されるのは、メモリではなくリソースオブジェクトだが。
RDBMSの話に戻ると要点は
- data fileとindex fileは通常別々に管理される
- fileはblock deviceサイズを持つpageに分割される? ← page が具体的にどのようなものなのか要確認
Bufering, Immutability, and Ordering
Buffering
LinuxにおけるディスクI/Oは通常ブロック単位で行われるため、WRITEするときに一度バッファメモリに書き込み命令をバッファリングし、1ブロック分まとめてディスクへの書き込みを実行すると、ディスクI/Oに要する時間が?最小化できる
という話。目的は異なるが、MySQLのダブルライトバッファ[1] を連想した。他にはB-treeと2コンポーネントLSM treeではバッファリングの考え方がだいぶ違うという話とか
Mutability (or immutability)
- Immutable の定義については、Javaとかで言われる Immutable Object の考え方とほぼ同様な話?
- レコードをimmutable objectとして実装したい場合、 LSM tree みたいにアペンドオンリー方式で実装するやり方と、 copy-on-write で実現するやり方があるとのこと
Odering
キーと同じ並びでディスク上にデータをシーケンシャルに格納していくか否か
という話題- 後者(シーケンシャルではなくばらばらのDisk上の領域にデータを格納する)がWRITE処理が早いこともあるとのこと。具体例としては、アペンドオンリーな方式の場合が例示されていた
[1] こちらの資料のP23がわかりやすいです https://www.slideshare.net/IIJ_PR/iomemoryatomic-write