今回の勉強会では、『データ指向アプリケーションデザイン』の監役者である斉藤太郎氏にデータ指向アプリケーションデザインの内容を約30分でご説明していただいた後、田籠聡氏にも加わっていただき、データ指向アプリケーションデザインについての理解を深めるトークセッションを行います。
当日の発表内容はこちらからご覧ください。
基調講演「30分でわかるデータ指向アプリケーションデザイン」
斉藤 太郎氏
Treasure Data社 Principal Software Engineer
東京大学理学部情報科学科卒。情報理工学 Ph.D。データベース、大規模ゲノムデータ処理の研究に従事した。その後、Treasure Data社に加わり、アメリカ、シリコンバレーを拠点に活動している。現在では、OSSを中心にプログラミングやデータ処理を簡単にするためのプロダクトを作成している。日本データベース学会上林奨励賞受賞。
Twitterのアカウントはこちら
はじめに、データ指向アプリケーションデザインの概要をご説明いただきました。
データ指向とは「データの量、複雑さ、変化の速度」を中心に考えるデザイン

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「「データ指向」とは、この本のためだけに生み出された新しい訳語です。
intensiveの従来の訳語は、例えばCPU、Memory-intensive、メモリ集中、特化型というような言い方をしていましたが、データ集中やデータ特化型という言葉もしっくりきませんでした。そこで、オブジェクト中心にプログラムを設計するという意味の「オブジェクト指向(objected-oriented)」をデータ指向のほうでも使おうと考えました。
そして「データ指向」とは、データの量、複雑さ、変化の速度を中心に考えるデザインを表します。」
まず、「データの量、複雑さ、変化の速度」に対応できるシステム設計とはどういうものなのかご説明いただきました。
データの作り方(データ量が少ない場合)

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「まず、データがそもそもないとアプリケーション作成は始められないので、データをどうやって作るかを見ていきたいと思います。
データ量が少ない場合、データの表現のしやすさや生成しやすさが重視されます。そのためテキストデータフォーマットだと、CSV、JSON、XMLなどが手軽でテキストエディタでも記述できるのでよく使われます。
ただ、テキストである性質上、正確なデータ型をコンパクトに表現したい場合に若干困ります。
そこで、バイナリーデータフォーマットを使うときもあります。例えば、MessagePack、Thrift、ProtocolBuffers、Apache Avroなどがあります。これらのフォーマットの特徴は、データとして完結している自己記述型(self-describing)フォーマットであることです。若干例外として、Protocol Buffersはデータ自体にスキーマを含まないので、かなり節約指向です。」
データの作り方(データ量が多い場合)

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「データ量が多くなる場合、データ基盤では省メモリ、圧縮しやすさ、ストレージへの格納しやすさが重視されます。
そのためにどうやってコンパクトにデータを表現するかというと、例えばテーブル型のデータの場合には、スキーマ(各カラム名、型)とレコード表現を分離することでデータを節約してコンパクトに表現しています。
RDBMSでよく使われる行指向(row-oriented)フォーマットは横に取った1行ずつがデータとして表現されているため、レコード単位で更新しやすいフォーマットです。
一方、列指向(column-oriented)フォーマットが最近デファクトスタンダードになってきています。今度は、縦方向の列ごとにデータを分解して保存するフォーマットです。
なぜ縦方向に分解するかというと、同じ型のデータを集めておくとgzipなどが非常にコンパクトに圧縮できるのです。また、同じ型のデータがキャッシュに乗りやすいし、SIMD演算にも活用しやすいので分析クエリに非常に特化したフォーマットです。
一方、1つのフォーマットを複数のブロックで表現するので、更新するのがどんどん大変になっていきます。」
列指向データフォーマットの中でもオープンフォーマットのApache Parquetについてご説明いただきました。

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「Apache ParquetはGoogle DremelというVLDB2010年で出版されたアイデアがベースになっています。ネストして繰り返しのあるデータでも、同じパスにあるデータを取り出して縦方向に圧縮します。
そのデータをクラウド上のストレージで扱いやすくするために、例えばページブロックに分けたり、フッターにページへのインデックスを格納したりといった工夫がなされています。」
データがどれだけ変化するかを考える

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「Columnar Formatのようにあまり変化しない不変データの場合、ログデータをどんどんcolumnarにして保存していき、ストレージサイズを節約したり分析クエリを速くしたりします。このようなデータへの高速なアクセスや分析の速さが問われるものを読み込み特化型(read-intensive)といいます。
分析クエリを速くしたい場合の常套手段としては、「データを分散する」というものがあり、データを分散させる方法はいくつか挙げられます。
例えばパーティショニング(シャーディングともいう)という方法があります。これは、データを時間範囲やキーの範囲で分割して別の領域に保存することで、本当に必要な部分だけにアクセスしたり別領域のデータへの並列アクセスを可能にしたりします。
また、データ自体のコピーを複数のマシンに配備して複数台のノードで別々の箇所のディスクを読めるようにして高速化するレプリケーションという方法もあります。
もう一歩進んだやり方としては、クエリ結果を保存しておいて、再利用できるようにしてread-intensiveのアプリに対応する実体化ビュー(Materialized View)という方法もあります。
書き込みが多い場合はどうしたら良いか

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「書き込みがたくさんある場合は、RDBMSが歴史的に非常に強い分野で、レコード単位の更新だったり、トランザクション処理をしたりする場合に、こういったデザインが効用されます。
ただ書き込みに特化すると言っても、書き込みだけが速ければいいわけではないです。 書き込みしたいとか編集したいデータがどこにあるかを素早く見つける必要があるので、同時に検索も早くしなければいけないところが難しいところです。
そのためのインデックス構造がデータ指向アプリケーションデザインでいくつか紹介されていて、例えばB-Tree、Hash index、SSTable(Sorted String Table)といったものなどがあります。」
インデックス構造のうち、B-Treeについて詳しくご説明いただきました。

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「B-Treeは非常に優秀な構造でして、 ディスク上のページに次のページへのルックアップテーブル(LUT)を格納します。
RDBMSはCREATE INDEX命令を実行すると、B-Treeが1個作られるというイメージです。 そのため、検索を速くしたいからと言ってCREATE INDEXをたくさん実行してしまうと、その度に複数のB-treeインデックスを更新しないといけないので注意が必要です。
基本的には、B-Treeは上手に使うと高い更新性能を発揮します。 空き領域にどんどんデータを挿入できますし、ページ数が増えても木の高さがあまり高くならないので、ディスクへのランダムアクセス回数を減らすのに役立ちます。
例えば各ノードに100個のエントリーが含まれている場合、1億個のレコードをB-Treeに放り込んだとしても、木の高さは4個の深さにしかなりません。ナイーブにやると、1億回データをスキャンしないといけないところを、B-Treeインデックスを利用すると、4回ディスクをルックアップすれば1億件のエントリーから目的のデータを見つけられるという意味で、非常に優秀なデータ構造です。」
さらに書き込みを強くしたい場合にはLog-Structured Merge Tree

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「B-Treeインデックスをさらに書き込みに強くしたデータ構造として、Log-Structured Merge(LSM) Treeが最近よく使われています。
この図では何をしているかというと、レコードを追加(インサート)する操作と、裏側でレコードをきれいに整形してマージする操作(コンパクション)を分離しています。
まずはメモリにどんどんデータを放り込んで、メモリ上でデータを並び替えます。 バックグラウンドでソート済みのデータを(先頭から順番に大小比較してマージするようなアルゴリズムで)マージソートし、次のレイヤーに保存していきます。
そうすると、ランダムアクセスをメモリ上で吸収するので、バックグラウンドのストレージにデータを書き出す際は、シークエシャルアクセスで書き出していけるので非常に優秀な構造となっています。
例えば、SSDの中身にも似たような構造が使われています。 SSDにはバッテリー付きのキャッシュメモリーが入っていることが多く、そこでランダムアクセスを吸収してからシーケンシャルアクセスに変換し、セルの寿命を延ばす工夫もされています。
ただ、LSM Treeは面白いのですが、読み込み時に各レイヤーにアクセスしないといけないので、その分のオーバーヘッドがあります。 書き込み時にも、LSM Treeインデックスはデータをどんどん次のレイヤーに書き出していくので、書き込みの増幅(Write Amplification)という、同じデータの書き込みが何回も生じてしまいます。そのため意外とディスクのライトが多くなることがあります。
例えば、levelDBやFacebookが作っているRocksDB(C++)、AWS S3(Rustで実装)などでLSM Treeが使われています。」
データが複数のノードにまたがる時の難しさ

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「基本的に、データが分散することで問題の複雑さが数段上がってしまいます。
そもそもノード間でデータを分散して配置するときには、データのやり取りをしなければならず、そのために分散システムを作らなければいけません。各ノードが同じ状態になる(membership)ように、たくさんのサーバー間の状態を整える必要があります。
そのために、サーバー・クライアント間でのデータ通信のための、RESTプロトコルやRPC(Remote Procedure Call)を使う必要があります。
さらに、複数ノードで頻繁に更新がある場合は、同期(コンカレンシーコントロール)と呼ばれる、ロックの取得、タイムアウト、トランザクション、ログのリプレイなどを考えないといけません。
また、どの状態が正解かを決めるために、合意(コンセンサス)のプロトコルが必要です。基本的には多数決(quorum)で決め、そのためのアルゴリズムとしてPaxoや2PC(two Phase Commit)などが考えられます。そもそもロックのような重い処理をさけるためにCoordination avoidanceなども使われてきています。
単純にデータを通信するだけでは済まず、障害対応も大事です。例えば、エラーが起こった時にどうするか、リクエストをリトライする時にどうするか、冪等性(べきとうせい、idempotency)という同じ操作を2回実行しても大丈夫なようにシステムを設計するとか、障害からどうやって復旧するかなどがあります。
さらに、ノードが間違ったデータを返してしまう状態(ビザンチン障害)でもシステムが正しく動くように考えないといけないのが難しいところです。」
24時間365日動き続けるサービスの設計

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「24時間365日動き続けるサービスの設計するときに主要となる数字として稼働率(availability)があります。許容されるダウンタイムが99.9%だと8.7時間/年、99.99%だと53分/年、99.999%だと5分/年 しか止めてはいけないということになります。
アプリケーションを1年同じ状態のまま動かし続けるのは不可能で、更新しなければいけません。アプリケーションをデプロイする時は、マシンのプログラムを一度止めて、次のバージョンのアップグレートをしなければいけないので、リクエストが一度止まります。クラッシュしたり、通信が遮断されたりすることがあるので、クライアント側ではリトライ(再実行)処理を実装しなければいけません。
サーバーがアップグレード中にリクエストが失敗しても、クライアントがリトライすることで、次のバージョンでちゃんとリクエスト処理される状態にしておきたいのです。
難しいのは、クライアントがレスポンスを送ってサーバーでは正しく処理されたが、ネットワーク障害などにより、レスポンスがクライアントに届かない場合です。 クライアントがリトライすると、サーバーでは同じデータが2個登録されてしまいます。
このようなことが起こらないようにシステムを設計することを冪等性を保った設計という言い方をします。具体的には、リクエストにユニークなID(UUID)をつけることがあります。
エンジニア面接で冪等性について質問すると、そのエンジニアにどれくらい経験があるのかわかる良い指標になります。」
常にアプリケーションをデプロイし続けられる設計についてご説明していただきました。

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「常にデプロイし続けられるように、Compute(クエリの実行)とStorageを分離するのが近年の標準的な設計になってきています。
こうすることで、クエリエンジンとストレージを別々にスケールさせたり、ノードを一個ずつ(ローリング)アップグレードしたりすることも可能になっています。例えば、SnowflakeやAmazon RedshiftはComputeとStorageを完全に分離したデザインで、SIGMODの論文に詳しいです。
Redshiftは、Redshiftネイティブのストレージだけでなく、S3にあるデータもクエリできるようデザインされており、ComputeをGPUにして超並列クエリを実行することもできるのが面白いところです。」
トランザクション処理とは?

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「トランザクション処理はデータを頻繁に更新する時に必要となり、データベースの花形技術です。
ACID(エイシッド)というキーワードを聞いたことがある人も多いと思われます。1983年頃に研究者が作ったキーワードで、Atomicity Consistency Isolation Durabilityの頭文字をとっています。
ACID の定義は色々ありますが、単にACIDと使われる場合はほぼマーケティング用語と思ったほうが良いです。
例えば、何がどう保護されるのかは、consistencyがなにかとか、isolationになにをやっているのか、詳細を見ないと全くわかりません。 むしろ、トランザクション分野に詳しくなればなるほど、分からなくなっていくようなものです。
このあたりを詳しく知りたければ、以下を読めばわかります。
TRANSACTIONAL INFORMATION SYSTEMS
Detabase Management Systems
“Database Management Systems” : Ramakrishnan, Raghu, Gehrke, Johannes: Foreign Language Books
データ指向アプリケーションデザインでも、重要な概念は一通りさらってあります。
例えば、アイソレーション(isolation、分離)のいちばん重要な考え方は直列化可能性(serializability)です。
直列化可能性はトランザクションが一つずつ実行されたのと変わらない状態を維持することであり、 この性質を持たせるのがトランザクションの基本です。 オーバーヘッドがかかるので、実際に使うかどうかはよく考えなければいけません。
そこで、弱い分離性というのが提案されてきており、Read-CommittedやSnapshot-Isolation、MVCC(Multi-version concurrency control)というものがあります。
さらに、分離性を妥協しないアプローチとして、スナップショットをとって性能を速くするが、Serializable Snapshot Isolation(SSI)というテクニックもあります。SSIはPostgreSQLなどで実装されて、皆さんが使うこともできます。
ここで考えなければいけないのは、どういうトランザクション異常(anomaly)が起きるかということです。例えばファントム(まだ存在しないレコードに、どうロックをかけるか)やWrite skew(同じスナップショットを読んで、違う場所に書き込む)などが挙げられます。
紛らわしい用語として、Repeatable Readは、名前からは繰り返しデータを読めそうなトランザクションを想像してしまいますが、実はそんなことはありません。この名前が出てきたら使うのはやめた方がいい、といったような説明が本書に記載されています。」
複数ノード間でのトランザクション実装

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「シングルノードでトランザクションを実装していた世界から、複数ノードでトランザクションを実装する世界へ広げていくと、いろいろな難しさが出てきます。
複数のノード・システム間でトランザクションを実装するには一貫性、合意、耐障害性などを考える必要があり、その時に重要な考え方が 線形化可能性(linearizability)というものです。
線形化可能性とは、データのコピー(レプリカ)が複数あっても、ユーザーにとっては一つしか無いように見せる。更新操作が終了した途端、全ノードが同じデータを見られるように保証することです。
これを実装するには、リーダー選出やサービスディスカバリ、メンバーシップ管理などいろいろな技術が必要となります。これらが正しく実現できないと、シングル・リーダーレプリケーションなども正しく実装できなくなってしまいます。こういった技術は、Zookeeperやetcd(Kubernetes内部で利用)などでも実装されています。
最近のアプローチとして、日本から出てきたScalarDBでは、アプリケーション側のクライアントで分散トランザクション処理を吸収し、どんなデータベースでも分散トランザクションを実装できるということをしています。
Amazon Auroraについて

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「この辺の技術を本書で学ぶと、SIGMOND 2018で発表されたAmazon Auroraの技術がいかに洗練され、シンプルになっているかわかって面白いです。
Amazon Auroraはいわゆる分散版のMySQLで、レプリカを6個作成し、3つのAvailability Zone(A)に分散配置しています。そのため一つAvailability Zoneが落ちても、多数決できる(quorumを取れる)設計になっています。
MySQLのデータベースの更新操作をログの書き込みだけに特化して簡単にしています。分散された各ノードでログをリプレーして、データベースの状態を同じに保っています。
データのコピーには、Gossipプロトコルを採用していて、送信先ノードをランダムに選び、データをコピーしてだんだん同じ状態に持っていきます。
トランザクション処理も同期を取らない coordination avoidanceというテクニックを使っていて、2相コミット(2PC)を使わなくても実行できるような非常に洗煉されたデザインをとっているところが面白いです。」
ここまでは、データベースシステムについてお話しいただきましたが、ここからはデータ自体から生まれる複雑さについてご説明いただきました。

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「従来ではデータベースのテーブルというと、「RDMBSにある最新のデータ(snapshot)」のことしか意味していなかったのですが、現代では「時間とともに変化するデータ」「そこから派生するデータ(derived data)」を表すようになってきています。
列指向クエリエンジンの発展により、大量の派生データが出てくるようになってきました。 バッチ処理とストリーム処理の区別がつかなくなくなるほど、いろんなデータが作られるようになっていて、『Streaming Systems』を読むと、色んなパターンが紹介されています。」
導出データ(Derived Data)について

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「上図はTreasure Data社の一つの事例です。
1つのデータから数千の導出データが生成されており、クエリで生成されるデータの依存関係、データの履歴の管理が必要となります。
そのため、最近だと、dbt(クエリの依存関係を記述するSQLコンパイラ)新しいTable FormatのDelta LakeやApache Iceberg、 Apache Hudi などが、テーブルの更新履歴やスナップショットを管理するため開発されました。」

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「データ処理では色々なオペレーターを組み合わせないといけないのですが、これは Unixコマンドのデータ処理に非常に近いです。
UNIX哲学というものがあり、端的な機能を持つコマンドをたくさん用意し、個々のコマンドをパイプでつないでデータ処理します。 実はシェルの裏側ではコマンドごとにプロセスが起動し、プロセス間でストリーム処理をしています。 UNIXでコマンドを叩くと、実際に分散データ処理が実行されています。」
UNIXのパイプのようなものを複数ノードで実行するには?

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「複数ノードで実行するにはどうしたら良いかというアイデアの原典はSparkで、Spark(2009)もMicrosoftが開発したDryadLINQ(2008)に影響を受けています。
DryadLINQはgrep を単純に実行するのではなく、grepを1000台のノードで実行するとか、sed
を500台で実行するとか、同じコマンドを分散並列実行させるような仕組みであり、 これをベースにSparkが作られたという歴史的な順番があります。
さらに、よりプリミティブな形として、Google が2004年に発表した MapReduce があります。MapReduceでは、Mapperが keyとvalueのペアを出力して、Reducerで同じkeyに属するvalueを集めて集計結果を出力します。こうすることで、ユーザーはMapperとReducerを書くだけで、フレームワーク側が自動で分散処理してくれることになります。
MapReduceは他にもSQL(Hive)、MapSide Join、Broadcast/Hash Joinなど色々なテクニックが誕生している。」
ストリーム処理とは?

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「ストリーム処理は、SQLのようなものをデータの入力側に送り、常にクエリーを実行し続けます。あるいは、データの変更を捉えて、細かい単位のバッチで処理したり(マイクロバッチ)、差分データ(CDC;Change Data Capture)を使って、変更部分に対して処理したりします。
この辺の概念を上手にまとめたのが、Dataflow ModelというGoogle が VLDB 2015で発表したエポックメイキングなpaperです。
時系列データ・ストリーム処理の分類・パターンを詳しく定義していて、遅れてやってくるデータ(late arrival)の処理を埋め合わせないといけないことを示しています。基本的には、データがとられた時間(event time)とデータがシステムに見えた時間(processing time)を二次元のwatermarkで管理して処理する仕組みです。
これはApache Beamなどに実装されています。
データモデルやクエリ言語の変遷をその歴史からご説明いただきました。

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「データモデルは歴史から学ぶところが多いです。データモデルは多様で、1970年頃から議論が続いており、詳しい歴史はRedbookに書かれている。
例えば、昔はネットワークモデル(CODASYL)や階層モデルなどがあったが、勝者はリレーショナルモデル(RDBMS)でした。JSON・XMLなど様々なデータ形式がRDBMSに取り込まれていき、RDBMSの一人勝ちになっていきました。 結局、品質が重要で、トランザクションができないデータベースはユーザーには使えないため、しっかりとトランザクションをサポートしているRDBMSが強くなっていきました。
アプリケーションが使いたい表現(構造データ、オブジェクトなど)とデータベースに格納されている形態がマッチしない状況をインピーダンスミスマッチ(Impedance mismatch)という。
RDBを使わないといけない不満から、NoSQLというバズワードが出てきたが、このアプローチは良くありませんでした。NoSQLは「SQLにNo」という意味で始まったが、次第に「Not Only SQL」というSQL以外もやりたいよねという解釈に変わっていきました。
このような歴史の教訓から学んだ良い事例はGraphQLです。 GraphQLはRDBMS/SQLとむやみに喧嘩しません。そのため、SQLを利用しても、アプリケーションがほしい形でデータを取得するサポートを実装しており、非常に好感がもてます。」
SQLの使われ方の推移

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「SQLの使われ方も段々変わってきている。今まではRDBMS専用のインターフェースだったが、例えばGoogle F1(VLDB2018)は、Google社内の多様なストレージへSQLでアクセスできます。そのための共通SQLコンパイラはオープンソースのZetaSQLで作っており、BigQueryの実装にも使われています。
さらに、Meta(Facebook)も共通SQLエンジンを作って、その裏側でSparkやPrestoのデータ処理を統合するVelox処理エンジンをC++で書いています。
Trino Distributed SQL Engineも面白いデザインで、ストレージ実装はなに持たず、データソースへのコネクタを提供して分散SQL(処理部分)だけをオープンソース化しています。
分散データシステムの世界

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「この地図において、個々の島はデータ指向アプリケーションデザインの各章に対応しています。」
データ指向がわかると1章の重要性がわかる

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「データ指向アプリケーションデザインの1章を見てみると、信頼性・スケーラビリティ・メンテナンス性と書かれていて、データ指向の意味が分かってくるとこれらの重要さがわかってきます。」
Twitterの実装例

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「初期のTwitterでは、ツイートをグローバルなコレクション(DB)に格納し、ユーザーがタイムラインを取得するたびに、DBから検索するという非常に読み込み負荷が高い実装になっていました。
そこで、ツイート時にフォロワーのタイムラインキャッシュに対してツイートを送る方式に変えると、書き込みの負荷は増えたが、読み込み負荷が2桁減りました。」
Elon Musk氏のインプレッションが低い問題を例にとって、データ指向アプリケーション的な考察についてお話していただきました。

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「イーロン・マスクのインプレッションがフォロワー数に対して少ないという事例がありました。イーロン・マスクによると、ファンアウトサービスがクラッシュしていて、95%のツイートが配信されていなかったそうです。
これはデータ指向アプリケーション的にとても面白い事例です。信頼性の面では、「一部サービスがクラッシュしていても、サービスは落ちていないのはなぜか」、メンテナンス性の面では、「数千人規模のエンジニアのレイオフをしても、引き継ぎがちゃんとできているのか」、スケーラビリティの面では「数億回の読み書きする実装はどうなっているのか」「性能調整はどうなっているのか」といった考察ができます。
システムのパフォーマンス(SLO)をどう測るか

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「性能を測る時に大事なのがSLOという概念です。システムの平均値を見るだけでは重要な部分が見えないので、例えば 95、99パーセンタイルの値のレイテンシーを見る必要があります。AmazonのSLOでは p99.9のレスポンスタイムを一定値以下に抑えるようしています。
100ms遅くなると、売上が1%下がると言われており、Amazonのように売上が莫大な場合、1%でも640億円という大きな額となる。ただ、p99.99 まで改善しようとするとコストに見合わないと判断し、p99.9としています。
まとめ

https://www.youtube.com/watch?v=ZiKWXc0fSCw より
斉藤 太郎氏:「データ指向アプリケーションという本は、分散データシステムに入門するための決定版の教科書といっても差し支えないです。
いろいろな教科書を読んできたなかで、この分野の教科書は2007-2017の10年間、全く存在していませんでした。 本書は660ページと分厚いのですが、おのおのの分野の教科書はもっと分厚いです。
そのため、上図の本を読む前に、まず「データ指向アプリケーションデザイン」を読み、ざっとまとめを知っておくと良いと思います。

斉藤 太郎氏:「著者のMartin Kleppmann さんは本書を完成させるにあたって大変な努力をされ、執筆に2014年から4年もかけました。 第2版も検討しているが、全く目処が立っていないようです。 第2版が出るのはだいぶ先ではないかと思っています。
この本をガイドにして、より深い世界に踏み込むためのテキストとして使ってほしいと思います。
本書は各章ごとに50-100本の論文が引用されています。論文を一個一個読むのは大変なので、まず基礎知識を抑えてから、次に出版される10年後に備え、論文から情報収集できるようにしておくとよいと思います。
特に今はクラウドの時代なので、データ基盤関連のインダストリアルデータが沢山出てきている。ACM SIGMOD・VLDB・usenix・ICDEなど、データの話が常にあるような状態です。 これらの論文を読めるようになると面白いなと思います。
また、Audible(英語版)もあるので、聞き流すと非常に楽に本書を読むことができます。
トークセッション
パネリスト
田籠 聡氏
フリーランス・技術顧問
東京大学工学部計数工学科卒。NTTやLINE、Treasure Dataなどでの勤務を経て、現在は個人事業主としてデータ処理基盤技術およびITエンジニアリング全般に関するコンサルティング等を行う。近著に「Fluentd実践入門」(技術評論社)。
Twitterアカウントはこちら / Github:@tagomoris
モデレーター
小林寛和
慶應義塾大学卒業。その後、株式会社リブセンスにてデータエンジニアとして同社分析基盤立ち上げをリードする。2017年にprimeNumberへ参画し、2018年10月にデータ分析基盤の総合支援サービス「trocco®」を立ち上げる。以降、同プロダクトの全般の統括・運営を担っている。
1.本書籍を更に深く学ぶ方法
斉藤 太郎氏:「エンジニア的な観点から言うと、データベースを作ってみると、いろんなことが腑に落ちてくると思います。データベースを真面目に作る人はいないと思うのですが、最近は、簡単に作れるデータベースがたくさん出てきています。
例えば、DuckDBはあえて分散しないデータベースを実装しています。そうすると、分散は無視して、本当にデータのアクセス部分とか、クエリー部分だけ気にすればいいし、トランザクションもさほどありません。
そういうものを作ってみようとすると、B-Tree、カラムナ・ストレージなどを実装するうえで、本書のほとんどの知識が必要になってきます。
コード書くのが好きな人とか、データベースが好きな人は、こういう作る学び方はありだと思います。」
田籠 聡氏:「データベースを作ってみようというのは、なかなかハードコアな路線だと思います。
本書には、技術的な一般論、典型的な手法を積み上げているので、書いてあることをすべてやれば良いソフトウェアになるわけではなく、その中でも、取捨選択やどういったデータベースの分離レベルを使うかなどの判断が必要です。
製品ごとにどういう選択を用意していて、デフォルトがどういう設定になっているか。 そういった細部に実際の使い勝手や性能特性など大事なものが宿っていることが多い気がします。
例えばRDSMS一つとっても、MySQLを中心に使っている人は、別のデータベース(PostgreSQL)やBig QueryやAthenaのような分析系エンジンを使ってみると、「何が違うのか」「何を大事にしているのか」「性能的な特性がどう違うのか」といったことがよくわかってくると思います。
それらの違いがわかった上で、どういう技術によって裏から支えられているのかを知ると、理解が一段と深まるのではないかと考えています。」
斉藤 太郎氏:「「実装してみる」「既存の製品を使って学ぶ」という二つのアプローチをするために必要な、分離レベル、B-Tree、データ構造、レプリケーション、障害耐性といったキーワードがこの本にたくさんあります。
600ページの内容を頭にいれるのは無理なので、その辺の基礎知識をキーワードだけでも、この本を眺めて拾っておいて、使ってみて、気になった時にこの本に立ち戻るといいと思います。
僕は研究者で論文を読むのが仕事のようなところがあったので、この本が出る前にいろんな技術をすでに知っていたので、本書は論文に書かれていることが上手にまとめてあるなと思いました。」
田籠 聡氏:「僕もこの本が出る前から、仕事していたので、守備範囲ではありました。論文を読んだものもあるし、いろんなOSSやサービス(Big Query、Aurora)が出てくる時に、内部実装を論文だけにしか書かないわけではなく、ブログや記事などの何らかの形で紹介します。そういうものを読むと、キーワードがあちこち書かれているので、どう実装されているのか、何となく分かると思います。
キーワードをどれだけ深堀りするかは人によるが、いろんな製品紹介記事を機会があるたびに読むと、共通しているキーワードを発見したりしていく中で、自分の中で技術的な蓄積ができていくのではないかなと思います。」
斉藤 太郎氏:「僕の学び方としては、Treasure Dataに入る前は24時間動き続けるサービスを作ることなんて無かったので、 リトライとか冪等性はTreasure Dataで経験で学ぶしか無かったのですが、本書にはそのあたりが書いてあります。
サービスを作る側に身を置くと、本書のありがたみ、有効性がよくわかると思います。」
田籠 聡氏:「作る、手を動かす経験は、どのレベルになっても必要になります。
ある程度動かして、本書やほかの本などに戻ってくるとわかってくるものがあり、そこからさらに一段高度なレベルで手を動かしてまた戻ってくる、という繰り返しになるのではないかなと思います。」
小林 寛和:「Twitterで質問が来ています。」
「データベースを作る」ぐらいの事がそんなハードコアな物扱いされてしまうのが悲しいよね。コード行数や難度としては言語自作や自作OSと大差ない労力でARIES+Selingerぐらいの奴はできるのに
斉藤 太郎氏:「確かにデータベースを作るのは、段々簡単にはなってきていて、 SQLの実装だけなら、山のようにあります。
トランザクションの実装もログをシップするだけの簡単なものなら、ARIES を使うと、分散DBもかんたんに実装できるのではないかと思います。
今はgRPCのおかげで、RPCも簡単になってきているので、分散システムの通信だけなら実装できます。 SQLコンパイラも実装は山のようにあります。
データベースの実装は簡単になってきていますが、まずは簡単になっていることを知らないといけないです。」
田籠 聡氏:「だいたいどういうものが必要なのか頭の中にある人は全体像があるので、いざやってみようとなったときにそれほど高い山に見えないと思います。
全体像がわからないと、自分にみえている範囲の外にどのくらいあるのか分からないし、 全体像の輪郭がわかっても、各々のサイズが感覚的にわからないと、恐怖というか、高いハードルに感じてしまうというケースは多いと思います。
データベースを作ろうと思うとわからないコンポーネントが結構あるので、そのうちの一つだけを作ってみるというのがいいのではないかなと思います。CSVをクエリできるSQLエンジンのように、簡単なところから一つ一つ進んでいくのがお勧めのアプローチです。」
小林 寛和:「本書を読み、データベースの全体像を理解した後でデータベースを作るといいよという斉藤さんの意見に対して、全体像を理解してもまだまだハードルが高いだろうから、SQLをパースするなど、一部を作るところから始めるといいというのが、田篭さんの意見だったと思います。
データエンジニアリングの話に特化すると、クラウドDWHは各技術をブラックボックス化してくれていて、いい意味でも、悪い意味でも、簡単に扱えてしまうと思います。
お二人は、技術を深める方向にフォーカスしたのか、技術を応用する方向にフォーカスしたのか、どちらだったのでしょうか?」
斉藤 太郎氏:「データベースの技術に興味を持ち、作ってみたいという動機からキャリアが始まっているので、実用性はあまり考えていませんでした。
B-Tree実装を参考にするためにPostgreSQLのコードを読むのは結構大変です。 KVSをB-Treeで実装し、ロックもあるBerkeley DBのコードなら読めて、ドキュメントもしっかりしたので、そこから学ぶことが多かったです。
教科書にはロックを取るとか、シリアライザブルの実装方法は書いてあるけど、データのページレイアウトはどうするか、ディスクにどう読み書きするかといった細かいところはOSSのコードを読まないとわかりませんでした。
作ってみたいから始まり、ソースコードをどんどん読むと面白くなっていったという感じです。」
田籠 聡氏:「僕の場合は、全く逆でした。
就職して業務システムを作る時に必要に迫られてRDBMSを使い始め、色々なデータベースを使い、仕事の都合で 何百GBあるデータを分析するためにHadoopを使い始めました。
当時はBigQueryのようなサービスがなかったので、あるものは組み合わせて使うし、足りないものは自分で作るしかなかったため、作る世界に一歩ずつ足を踏み入れていきました。そういう意味では、出発点が斉藤さんとは全然違います。
本書よりさらに学びたい時、大量データ分析の基盤を自分で作れるかというと、手元にデータが有るか次第なので、手元に処理する必要のある大量のデータがある・ないで感覚が全く違うと思います。 そういった意味ではどういう人が大規模データを自前で生成するのは難しいと考えています。」
斉藤 太郎氏:「データベースの研究者をしばらくやった後、ゲノムサイエンスに移りました。ゲノムサイエンスは人のDNAを読んで、一人から数TBのデータが出てきて、これを何千人分処理する大規模データ処理の現場になっています。
データを処理しないと何もサイエンスが進まないというところに放り込まれたので、DryadLINQやUNIXコマンドで超並列処理するアプローチで大量にデータを処理して統計処理をしました。ゲノム配列の検索用のインデックス(FM-index:suffix arrayがベース)を作ったりもしました。
現場に飛び込んで、プログラミングの腕も上がったし、データ処理の知識も上がりました。データベースの研究をしているだけだと、実際にデータを使う現場の気持ちがわからなかったが、 生物学でデータ処理をやり、このあたりが絡み合っていると実感できました。データが有る場所に飛び込むのはすごく大事です。」
小林 寛和:「田籠さんも斉藤さんも全然違うところから山を登りつつ、データベースを自分で作ったり、もう少し実装の抽象度が高いOSSを活用したりするものもあるのかなと思いました。」
②本書籍からの技術進歩に関するアップデートについて
斉藤 太郎氏:「Parquet、Amazon Aurora、Iceberg、時系列データの変更履歴など書籍でも扱われていたものが、実装レベルで出てきたのが新しいです。
「12章:データシステムの将来」を見ると、データの変更履歴をトラッキングすることの重要性が書かれているのですが、 本書を読んで実装する流れになったのだと思います。」
田籠 聡氏:「この本の出版時は、各パブリッククラウドのデータベースやオンライントランザクション、分析トランザクションがほとんど出ていなかったのですが、この7-8年でぜんぜん違う世界になってきています。OLTPでいえばAmazon AuroraやGoogle Spannerで、OLAPだとAthenaやBigQueryがあります。
いろんなサービスが出てきましたが、実装の裏側がわからず、数年遅れでpaperから知るという世界になってきています。実装が先行して、後からpaperに出てくるので、各クラウドサービスベンダーの出してくる情報に注目しないといけないと思います。」
斉藤 太郎氏:「詳細はクラウドベンダーの中の人しかしらない状況になってきている。 実装の経験が表に出てきていない。」
田籠 聡氏:「理論をもとに実際に実装したとき、実用で求められる一工夫が表に出てきていないと感じています。」
斉藤 太郎氏:「本書には、Riak(Basho)やRethinkDBなど、会社自体がなくなったデータベースが紹介されています。
OSSとして公開するだけだと、ビジネスとしては続けられません。実際にデータを持って、サービスを運用している会社でないと、製品を改善していけない。 技術の先に、トラフィックから得られる経験をもとに、サービスを改善するフィードバックループまでたどり着かないと、こういったデータ基盤系システムの開発は続けられないんだろうなというのが、この5年間の経験で見えてきています。
RiakのBashoは作った製品を売るだけの立場だった。 データを実際に集めているAmazonやAzureに比べると、経験値のたまり方が遅かったのかなと思います。」
田籠 聡氏:「一方、当時からあっても本書であまり取り上げられていないものとして、ドキュメントDBがあります。 MongoDBやGoogle Cloud Firestoreはビジネスとしてはとてもうまくいっています。
利用シェアとしては、ドキュメントDBはだいぶ大きくなっているので、それらのデータベースの技術は調べる価値があるかもしれません。
本書では「Dynamoスタイル」という用語が何度か出てくるが、誤解している人が多いです。 「DynamoスタイルDB」と「Amazon DynamoDB」は全然異なるデータベースです。当時の文脈で理解できる言葉があるので気を付けてほしいです。」
斉藤 太郎氏:「本が出る少し前に、CAP定理がすごく流行り、分散システムを利用するにはCAPを理解しないとだめだというような風潮がありました。
この本では、CAP定理は意味がないから忘れるよう、書かれています。CAP定理が流行っていたときは関連論文がたくさん出版されていましたが、それらは読まなくて良いと、知識をちゃんと整理してくれています。
今後、Dynamoとかのアップデートが必要なので、誰かが整理しないといけないと思います。」
小林 寛和:「この本の出版後に出てきたトレンド技術で、お二人が一番着目しているものは?」
斉藤 太郎氏:「Snowflakeはクラウド(S3)の技術をふんだんに使ったデータベースです。トレジャーデータにもほぼ似たようなデータベースがあります。
データレイクという話になってくると、むしろ技術的には過去に逆行しているような気がします。トランザクションの更新はあまり頻繁でなく、アップデートが1分間に数回しかないようなデータ基盤向けですが、 1秒間に100万回トランザクションが必要なものだと、このようなデータレイクは動かないです。
必ずしも最先端を突き進んでいるわけではなく、現代的なS3を使って、古い技術を実装しているようなところがあると思います。」
田籠 聡氏:「タイムシリーズデータベースは本書で扱われていないが、最近はよく使われています。
AWSにもあるし、モニタリング関連のDatadogを始めとして、単独のサービスとして出てきていて、時系列データをどう扱うかというのがポイントになってきています。
これからデータが減ることはないし、時間の経過に従ってデータが蓄積するものを扱うなら、時系列データベースに近いものが必要です。 Treasure DataのPlasmaDBもtime-partition orientedなデータベースだったので、そういったデータベースがどうでてくるかを楽しみに見ています。」
小林 寛和:「要素要素の技術を見ると、エッジがきいていて面白いなと思うものがあるが、使われているユースケース・ニーズがないと普及しない。技術的な振り戻しが起きている。読み込み特化だと、トランザクションは重要ではない。時系列分析のニーズが伸びていて、AWSも出している点、などを理解しました。」
斉藤 太郎氏:「最近出てくるOSSのデータベース関連のサービスは、エンジニアリングやメンテナンス性も意識し、あえて簡単なデザインにして、長期的にメンテできるような方向性のデータベースも出てきています。DatabricksのPhotonはそのような例です。
GoogleのF1もコア部分はC++で書かれているが、SQLのオプティマイザーはPythonで書けるようになっており、いろいろなエンジニアが扱えるようにしています。」
③本書籍の応用について
小林 寛和:「データエンジニアリング、データ分析基盤に特化した事例として、お二人の実業務における、本書籍の応用・事例失敗談のようなものはあるでしょうか?」
斉藤 太郎氏:「データ基盤を使うという観点からすると、データのパイプラインをいかに動かし続けるのかという観点が大事になります。
データを一回だけ書くexact onceという観点だとか、そのために、データをクリンナップしてから書いて冪等に書くという観点も大事になってきています。
データパイプラインにおいて、システムがクラッシュしたり、間違ったSQLコードをデプロイし解析結果が壊れた時に、 ロールバックして計算し直すといったことを考えないといけない時代になってきていると感じています。」
田籠 聡氏:「自社向けのデータ分析基盤を作ろうと思った時に、 データパイプラインをどうやって作るかを考えると、元のデータは必ずしもデータ分析用にどこかから湧いてくるわけではないので、「本番のデータベースからどのようにデータを分析用に引っ張ってくるか」「アプリケーション・サーバーのデータをどうやって集めてくるか」といったことを考える時に、一貫性のあるデータを集めるのが難しいです。
複数箇所からデータを持ってきた時に時系列がずれていると、突き合わせてもまともなデータとならないと思います。
そういう時に、タイムスタンプを決めてスナップショットをとったり、整合性のある形でCDCをとってきたりすることになると思います。
データをつくるという要素技術だったスナップショットやCDCが、データベースの中だけの話ではなく、データ分析基盤を作る時の要素技術として、必要になるケースがよくあると思います。
そういう意味では、本書の内容を前のめりになって使おうとしなくても、それぞれの要素技術が必要になっていると思います。 一度立ち止まり、「これってあの本に書いてあったあの事なんじゃないかな」と振り返り、頭の中でより明確に形作れば、現実の仕事に応用していけるのではないかなと思います。」
斉藤 太郎氏:「データを毎日処理し続けないといけないので、全部のデータをBigQueryなど一つのシステムで処理するのはコストがかかりすぎます。
そういったときに、インクリメンタルに必要なデータだけを処理できるように考えないといけません。CDC・トランザクションなどは必須の技術になってきている。」
小林 寛和:「Twitter上で気になる意見があったのでピックアップさせていただきます。」
発生元を探して、データクレンジングして、余計な重複が内容に蓄積して、導出・結合して価値のある分析結果につなげるのは結構ドメインの知識だったりする。
斉藤 太郎氏:「データエンジニアも普通のエンジニアがやっているようなCI/CDが必要になってきていると思います。
データベースのクエリに対してテストを書くのはまだ習慣化されておらず、知見がたまっていません。
SQLを追加・書き換えるたびにテストを流し、パイプラインがうまくいくか検証し、うまくテストが動いたら本番パイプラインにデプロイし、結果を確認する。うまく行かなければ、どこまでロールバックするか、どこから再計算すればよいか、そういったコントロールができるようになると面白いと思います。
普通プログラムのコンパイルは、インクリメンタルで処理されています。 データパイプラインでも、同じようなことをしないといけないが、まだ技術がそこまで揃っていないので、今後変わってくると思います。」
④本書籍を特に読むべき人・タイミングなど
斉藤 太郎氏:「エンジニア・データエンジニアだけでなく、データシステムのマネージャーも読んでみると良いと思います。
キーワードを効率よく抑えられるし、何百本もの論文を読み、OSSコードで学んだことが、この本一冊にまとまっているので、データベースやデータ基盤に興味を持ったら、まずはこの本をパラパラめくり、キーワードを抑えておくと良いです。興味を持ったら、論文を読む基礎体力を鍛えると良いと思います。
最近は、データ基盤系のインダストリー寄りの論文が増えており、少しでもBigQueryとかAWSのシステムを使っている人なら、馴染みのあるキーワードが増えています。」
田籠 聡氏:「この分野が気になっているなら、今すぐ読み始めるといいと思います。
一方で、660ページと分厚いですし、この分野の技術的なバックグラウンドがないと、ハードな内容の話が続くので、読んでいると疲れるケースが多いと思います。
個人的なお勧めとしては、話としては全部トピックがつながっていて、省略できる話があまりないので、先頭から順番に読んでいくといいと思います。
技術的な細部を全部飲み込まないと読み進められないわけではないので、ちょっと難しいと思ったら、その節はざっと目を通すくらいでも、全体像を頭に入れるという意味では十分です。 適度に無理しない範囲で読めるところを読んでいけば良いと思います。
実際に手を動かしていると、この本に戻ってくるタイミングは常にあるので、キーワードだけ頭に入れておいて、読み進め、必要になったら、本書に戻ってくるという流れが良いと思います。」
小林 寛和:「勉強会で途中で挫折した組なのでよく分かります。
最初からまず読んでみて、難しいところにぶち当たっても、とりあえず読み進めてみることが大事で、 インデックスを張るような読み方をして、必要になったタイミングで、詳しく読み込むというのが良いと理解しました。」
斉藤 太郎氏:「Audibleでよむのが一番楽でした。
合計で20時間ほどありますが、この本の監訳に使った時間はその比ではないです。 Audibleは止まらないので、わからないところがあっても、20時間で必ず聞き終わるのが良い点だと思います。」
過去のData Engineering Studyのアーカイブ動画
Data Engineering Studyは月に1回程度のペースで、データエンジニア・データアナリストを中心としたデータに関わるすべての人に向けた勉強会を実施しております。
当日ライブ配信では、リアルタイムでいただいた質疑応答をしながらワイワイ楽しんでデータについて学んでおります。
過去のアーカイブもYoutube上にございますので、ぜひご覧ください。