Upgrade to Pro — share decks privately, control downloads, hide ads and more …

24時間365日動き続けるデータシステムの設計手法 : 「データ指向アプリケーションデザイン」実践編

24時間365日動き続けるデータシステムの設計手法 : 「データ指向アプリケーションデザイン」実践編

「データ指向アプリケーションデザイン」をベースに、24時間365日動き続けるデータシステムを実装する際に必要となる技術や考え方を紹介します。

この資料は、2023年大阪大学大学院 情報科学科 マルテメディア工学特別講義で使われた資料を一般用に修正して公開しています。

参考:
「30分でわかるデータベースデザイン」https://speakerdeck.com/xerial/30fen-dewakarudetazhi-xiang-apurikesiyondezain-data-engineering-study-number-18 

Taro L. Saito

October 14, 2023
Tweet

More Decks by Taro L. Saito

Other Decks in Technology

Transcript

  1. ⾃⼰紹介: Taro L. Saito 2 • Ph.D, Researcher & Software

    Engineer • 分散データベースサービスの研究開発・運用 • カリフォルニア在住 (9年目) • Treasure Data • 日本人がシリコンバレーで起業したスタート アップ • CDP (Customer Data Platform)サービスを提 供
  2. 参考図書:データ指向アプリケーションデザイン • 原著:Designing Data-Intensive Applications • 「データ指向」とは、この本のために生み出された新しい訳語 ▪ Intensiveの従来の訳語: CPU,

    Memory-Intensive (CPU、メモリ集中、特化型 ) ▪ では、データ集中、データ特化型、それともデータ指向? • 例えばオブジェクト指向 (object-oriented) は、オブジェクトを中心にプログラムを設計する意味 • データ指向:「データの量、複雑さ、変化の速度」を中心に考えるデザイン 3
  3. 背景:クラウドビジネスの台頭 • 「物を買う」から「サービスを買う」流れが加速 • 例:計算資源もサービスに • 従来: ▪ 計算機を購入し、自分でセットアップ、維持管理 •

    現在: ▪ クラウド上の計算資源を利用するサービスを購入 ▪ 例えば、Amazon Web Service (AWS) の上で、c6g.16xlarge (64 core, 128GB memory)タイ プのマシンを1時間利用すると $2.176 の費用を払う • 物の所有する価値(ownership)ではなく、サービスを利用して得られる価値 (outcome)への変 遷 • 双方に利点 • ユーザー:管理の手間を削減できる。必要に応じて利用量を増やすことができる • サービス提供側:スケールメリットを出せる ▪ 例:AWSにはマシンを大規模に調達して購入金額を抑え、専用ハードウェアを開発して電力 利用を抑えるインセンティブ(経済的な動機)ができる。 ▪ 他にも、AWSはIntel CPUから省電力Arm-based CPU (Graviton 2, 3) への移行を進めてい る 5
  4. 数字で⾒るクラウドビジネスの規模 • 2023年現在、Amazon AWSだけで年間13.2兆円 ($22B x 4 quarters = $88B)の収入に

    • $1=150円換算 • 参考 • 日本の一般会計の歳入 (2023) ▪ 69兆円 (= $420B)。 • 日本の大学の研究開発費 (2022) ▪ 2.1兆円 (= $14B) • Toyotaの収益(2023) ▪ 37兆円(= $274B) 6
  5. Software as a Serviceの時代: ソフトウェアがサービス化する • 従来 • ソフトウェアを販売する(CD-ROM、ダウンロード版製品、OSなど) •

    Software as a Service (SaaS) • ソフトウェアをサービスとして提供する( Webアプリケーション、API) ▪ 例: GMail, Zoom • インストールの手間が少なく、すぐに使える • Webブラウザが重要なプラットフォーム ▪ Google (Chrome), Microsoft (Edge) など、SaaS企業がブラウザへの開発投資をしている • Platform as a Service (PaaS) • ソフトウェアを動かすクラウドプラットフォーム(マシン、ハードウェア、等)を提供する • ベンダーが各国に拠点を展開し競争中 ▪ Amazon AWS, Microsoft Azure, Google Cloud Service など • クラウド上にデータが集まってくるようになり「データ指向」のサービス構築が重要に • データには重力(Gravity)があると言われることも 7
  6. まずはデータを作るところから • データ量が少ない場合 • データの表現、生成しやすさが重視される • テキストデータフォーマット • CSV、JSON、XMLなど。テキストエディタでも記述できる •

    正確なデータ型をコンパクトに表現したい場合に若干困る • バイナリデータフォーマット • MessagePack • Thrift (現在ではApache版と、Facebook版が分離) • ProtocolBuffers (Google) • Apache Avro • データとして完結している自己記述型 (self-describing) データフォーマット • 例外:ProtoBufはデータ自体にスキーマを含まない (self-describingではない)ので、かなり節約指 向 9 JSON csv csv csv
  7. • データ基盤では省メモリ、圧縮しやすさ、ストレージへの格納しやすさが重視される • テーブルフォーマット • スキーマ(各カラムの名前、型)とレコード表現を分離 ▪ カラム名、型の情報を繰り返して出力しない分、コンパクト • 行指向(row-oriented)

    フォーマット • RDBMSでよく使われる • 一行(1 record)ずつ表現 • レコード単位で更新しやすい • 列指向(column-oriented)フォーマット • 列(カラム) • 同じ型のデータを集めると圧縮しやすい • 分析クエリ向き ▪ キャッシュに乗りやすく高速 ▪ SIMD演算も活用しやすい • 一方、単一レコードの更新は大変 データ量が多い場合 10
  8. 列指向データフォーマット (Columnar Format) • 例:Apache Parquet • Google Dremel (VLDB2010)

    のアイデアがベース • ネストして繰り返しのあるデータでも、同じパスごとに分解、圧縮する ▪ Spark、DuckDBなど、エコシステムで広くサポートされるように • クラウド上のストレージ (AWS S3など)で扱いやすくするための工夫 • S3:スループットは高いが、ランダムアクセスの latencyが大きい (10ms - 数百ms) • 1ファイル内でページ分割、フッターに各ページへのインデックスを格納 11
  9. データが変化する速度は? • 変化しない場合:不変データ(immutable data) • 例:蓄積されるログデータ。列指向フォーマットが使いやすい • 読み込み特化型 (read-intensive) •

    データへの高速なアクセス、分析の速さが問われる  • 読み込み特化型の高速化手法: データを分散する • パーティショニング (シャーディングとも言われる) ▪ データを時間範囲(1時間、1日など)、あるいはキー範囲などで分割する ▪ 必要なデータのみにアクセスしたり、別領域のデータへの並列アクセスを可能に • レプリケーション ▪ 同じデータを複数箇所(マシン、ディスク)に配備する ▪ 並列アクセスしやすくし、耐障害性を持たせる • 実体化ビュー (Materialized View) ▪ 一度計算したクエリ結果を保存し、再利用できるようにする 12
  10. データが頻繁に更新される場合 • 書き込み特化型 (write-intensive) • RDBMSが強い分野 ▪ レコード単位での更新 ▪ トランザクション処理

    • 更新対象をどう素早く見つける? • インデックス:ディスク上のデータを高速に見つけるためのデータ構造 ▪ B-Tree, Hash index、SSTable (Sorted String Table) 13
  11. クラウドストレージ上でデータベースを作成する • データベースを構成する技術 • クエリコンパイラ ▪ 例:SQLの字句解析(lexer), 構文解析 (parser) ▪

    論理実行プラン作成 (logical plan, relational algebra) ▪ 分散実行プラン作成 (execution plan) ▪ クエリオプティマイザ(最適化) • クエリ実行エンジン ▪ プランにしたがってデータを処理する ▪ selection, projection, join, aggregation, sortingなど (Relational Operators) • クエリキュー • データカタログ ▪ テーブルリスト ▪ スキーマ (テーブルカラム名・データ型)管理 • データストレージ ▪ オブジェクトストレージ( S3など)、ローカルディスク (SSD)など ▪ パーティションやレコードへの索引 • クラウド上のリソース確保のためのシステム (auto-scaling, instance provisioning)
  12. 発展:Log-Structured Merge (LSM) Tree • 更新がさらに頻繁な場合にどうするか? • レコードの追加、コンパクション操作を分離する • メモリ:ランダムアクセスに強い構造

    ▪ 例:更新されるたびにメモリ上でソートしておく • L0, L1, …:ディスク、外部ストレージなど ▪ 定期的にソート済みのデータと合成(merge sort)して次のレイ ヤーに保存する • 性能特性 • 更新時のランダムアクセスを減らせる ▪ SSD内部でも、一度キャッシュメモリでランダムアクセスを吸 収してから、シーケンシャルアクセスに変換し、セルの寿命を 伸ばしている • 各種オーバーヘッド ▪ 読み込み時に各レイヤーにアクセスする必要がある ▪ 書き込みの増幅(Write Amplification)が生じる • 関連 • LevelDB、RocksDB(C++)、AWS S3(Rustで実装)など 16 RocksDB Overview Amazon S3 Data Structure (SOSP 21)
  13. • Partition Index • データファイルのパス、統計情報を管理するデータベース(あるいはファイル) • 古い方法 • S3上の特定のパスにデータファイルを保存、 S3

    LISTでファイル一覧を取得 ▪ Key-valueストアのS3でのLIST操作は遅く一度に1000個のオブジェクトまでしか取得できない • トランザクション管理がない ▪ データを追加・削除中の状態が、他のクエリから見えてしまう(dirty read) • HiveMetastore (2010-) • Hadoopのエコシステムで広く使われている ▪ Hive, Spark, Trino, etc. • HiveMetastore serverがパフォーマンスのボトルネックになる • 最近の流行 • パーティションのリストとカラム統計情報をまとめて S3に保存する • Hive Metastoreの性能問題を解決 Partition Index: データファイルに索引を付ける 17 Partition Indexes Columna Partition Files
  14. カラムの統計情報を⽤いた最適化 • SQLのWHERE句で使われている条件を抽出 • =, >, <, <=, >=, IN

    • 実際のデータを読まずに、カラムの統計情報から、ターゲットのデータが含まれないパーティションをスキップする • 統計情報の例 • レコード数、nullの値の数、カラムのmin/max • Bloom filter ▪ カラムの値 x に複数のハッシュ関数h1(x), h2(x), …を適用した値を、ビットベクターにセットする ▪ ある値xに対して、 • h1(x), h2(x)の全てのビットがセットされていてば、そのパーティションは該当レコードを含んでいるかもし れない。 • false-positivesは許可するが、false-negativesは許可しない • Spatial indexes (S2 Cell) • 値の頻度ヒストグラム 18
  15. Apache Iceberg (2018-) • テーブルフォーマット (spec) • テーブル内のパーティションファイルのリストをヒスト リーを管理 •

    マニフェストファイル ▪ パーティションや他のマニフェストへのポインター • メタデータを同時に更新できるのは1つのプロセスの み ▪ コンフリクトせずにマニフェストを更新できるまでリト ライし続ける • カラム統計 • マニフェスト内に、カラム名から min/maxなどの値へ のマップを保持 19
  16. Databricks: Delta Lake (2019-) • Delta lake: high-performance ACID table

    storage over cloud object stores (VLDB 2020) • Iceberg同様、パーティションリストの変更履歴を保持 • 定期的にコンパクションを実行( 10分おき)、チェックポイントファイルを作成する • 読み込み操作 • 前回のチェックポイントから現在までの全ての変更ヒストリをスキャン (S3 LISTを使う) • 新しいversion(00000N.json file)を追加するには、put-if-absent操作が必要 ▪ S3にはput-if-absentがないので、コーディネーターサービスが必要 • 以下の機能を実現 • Time travel • UPSERT, DELETE, MERGE • Streaming I/O • Caching • Data layout optimization • Schema evolution (adding columns) • Audit logging 20
  17. Google: BigQuery Partition Indexes • Big Metadata: When Metadata is

    Big Data (VLDB2021) • Google BigQueryでは、60%のクエリが1%以下のデータしか必要とせず、25%のクエリが 0.01%のデータしか結果に必要としていない => Partitionの読み飛ばしが重要 • カラム名フォーマットで、カラム統計情報を保存し、必要なカラムの統計情報のみにアクセスでき る • min/max, bloom filter, S2 Cell (spatial index for geo-spatial search) • partition setのgenerationを管理し、過去7日分保持 time travel (for last 7 days) • SQLを処理の中にpartition listのscan, pruningを埋め込み1passで処理している • _block_locatorカラムがパーティションファイルの位置を管理 21 Partition Index Scan Column Statistics
  18. 分散データでの新たなチャレンジ • 1箇所にデータがある場合と比較して、 考えるべき問題の複雑さが数段上がる • そもそもノード間でデータを送受信するために、 分散システムが必須 • 分散ステートマシン、つまり各ノードが同じ状態になる必要( membership問題)がある

    • サーバー・クライアント間でのデータ通信 (HTTP上で実装されることが多い ) ▪ RESTプロトコル、RPC (Remote Procedure Call) • 複数箇所で頻繁に更新される場合 • 同期(ロックの取得、タイムアウト、トランザクション、ログのリプレイ) • どの状態が正解かを決めるための合意( consensus)プロトコル ▪ 多数決 (Quorum) で決める:Paxos、2PCなど ▪ あるいは、そもそも調整を避ける( coordination avoidance) • 障害対応 • エラーハンドリング、リトライ、冪等性 (idempotency)、障害からの復旧・リカバリ • ノードが嘘を付く(間違ったデータを返す)ビザンチン障害と呼ばれる 24
  19. HTTP通信でのリトライ (Retry) • 100%の稼働率に依存したコード • 障害時に動かなくなったり誤った動作をしてしまう • 99.99%程度の稼働率でも安全にアプリケーションを作るには? • ベストプラクティス

    • あらゆる通信リクエストに、リトライ(再実行)、エラー処理を実装する • サーバーからのレスポンスをリトライ可能 (retryable)か、リトライできないもの (non-retryable)にわけ る 25
  20. • http statusコードでまず分類 • 2xx 成功 • 4xx ユーザーエラー (リトライしないが、一部例外 あり)

    • 5xx サーバーエラー (リトライする) • 例外(Exception)パターンによりさらに分類 例:Airframe HTTPでのリトライ処理 26
  21. • 稼働率 (Availability) • 許容されるダウンタイム ▪ 99.9% availability 8.7時間/年 ▪

    99.99% availability 53分/年 ▪ 99.999% availability 5分間/年 • アプリケーションのデプロイ時 • サービスを動かし続ける必要がある ▪ 複数バージョンのアプリケーションが同時稼働する • デプロイ中、あるいはクラッシュ時に通信が遮断される • クライアント側でのリトライ(再実行)処理 ▪ サーバー側の稼働率の要件を緩められる • 冪等性 (Idempotency) • リトライが起こる前提で設計する ▪ 同じ操作が繰り返されても、データを重複させない • リクエストにUUIDなどをつけて重複をチェックする 24時間365⽇動き続けるサービスの設計 27 Client Server v1 Server v2 リクエスト失敗 デプロイ(更 新) リトライ Client Server  ネットワーク障害 (レスポンスだけ失敗) データ重複 (!!!) リトライ 重複リクエスト除去 UUID check リクエスト成 功
  22. ユニークなIDの⽣成⽅法 • カウンターを1ずつ増やす • カウンターの状態を管理するサービスが別途必要。分散システム向きでない • UUID (Universally unique identifier)

    • 128-bitの乱数。分散して生成しても衝突確率が非常に低い ▪ 例:6d79373f-8157-44b1-b1f8-276028bbda12 • 完全にランダムで順序が定義されないため、 indexとして使いにくい • ULID (Universally Unique Lexicographically Sortable Identifier) • タイムスタンプをprefixにし、乱数を加えたID • 時系列順にソートでき、文字列 (string)として管理できる • UUID v6, v7 • UUIDにタイムスタンプを加えようという提案 28
  23. クラウド上でのアプリケーションデプロイメント • In-Place Deployment • マシン内でアプリケーションをアップデートする。ステートレスな Webサーバーでよく使われる • Blue-Green Deployment

    • 複数系統のサービス(BlueとGreen)を立ち上げ、動作を確認後トラフィックを切り替える • トラフィックを切り替えるためのルーターあるいはロードバランサーが必須 29
  24. より⾼度なデプロイメント • Canary Deployment • 特定のサイトやユーザーのみ upgradeする(炭鉱のカナリア・有毒ガスの検知が由来) • 利点:Blast radius

    (障害の影響範囲)をコントロールできる • 欠点:デプロイの手順が複雑に。自動化システムを用意する必要あり • AWSでは、デプロイメントを多数のステージに分けて自動化している • 参考:Automating safe, hands-off deployments (Amazon Builders' Library) 30
  25. 100%動き続けるシステムを作るには⼤きな費⽤がかかる • 常時システムを動かすには、あらゆる障害を想定する必要がある • ソフトウェアに起因するもの:バグ、システムの高負荷、ネットワークトラブル、設定ミス、アップグ レード時のトラブルなど • ハードウェアに起因するもの:ディスクの故障、ハードウェアの老朽化、ネットワーク切断 • 外的要因:地震、停電、天変地異

    • 対応策 • データセンター間でサービス移動 • 大陸間をまたがったサービス移動(あまり現実的ではない) • 障害時にバックアップとなるサービスを用意するには、顧客もそれなりの費用を支払う必要がある • 例:携帯電話がつながらない ▪ 100%使えるようにするためのバックアップとして複数社の携帯サービスを常時利用するコス トを支払う用意があるか? • 24/7サービスを運営していると、他社の障害に同情できる 32
  26. リトライ間隔の⼯夫 • Exponential Backoff • リトライ間隔を倍々にしていく手法 ▪ 1 sec., 2

    sec., 4 sec., 8 sec., .. (x 2)の場合 • 問題 ▪ 待ち時間が長くなりすぎる ▪ 分散環境で、各ノードが同時にリトライすると、同じ間 隔でリトライされ、synthetic pressureが発生する。 • システム障害時に深刻 • Jitter • 同じくリトライ間隔を倍々にするが、 0~1の間の乱数を かける手法 ▪ 1 sec * rand(), 2 sec * rand(), … • リトライ間隔が調整なしにばらけるようになる • 参考 • AWS Architecture Blog: Exponential Backoff And Jitter 33
  27. トランザクション処理 • 障害があっても安全にデータベースを更新する技術 • ACID (1983年に提唱されたキーワード ) • Atomicity, Consistency,

    Isolation, Durability • 単にACIDと言う場合、ほぼマーケティング用語 ▪ 何がどう保護されるかは、実装の詳細まで見ないとわからない。実は専門家になるほど、 ACIDの意味 がわからなくなる • ACIDの中では分離性( Isolation)の概念が最も重要 • 直列化可能性 (Serializability) が基本 ▪ トランザクションが1つずつ実行されたのと変わらない状態を維持する。オーバーヘッドが大きいため現 実的には使われにくいが、逐次実行しても性能が得られる場合も • 弱い分離性 ▪ Read-Committed、Snapshot Isolation、MVCC (Multi-version concurrency control) • 妥協しないアプローチ: Serializable Snapshot Isolation (SSI) (SIGMOD 2008 best paper) • トランザクション異常(anomaly)の種類 ▪ ファントム (まだ存在しないレコードに、どうロックをかけるか) ▪ Write Skew (同じスナップショットを読んで、違う場所に書き込む) • Repeatable Read (という紛らわしい名前)の弊害 => 実はrepeatableではない 34
  28. 分散トランザクションの世界 • 複数ノード間、複数システム間でトランザクションを実装する • 一貫性、合意、耐障害性 • 線形化可能性 (linearizability) ▪ レプリカが複数あっても、コピーが1つしかないように見せる。つまり、更新操作が終了した途端、全ノー

    ドが同じデータを見られるようにする • 要素技術 (9章に詳しい) • リーダー選出(leader election) 、サービスディスカバリ、メンバーシップ管理 ▪ これらが正しく実現、シングルリーダーレプリケーションなども正しく実装できない • 関連:Zookeeper、etcd (Kubernetes内部で使われる) • 異なった方向性の新しいアプローチ (2022~) • アプリケーション側のクライアントで分散トランザクション処理を吸収 (ScalarDB) 35 Scalar DB (VLDB 2023)
  29. 分散トランザクションの極み Amazon Aurora (SIGMOD 2018) • 分散版MySQL:6つのレプリカを作成 • 2 copy

    x 3 AZs. Availability Zone (AZ)が1つ落ちてもquorum(多数決)を取れる:4/6 • MySQLのデータベース更新操作を「ログの書き込み」だけに簡略化 • ストレージノードがログを分配、各インスタンスでログをリプレイして同じデータを持つ ▪ gossipプロトコル(ランダムにノードを選んで配信、同期システムなしに実装できる) • さらに、トランザクション処理も同期をなるべく取らずに処理( Coordination Avoidance) ▪ 各ノードの返信を待つ2相コミット (2PC)を使わなくても良いよう、 MySQLの裏側のストレージ全体を再設計 36
  30. Tsurugi: ⾼速トランザクションを実現した国産RDBMS • 数百万 transaction / second を実現 • メニーコアの性能を最大限引き出すことを目標に

    している • 2023年現在ではシングルノードのみ対応している が、今後分散実装も提供される予定 • 基本デザイン • Multi-version concurrency control (MVCC) ▪ 複数のversionのデータがメモリ中に混在 • Optimistic concurrency control (OCC) ▪ ロック (e.g., mutex) を取得しない • user - kernel間のコンテキストスイッチを 減らせるので性能を上げやすい ▪ コミット時に整合性をチェック • 多数のレコードを触るバッチ処理に対応するた めのプロトコルの工夫
  31. データの複雑さ:「テーブル」の意味の変化 • 従来の「テーブル」の定義 • RDBMSにある最新のデータ (snapshot) • 現代での「テーブル」の意味 • 時間とともに変化するデータ

    、そこから派生するデータ(derived data)を表すように • 列指向クエリエンジンの発展により、分析クエリが容易になり導出データが大量に ▪ Redshift, BigQuery, Trino, Spark, DuckDBなどのクエリエンジン、サービス • バッチ処理、ストリーム処理 • 近年では両者の区別は少なくなってきいる 39
  32. 導出データ (Derived Data) • 数千以上の導出データが生成される実例 (Treasure Data社) • クエリで生成されるデータの依存関係や、データの履歴を管理するには? • 例

    ▪ dbt: クエリの依存関係を記述できる SQL compilerを使う ▪ 新しいTable Format: Delta Lake、Icebergなどを使い、テーブルの更新履歴の確認、スナッ プショットを管理(time travel)する、など 40
  33. 例:dbtによるインクリメンタル処理 • dbtはpythonで書かれたSQLテンプレートコンパイラ • 導出データを、model(SQLテンプレート)として定義する • SQLのテンプレートをコンパイルし、複数のSQLを実行するスケジュールを作成する • ユーザーはCREATE TABLE,

    INSERT INTOを明示的に書く必要がない • 自身や他のモデルを{{ … }}で参照して、モデル間の依存関係を定義する • {{ this }}: References the self-update target table • {{ ref(“....”) }}: References the table generated by another SQL template SQL Template Table Presence Check Build from scratch Incremental Update 41
  34. バッチ処理によるデータ加⼯ • Unixコマンドでのデータ処理に近い • $ cat access.log | grep “xxx.yyy”

    | awk ‘{ print $2; }’ | sort | uniq • UNIX哲学 • 端的な機能を持つ様々なコマンドを用意 • 個々のコマンドの標準入出力をパイプでつなぐ • シェルの裏側ではコマンドごとにプロセスが起動していて、プロセス間のストリーム処理をしている ▪ ひと昔前の東大情報科学科の OS演習では、シェルをCで実装する課題があった。プロセス起 動、同期(mutex、signal)、I/Oを同時に扱うため、難しい課題 • これを分散(複数ノード)で実行するには? 42
  35. 分散バッチ処理 • Spark (2009) • Microsoft DryadLINQ (2008)のアイデアがベース。 • UNIXコマンドのような命令(小さなプログラム)を並列・分散実行するイメージ

    • MapReduce (Google 2004, Hadoop 2006) • Mapper: (key, value)のペアを出力する。Reducer: 同じkeyに属するvalueを集めて集計結果を出力 • フレームワーク側が自動で分散実行 ▪ MapSide Join, Broadcast/Hash Joinなど様々なテクニックが誕生。SQLも実行できる(Hive)  43 DryadLINQ(2008) MapReduce
  36. ストリーム処理 • バッチ処理 • 保存されているデータに対してクエリを実行 • ストリーム処理 • クエリをデータの入力側に送り、常時クエリを実行し続ける •

    あるいは、データの変更をとらえ処理する ▪ マイクロバッチ、CDC (Change Data Capture) • Dataflow Model (Google, VLDB 2015) • 時系列データ処理方法の分類・パターンの定義 • 遅れてやってくる(late arraival)データの処理を埋め合わせる必要性を提示 ▪ event time, processing timeをwatermarkで管理 • Apache Beamなどに実装されている 44
  37. データモデルの多様性とその歴史 • JSON、XML、テーブル、グラフ(ノードとエッジ)など • 1970年代から議論が続く (詳しい歴史は Redbookにも) • ネットワークモデル (CODASYL) •

    階層モデル • リレーショナルモデルによる RDBMSが圧倒 • 種々のデータ形式(JSON、XMLなど)のサポートが、次々に RDBMSに取り込まれていった • その理由:データベースにとっては、 DBMSの品質(トランザクションサポートなど)が重要で、新しいモデルが 生まれても、ユーザーにとって本格的に使うまでの道のりが長かった。 • インピーダンスミスマッチ( Impedance mismatch) • アプリケーションで使いたい表現(構造化データ、オブジェクトなど)と、データベースに格納される形態(テーブ ル)がマッチしない状況 • NoSQL • SQL、リレーショナルモデルへの不満から、ドキュメントモデルなども生まれる • バズワードとして広まったが、次第に Not Only SQLとして解釈されるように • 歴史から学んだ最近の良い事例 • GraphQLはRDBMS、SQLとはむやみに喧嘩しないアプローチ。RDBMS、SQLは利用しつつも、アプリケー ション側が欲しい形でデータを取得するのをサポート 46
  38. インターフェースとしてのSQLの価値 • SQL • RDBMS専用のインターフェースだったが。。。 • Google F1(VLDB2018) • Google社内の多様なストレージに

    SQLでアクセス • ZetaSQL:共通SQL実装 (OSSで公開されている) ▪ BigQueryにも使われている • Meta • 共通SQL + Velox処理エンジン (CIDR 2023) • Trino Distributed SQL Engine • 種々のデータソースへのコネクタを提供 • ストレージ実装を持たない SQLエンジン 47
  39. Trino: ストレージを持たないOSSクエリエンジン • Trino (formerly known as Presto) • Facebookが公開した分散SQLエンジンのOSS。後に開発者が独立してTrinoに名称変更

    • 多様なデータベース、ストレージにコネクタ経由で接続して SQLクエリを実行できる • Data Source APIでストレージ層を分離 48
  40. DuckDB: 敢えて分散しないSQLエンジン • C++で実装された小さな列指向SQLエン ジン • JSON/CSV/Parquetファイルなどを直接 読める • 利点

    • データベースサーバーを立てずに SQL を実行できる ▪ コマンドラインでも動く • 列指向データの扱いに強く、分析クエリ を高速に実行できる • WASM (WebAssembly)を使って、ウェ ブブラウザ上でも動いてしまう
  41. 10年戦えるSQL • 今、学んで一番役に立つプログラミング言語は? • データ指向の時代では、ほぼ間違いなく SQLによる処 理が必須 • Pythonなどは比較的すぐに使える •

    ただし、SQLは必ずしもユーザーに優しくないことでも 有名 • 参考 • 「10年戦えるデータ分析入門 」 • 「さらに10年戦えるかもしれないデータ分析入門 」
  42. 具体例:ツイート配信の実装 (Fanout Service) • 1:初期のTwitter(X)の実装 • ツイートをグローバルなコレクション (DB)に格納。ユーザーがタイムラインを見るたびにフォロアーの ツイートをDBから検索 (読み込み負荷が高い )

    • 2:(改良)ツイート時にフォロアーのタイムラインキャッシュにもツイートを送信 • 書き込み負荷は高い が、タイムラインの読み込み時の負荷が2桁減った • 極端な例: Elon Muskは128Mフォロアー (= 128M ファンアウト) • ツイートするたびにフォロアーのタイムラインキャッシュに 1.28億回の書き込み? 53 ファンアウト(広 がり) タイムライン取得 ツイート
  43. 128M followersの割にElon Muskのインプレッションが低い問題 • ファンアウトサービスが高負荷でクラッシュして、 95%のツイートが配信されていなかった • データ指向アプリケーション的に興味深い • 信頼性

    • 一部のサービスがクラッシュしてもサービスは動 き続けている。障害への対応 • メンテナンス性 • 数千人規模のエンジニアのレイオフをしても耐 えられる。運用の自動化、知識の継承、維持が できている(?) • スケーラビリティ • 数億回の読み書きはいずれにしても発生。分散 RPC (Finagle) 、レプリケーション、スロットリン グ(性能調整)はどうなっているか? 54
  44. Service Level Objectives (SLO) • SLO • サービスにどの程度の availabilityやlatencyを 持たせるかの目標値

    • SLA • Service-Level Agreement • 顧客との契約上取り決めた性能目標値 • システムメンテナンスの頻度などから逆算 • Status Page • サービスの稼働状況の情報を提示 • 各企業がSite-Reliability Engineering (SRE)チー ムを持つようになってきた • SLO violation budgetを管理 55
  45. 障害対応のためのOn-Callスケジュール • PagerDuty • 誰がどの時間のアラート 対応するかを管理 • 障害時に通知が飛ぶ • 障害対応

    • アラート監視 • Runbookを用意 ▪ 対応マニュアル • 各国にエンジニアがい ると24時間カバーしや すい
  46. SLO: システムのパフォーマンスをどう測るか? • 平均値を見るだけでは、データ規模が大きく性能が遅くなりやすい重要顧客の様子が見えてこな い。 • 95、99パーセンタイル (p95, p99) などを見てSLOを決める

    • SLO (Service Level Objective) • Amazonでの例: p99.9でのレスポンスタイムを一定値以下に。 100ms 遅くなれば、売り上げが 1% 下がるというデータがある( 2022Q4にonline storeは$64Bの収入。その1% = $640M) ▪ ただし、p99.99の極端な領域での改善は、コストの割に利益を十分生まないと判断 57
  47. システムの品質管理にはログデータの収集が不可⽋ • Treasure Dataでは自身のシステムを使って、クエリログを収集、解析している • Implicit SLOの計算、ワークロード予測 • 主な用途 •

    性能分析、クエリシミュレーション用のベンチマーク生成 Logs Batch Data Partition Indexes (PostgreSQL) Realtime Storage Archive Storage Merge periodically Table Catalog Query Logs PlazmaDB Tables Query Logs Simulation Logs Customer-Specific Benchmarks Replay Queries Production Cluster Control Cluster Test Cluster PlazmaDB Query Simulator Simulation Reports Build Benchmarks Extract Workload Pre-production Collect Query Logs Read/Write Partitions Stream Import Bulk Import 59
  48. クエリの挙動をユーザーごとにテスト(Simulation)する • 実際のデータ(production data)にアクセスして、クエリの挙動をテ スト • 社員は顧客のデータを直接見ることはできないシステム設計 • 全てのクエリをテストするのは非現実的 •

    クエリの分析、クラスタリング、データアクセス範囲の縮小などを行う 60 User Query User Query User Query User Query User Query User Query 50,000,000 queries clustering Query Sig Query Sig Query Sig Query Sig minimize Small Query Small Query Small Query Small Query 100,000 query patterns 100,000 small queries simulate queries simulation results and stats
  49. Google NapaでのSLOコントロール • クエリを速くする手法は、コストを度外視すればいくらでもある • 例:データを全てメモリに展開する • 速いマシンを多数並べて使う • あらかじめMaterialized

    View (計算済みのクエリ結果)を用意しておく • Google Napa (VLDB 2021)では、queryable timestamp(QT)をユーザーが調整できるようにして、性能とコストのトレードオ フを取っている • QTを小さくする: リアルタイムデータ処理。データがすぐに前処理される(view maintenance)。CPU、差分計算が常に 発生するので稼働コストが高い • QTを大きくする:バッチデータ処理。データを後でまとめて処理することで、コストを抑える 62
  50. 課題:マシンリソース利⽤率(utilization)の最⼤化 • 時間帯やワークロードによってピークタイム の波ができる • US (upper) ▪ 全世界の顧客 •

    Tokyo (lower) ▪ 日本顧客のみなので利用者が 少ない時間帯がある • ピークに合わせてクラスタサイズを最適化 (auto scaling)するだけで、億単位の費用が 節約できることも • Capacity Planning • Reserved instanceなど、3年分まとめ て購入すると40-50%程度の割引があ る • そのため、コスト削減の効果が 50%を 超えるようなauto-scalingでないと意味 がない 63
  51. データのセキュリティの担保 • 例:Treasure DataのTrust & Security Compliance一覧 https://trust.treasuredata.com/ • 各種セキュリティ基準に準拠していることを

    示す • SOC-2 • コードの開発体制の監査 ▪ 例:コードレビューがなされているか、テスト要 件を満たしているか • 誰がプロダクションデータにアクセスできるかを管理 ▪ 例:SSHによるマシンアクセスを制限、ネット ワークの分離、など • 顧客データを直接見られないようにするシステムデ ザインも必要 64
  52. 差分プライバシー(Differential Privacy)によるプライバシー管理 • 差分プライバシーを考慮した SQLエンジンの実装 • クエリの集計結果にノイズを入れたり、少人数のグループからなる結果を隠す( aggregation thresholding)仕 組み。複数社間でデータを分析用に共有したい場合のプライバシー管理

    Provider Consumer Secure Exchange SQL Consumer Tables Analytic SQL Provider Tables Distributed Query Engine Provider CDP Secure join User-Level Sampling Access Delegation Encrypted Data Noise Injection Anonymized Statistics Query Rewrite Sensitivity Analysis Privacy Policy Check Privacy Budget Management Segment Insights Aggregation Thresholding 65 Consumer CDP Differential Privacy
  53. Differentially Private (DP) SQL Engine • 特定の個人のレコードがデータベースに存在するかどうかにかかわらず、同じようなクエリ結果を返す • 例:Google Mapの混雑データにはDPによるノイズが含まれている

    • Neighbour databases (近隣データベース)を考える • 特定の個人からのレコードのみが違う、あらゆるデータベースの D1、D2の組み合わせを考慮する • すべての近隣データベースに対し、同じようなクエリ結果を返す = Differentially Private • ノイズを入れることでこれを実現。クエリ結果から、特定の個人の情報を類推しにくくなる • Differential Privacyは攻撃方法に依らない理論のため、将来に渡ってプライバシーに関する一定の保証を提供できる 66 An illustration from “Why differential privacy is awesome” D1 D2
  54. おわりに:より深い世界に踏み込むために • データ指向アプリケーションデザインを題材 に、実務上で必要な知見を紹介してきた • 今後は論文からも情報収集できるように • 現在はクラウド企業からの論文も充 実している(Industrial Track)

    • 実際のサービスを開発したり、 OSSを動か す経験からも学びが多い • 今日紹介した内容の大半は、データ指向 アプリケーションデザインには書かれてい ない • ソフトウェアのサービス化の時代 • ソフトウェアを開発するだけでは売れにく い • サービス化することを視野に 67