View on GitHub

Today I Learned

Software Engineering Blog

Designing Data-Intensive Applications - Part 1. Foundations of Data Systems

第1部: データ指向アプリケーションの基本的な概念

Chapter 1. Reliable, Scalable and Maintainable Applications

信頼性(Reliabile)

スケーラビリティ(Scalable)

メンテナンス性(Maintainable)

用語

Chapter 2. Data Models and Query Languages

アプリケーション開発者側の観点でデータを扱う方法

Data model

データモデル 特徴
リレーショナルデータベース データの結合、多対一や多対多のサポート
ドキュメントデータベース ドキュメント間の関係がそれほどないユースケースで使われる
グラフデータベース データの関係の多くが多対多の場合に使われる

すべてのデータが入れ子になった階層モデルは多対多の扱いの課題があり、これに対応するためにリレーショナルデータベースが作られた

ドキュメントデータベースの特徴

Query language

宣言的クエリ言語

用語

Chapter 3. Storage and Retrieval

データベース側の観点でデータを扱う方法

Storage engine

データベースから特定のキーを効率的に見つけるためにはインデックスが必要

インデックスはreadのクエリを高速してくれるが、データ書き込みのたびにインデックスを更新するため書き込みを低速にする

LSM tree (Log-Structured Merge-Tree)

B tree

OLTP vs OLAP

OLTP(Online transaction processing): オンライントランザクション処理

OLAP(Online analytic processing): オンライン分析処理

ユーザ –> OLTPシステム –> OLAPシステム <– ビジネスアナリスト

特性比較

  Read Write データの内容 データサイズ
OLTP 少数のレコードをキー毎にフェッチ ランダムアクセス、低レイテンシ 最新のログ GB~TB
OLAP 大量のレコードを集計 ETL, イベントストリーム イベント履歴 TB~PB

分析のために直接OLTPデータベース上で実行することを避けるためにデータウェアハウスを用意する

列指向ストレージ

分析のワークロードでは列指向ストレージが使われる

大量にシーケンシャルにスキャンしなければならない場合に、列でまとめて保存しておく

ディスクからのreadを最小限にでき、データの圧縮効率も良い

用語

Chapter 4. Encoding and Evolution

ファイルにデータを書いたり、ネットワーク経由でデータを送信するような、メモリ共有していない他のプロセスに送信する場合、バイト列にエンコードしなければならない

インメモリ->バイト列をエンコーディング(シリアライゼーション)、バイト列->インメモリをデコーディング(デシリアライゼーション)と呼ぶ

データエンコードのフォーマット

スキーマのメリット

言語固有フォーマット

多くのプログラミング言語にエンコーディングライブラリが用意されている。

Javaならjava.io.Serializable, Pythonならpickle

特徴

JSON, XML、バイナリエンコーヂング

Thrift, Protocol Buffer

Protocol Bufferのスキーマ定義例

message Person {
  required string user_name = 1;
  optional int64 favorite_number = 2;
  required string interests = 3;
}

Avro

Avroのスキーマ定義例

{
  "type": "record",
  "name": "Person",
  "fields": [
    {"name": "userName", "type": "string"},
    {"name": "favoriteNumber", "type": ["null", "long"], "default": null},
    {"name": "interests", "type": ["null", "array"], "items": "string"}
  ]
}

データフローの形態

データベースでは、データベースへの書き込みを行うプロセスがデータをエンコードし、読み取りを行うプロセスがそのデータをデコードする。

REST, RPCでは、クライアントがリクエストをエンコードし、サーバはそのリクエストをデコードしてレスポンスをエンコードする。最後にクライアントがレスポンスをデコードする

非同期のメッセージパッシングでは、ノードはお互いにメッセージを送信することによって通信し、送信側がメッセージをエンコードし、受信側がそのメッセージをデコードする