17 Dec 2017

ビッグデータを支える技術を読んだ

ビッグデータに関連する各技術の概要と位置づけが分かる本。とても良い内容だった。

ビッグデータの処理基盤は複数の技術が組み合わされているし、Hadoop の登場以降いろいろな技術が登場したが、それぞれがどのような位置づけで、どのような問題を解決するのかをわかりやすく説明している。例えば以下のような疑問が解消すると思う。

  • 各クラウドインフラにはログ系のサービスがたくさんある。例えば AWS だと EMR, Kinesis, Redshift, Athena… それぞれの違いや使い所が明確に説明できない
  • 単純な cron 起動のバッチで実装されていたデータ処理がつらくなってきた。分散処理やジョブ管理ができたらよさそうだが、どこから手を付けてよいかわからない。
  • 他チームがメンテしているログ基盤。なんとなく使えているが、微妙に困ることがあったときにどう対処したらよいかわからない。仕組みをきちんと理解したい。

主な対象読者は以下になると思う。

  • ログ基盤系の専門ではないエンジニア
  • エンジニアが別にいる組織でのデータサイエンティスト

自分は前者の「ログ系が専門ではないエンジニア」だが、今までおおまかにしかわかっていなかったビッグデータ系の技術スタックをすっきりと整理できた。最終章に簡単なハンズオンがあり、具体的なイメージを持つのに役に立った。ラップトップ一台でさくっと試せるように配慮されている。

反対にこの本では以下のことは説明されていない。

  • BI や機械学習など、データの活用方法
  • 各技術の詳細。インストール方法や設定方法などの説明や、例えば kafka などのデータブローカーはどのようなアーキテクチャなのかなど。

あくまでログ基盤の技術スタックの整理ができる本。整理ができているので、次にどこへ進めばよいのかは明確になっている。この分野を勉強したい場合に最初に読むのが良いと思う。

また「現在の」情報が整理されている本なので、新鮮なうちに読むのがよさそう。数年後には陳腐化する内容も出てくるので、この本を起点として今後のアップデートは各自で追ったほうがよさそうだった。

以下は読書メモ

第一章 基礎知識

ビッグデータの定義と関連技術の紹介

  • 従来はデータウェアハウス
  • NoSQL と Hadoop が根本的な技術革新で、それによってシステムの枠組みがかわった
    • 大量のデータを分散して保持する (NoSQL を使うこともある)
    • それを処理するモデルが Hadoop
  • 周辺技術
    • データの収集
    • 可視化 (データマート、BI、etc)
      • DWH のころからある
    • ワークフロー管理
  • ビッグデータ以降のシステムの枠組み
    • データ収集 (streaming / bulk)
    • ストリーム処理基盤
    • 分散ストレージ
    • 分散データ処理
    • データマート
    • ワークフロー管理
  • 用語
    • ETL
      • あるデータストアから別のデータストアへのデータの移動と加工
      • extract-transform-load
    • データフレーム
      • データ処理の際のデータモデル
      • 二次元配列
    • 基幹システム (mission critical system) と情報システム (information system)
      • システムのうち業務に直結する部分とそうでない部分
      • 分けて設計すると良い

第二章 ビッグデータの探索

データの探索 (可視化・分析) のためのパラダイムと技術の解説。 説明されている内容のほとんどが普段の業務で自然に身につけられたものだが、それらの適切な名前がつきモデリングされることには価値がある。今後の業務でもここで紹介されたモデルに当てはめることですっきりと解決できそう。

  • クロス集計はデータの探索において最も基本になる考え方
    • やっていることはピボットテーブルで、二次元の表を作るという行為
    • 集計の軸 (次元) と集約方法 (メジャー。平均・合計など) を決める
    • 以降はクロス集計を TPO に合わせてどう実現するかの話
  • データストア
    • データの分析は往々にして試行錯誤をともなうのでデータを取り出す際の効率が大事
    • 行指向データベースや MPP データベースがその解
    • 行指向データベースは行ごとにデータを保持する。データ分析は大概特定の行だけを取り出すのと、行ごとだとデータの圧縮効率がよい (= メモリに乗る) のがメリット
    • MPP は map reduce のような考え方でマルチコアを使い切るモデル。詳細はよくわからない
  • 分析・可視化ツール
    • アドホック分析は Jupyter Notebook
      • ログを残せる
    • ダッシュボードは redash 等
      • クエリ定期実行とグラフ作成
    • BI は Tableau など
      • ダッシュボードツールの高度版
  • 用語
    • クロステーブル
      • クロス集計された結果のテーブル
    • トランザクションテーブル
      • RDBMS のような、列が固定されたテーブル
    • pivot, melt
      • クロステーブル <=> トランザクションテーブルの変換
    • ルックアップテーブル
      • マスタ系のテーブル (vs トランザクション)
    • データマート
      • ダッシュボード・BI ツール専用のデータストア。分析がしやすい形に変換済みの最終的なデータが入っている。極論コンピューターリソースが無限ならばいらない
    • ファクトテーブルとディメンジョンテーブル
      • それぞれトランザクションとマスタテーブルと同じ
    • 非正規化
      • あえて正規化せずに、全部のテーブルを JOIN した結果を一つのテーブルとして保持するような考え方
      • 行指向データベースではその方が効率がでる
        • 圧縮効率がいいので重複は気にしなくていい
        • 特定行だけを読むので JOIN しないほうが速い

第三章 ビックデータの分散処理

  • 大量にあるファイルを分散ファイルシステムで管理し処理する
  • 分散ファイルシステム、リソースマネージャ、分散データ処理の三要素からなる
    • hdfs
    • yarn, mesos
    • mapreduce, 各種ラッパー (hive)
  • クエリエンジン
    • presto, impala
    • クエリを mapreduce に則った処理に変換して実行する。 hive との違いはオンメモリであること
  • クエリだけでなく mapreduce 全体をメモリでやろうとするのは spark
  • hive + spark
    • hive は分散ファイルシステムからのデータ読み込み・加工をクエリで書ける
    • 結果をカラムナ型のデータストアの形式で保存
    • その結果を presto で参照する
    • presto の方がメモリでやろうとするのでアドホッククエリは早い
  • mpp db vs hadoop (分散データ処理)
    • 分散データ処理では大量の非構造化データを hadoop フレームワークに乗って処理できる。データさえ入れてしまえばその後の柔軟性安定性は高い
    • mpp は etl さえしてしまえばあとはクエリするだけなので簡単。構造化データなので変更時は大変。データ定義の変更と etl の変更がいるし過去データのケアは難しそう
  • hive vs presto
    • 超時間かかるバッチ vs それほどでもないクエリやアドホックなクエリ
  • データマートの構築 (= 集計結果の便利な格納方法)
    • サマリーテーブルを作る (= 次元の圧縮)
    • 非正規化すると楽
    • スナップショットテーブルがあると楽
      • マスターが更新されるような場合 (ディメンションテーブル)
      • スナップショットを非正規化してファクトテーブルと join して保存しておくと楽
  • 用語
    • カーディナリティ
      • カラムの取りうる値の種類の多さ
      • 大きいと表現力が高いが空間効率が悪い

第四章 ビッグデータの蓄積

  • データインジェスションの大別
    • バッチとストリーミング
    • 信頼性が求められる場合は基本的にバッチを選ぶべき
  • ストリーミング型の概要と実装
    • 要素
      • クライアント
        • web, app, device (iot) など
      • フロントエンド、プロデューサー
        • クライアントからのメッセージの受け付け、検証などを行う。その後ブローカーに投げる
        • 一般的にここより前はシステムやクライアントに個別の部分で、ここより後ろは各システムで共通化できる部分
      • メッセージブローカー
        • メッセージ送信に弾力性を持たせ安定させる
        • バッファリングが主な仕事。送信されたメッセージを一定期間保持し、求めに応じて提供する。再送やルーティングもできる
        • kafka, kinesis などが代表。その一部が実装されているのが fluentd など
        • 単純なシステムではブローカーはなく直接ストレージに書き込む
      • コンシューマー
        • ブローカーからメッセージを取り出しストレージに書き込む
        • 適度なサイズまでメッセージを貯めてから取り出してストレージに書き込んだり、短期間のメッセージを逐次取り出してリアルタイム処理したり
      • 分散ストレージ
        • 前章参照
      • 事後処理
        • 重複排除など。後述
  • ストリーミング型での設計のポイント
    • メッセージ送信の信頼性
      • 信頼性を犠牲にしてパフォーマンスを稼ぐことが多い
      • 特にメッセージの重複の許容 (at least once)
        • 必ずメッセージは届くが重複可能性がある
      • 途中の経路は重複排除せず、最後に (エンドツーエンドで) 重複排除するのが基本
      • 集計側で重複を前提とした設計をしておくのがコツ
      • 障害がなければ重複しないので、可用性を高める方向に努力するのもあり
    • 時系列データの処理
      • メッセージが遅延して届く、クライアントの時計がずれているなど
      • イベント時間: クライアントでイベントが発生した時刻 / プロセス時間: イベントがサーバ側に届いた時間
      • 時間に応じてデータストアに挿入するアプローチや、集計基盤ではプロセス時間のみで処理しデータマート側でイベント時間ベースで処理するなどのアプローチがある
  • ブローカーではなく NoSQL を使うソリューション
    • 要は書き込み性能が出ればいいので、フロントエンドからブローカーではなく NoSQL に書くアプローチも紹介
    • それぞれ特徴があるので目的特化でマッチすれば採用可能性あり
    • 代表的な分類
      • 分散 KVS
        • データに一つのキーを振って分散する
        • 広い意味では他のもこの分類に入る
        • マスタスレーブ型や p2p 型など
        • dynamodb などが実装
        • aws ファミリーであれば kinesis, emr, redshift などにデータを流して処理できる
      • ワイドカラムストア
        • 分散 kvs に対して、2 つ以上のキーを振った拡張
        • cassandra, bigtable, hbase などが実装
        • 分散 kvs 同様単体での分析は不向きなので hadoop ファミリーなどにデータを流して使う
      • ドキュメントストア
        • アプリケーションからのデータの取扱のしやすさ振ったもの
        • mongodb など
      • 検索エンジン
        • データ取り出しの高速化に振ったもの。
        • インデックスを作りまくるので挿入は遅い
        • elasticsearch など
          • logstash, kibana と組み合わさることが多い
  • todo
    • kvs の特性系
      • kvs は RDBMS と比べ一部の機能を捨てることで性能を稼いでいる。以下のキーワードで整理するとよさそう
      • acid 特性
      • cap 定理
      • 結果整合性

第五章 ビッグデータのパイプライン

  • ワークフローとデータフロー
    • ワークフロー
      • より汎用的なジョブ管理ツール
      • 各ジョブのステータス管理、ロギング、リトライなどの面倒を見る
      • 実装: airflow, azkaban, digdag, luigi, oozie
    • データフロー
      • 分散データ処理部分に関するもの
      • DAG で処理を記述するものなど
      • 表面上はプログラミング言語に見える。裏では dag で表現されるタスクのグラフに落とし込まれる
      • dag なので直列でなくて良い。適切なサイズで処理が分割されていればリソースを最適に使えるメリット
      • 実装: dataflow (gcp), spark, flink
  • 注意点やコツ
    • 各処理の冪等性を保つこと
      • 一時テーブルを作って swap するなど
      • rdbms への時系列データの INSERT などは難しい
    • 各タスクの大きさを適切にする
      • 粒度が揃うとリソースの最適化がいい感じ
  • ストリーミング
    • データフローについてはバッチとストリーミングのフローの記述は透過的に書ける製品もある
    • 一般的には両者は別物になることが多いので恩恵は少ないかもしれないが
  • ラムダアーキテクチャ
    • 同じデータソースをストリーミングとバッチで並行して処理する
    • ストリーミングで速報値、バッチで確定値のイメージ
    • 複雑なので必要になるまで入れないほうがいい

第六章 ビッグデータ分析基盤の構築

一通りやった