Designing Data-Intensive Applications / データ指向アプリケーションデザイン
https://gyazo.com/f63695ea773fbc2e8d56101e2ad6edde
https://www.oreilly.co.jp/books/9784873118703/
https://www.amazon.co.jp/データ指向アプリケーションデザイン-―信頼性、拡張性、保守性の高い分散システム設計の原理-Martin-Kleppmann/dp/4873118700
articles
https://speakerdeck.com/xerial/30fen-dewakarudetazhi-xiang-apurikesiyondezain-data-engineering-study-number-18
https://speakerdeck.com/xerial/24shi-jian-365ri-dong-kisok-kerudetasisutemunoshe-ji-shou-fa-detazhi-xiang-apurikesiyondezain-shi-jian-bian
メモ
データ指向とは
データの量や複雑さ、変化の速度が主な課題のアプリケーション。多くのアプリケーションはこっち
<-> CPUのサイクルがボトルネックになる演算指向
データシステム
DB, キュー, キャッシュはデータを保存しておくものだが、それらの境界は曖昧になってきている
Redisはキャッシュストア、メッセージキューどちらにでも使われるとか
これらをどう配置するか設計する人でもある
重要な課題
信頼性,スケーラビリティ,メンテナンス性
信頼性 Reliablity
fault tolerant 耐障害性を持つ
なにか問題が生じたとしても正しく動作し続けること
意識的にフォールトを作り出して耐障害性のしくみを継続的に動作させる
NetflixのChaos Monkey (https://github.com/Netflix/chaosmonkey/)
Chaos Engineering
ハードウェアの冗長化
ディスクをRAID構成に
ホットスワップ可能なCPUに など
AWSとかでは単一のマシンの信頼性より柔軟性やエラスティック性が重視して設計されているので警告なしにインスタンスが止まることもある
ソフトウェアの対応も必要。ダウンタイムをなくすためのローリングアップデートとか
ソフトウェアのエラーは手っ取り早い解決策はないので、徹底したテスト、計測、モニタリングなどを積み重ねる事が大事
ヒューマンエラー
適切なAPIの設計などエラーが少なくなるようなシステム設計
サンドボックス環境の用意
テスト
ロールバック、ロールアウト
パフォーマンスやエラーのモニタリング = テレメトリ
スケーラビリティ Scalability
Twitterのスケーリングの課題はポスト数ではなくファンアウト(=twitterにおけるフォロー)
各ユーザーのタイムラインをキャッシュする場合、ツイート1つに対してフォロワー分のタイムラインキャッシュを更新しているらしい
フォロワーが多いユーザーのツイートは個別に取得してマージしているらしい
負荷を表すのはスループットなどのパーセンタイルで、これをSLO, SLAで指定して計測を行う
HOL ブロッキング
キューイングの遅延。低速なリクエストがあるとそれ以降のリクエストの処理が待たされる
負荷への対処としてはスケールアップ,スケールアウト
Elasticなシステム = 負荷の増大を検知して自動的にリソースを追加できる
メンテナンス性 Maintainability
レガシーソフトウェアを生み出すのを避けるため、3つの設計原理に特に注意を払う
運用性
自動化、依存性の排除、ドキュメントなど
単純性
big ball of mud にならないように
抽象化によって複雑さを隠蔽する
進化性
システムの修正が容易であること
RDBの起源はビジネスデータ(銀行や航空機、倉庫などのトランザクション)の処理。
NoSQLは元々非RDBのミートアップのためにTwitterハッシュタグに使われただけのものが、目を引いて広まった
広がった要因は、RDB以上のScalabilityやOSS、RDB以上の特殊なクエリなど
オブジェクトとRDB上のモデルの間に断絶がある(インピーダンスミスマッチ)。ActiveRecordなどORMが吸収して入るが完全に隠蔽しているわけではない
RDBでXMLやJSON型を使う方法もある
多対多の関係や結合の対応が厳しい
非正規化によって、アプリケーション側で非正規化されたデータの整合性を保つための処理が必要になる
ドキュメントDBはスキーマレスと言われるが、スキーマオンリードのほうが正確。
構造は暗黙のものであり、読み取り時にのみ解釈される
リレーショナルモデルに対してネットワークモデルというものが存在した
MySQLはALTER TABLE文実行時にテーブル全体をコピーするためダウンタイムが発生することがある。避けるツールもある
データのローカリティ (局所性)によるパフォーマンス向上
Cloud Spanner
Oracleのマルチテーブルインデックスクラスタテーブル
CassandraやHBaseのカラムファミリー
グラフDB
Neo4jにはCypherというクエリ言語がある
あらゆる者同士に関係が存在するようなユースケース
DBを構成するデータ構造
ハッシュインデックスを使用してログファイルに追記していく
ハッシュマップのデータ構造は、キーのバイトオフセットを基に配列に保存する
コンパクション
KVSだと各キーに対する最新の値だけ保存するため、複数ファイルに記録したログをまとめる追記
削除用のレコードが必要(tombstoneとも呼ばれる)
クラッシュのリカバリ、並行性の制御が課題
SSTable Sorted String Tableで読み取りを早く
LSM-tree Log-Structured Merge Tree は極めて高い書き込みのスループットを出せる
最も一般的なのはB-Tree
キーと値のペアをキーでソートされた状態で保持し、固定サイズのブロックに分割して保存する
ツリーのバランスが保たれることが保証されるので、深さはO(log(n))になる
プライマリキー, セカンダリインデックス
複合インデックス
全文検索で使われる曖昧インデックス
インメモリデータベース
Memcachedのように再起動時にデータが失われるものも
不揮発性メモリが発展すればより使われるようになる
分析用のデータウェアハウス
OLAP (online analytic processing) <> OLTP
スキャンがボトルネックになることが多く、列指向ストレージがよく使われる。BigQueryやAWS RedShiftとか。
スノーフレークスキーマと呼ばれるデータモデルを使用してデータを表現
マテリアライズド・ビューによる集計値のキャッシュ
データフロー
JSON
整数値と浮動小数点の区別がなかったり、精度を指定することができないという問題がある
巨大なデータを扱うにはサイズが大きいので、MessagePackなどのバイナリエンコーディングが存在する
Protocol BuffersやApache Thriftなどのバイナリフォーマットは効率的にエンコーディングできる
RPCの問題
失敗したときのタイムアウト、リトライ処理が必要
ローカル関数呼び出しとは違い、冪等性のチェックが必要(リクエストは届いたがレスポンスは失われたときとか
異なる言語間のデータ型の違い
メッセージブローカー
通信が単方向になり、システムの信頼性を向上できる
分散アクターフレームワーク
Akka, Orleans, Erlang OTP
多少の注意を払っておけば互換性を保ったローリングアップデートは十分に可能である
DBのフェイルオーバーの問題点
レプリケーションが非同期の場合、書き込みが一部失われている可能性がある
auto increment のカウンタがずれていたことで間違ったデータが公開される
スパイクによってフェイルオーバーした場合、リカバリ中にパケットの遅延が悪化する
レプリケーション
シングルリーダー: すべての書き込みを1つのノードに送り、他のレプリカに送られる
マルチリーダー: 複数ノードに書き込みを送り、お互いとフォロワーノードに送られる
リーダーレス: 複数ノードに送信し、修正のため他のノードから読み取る
ebiken.iconレプリケーションで一貫性を保つ仕組み、よく理解できなかったので後で読む
書き込みが並列に行われたとき
複数ノードで行われたとき
ラグは発生するが、結果整合性として一貫性を保つ
パーティショニング
不均等な負荷の集中(ホットスポット)になるとボトルネックになる
キーの範囲やハッシュを使って行われることが多い
セカンダリインデックスもパーティションする必要がある
トランザクション
ACID
Atomicity: 1つのトランザクションが完了しなかったら書き込みを全て破棄/取り消しすること
Consistency: データの一貫性が保たれていること
Isolation: 平行に実行されたトランザクションがお互いから分離されており、逐次実行と結果が一緒になること
Durability: コミットが成功したら書き込まれたデータは失われない
並行性制御
Read Commited (分離性において最も基本的なレベル)
ダーティリード (=未コミットのデータ)、ダーティライト (=未コミットのデータの上書き) を防ぐ
スナップショット分離
直列化可能
順次実行
ツーフェーズロック
SSI
部分障害
信頼性の低いネットワーク
クロックのズレ
Cloud SpannerはTrueTimeを使用している
プログラムが止まる
GCの実行
ebiken.icon長すぎるのでまとめるのは断念。輪読会を開いて読むことにした