- Background
- Twitterでは2012年の時点でKestrel、BookKeeper、Kafka、DBをメッセージキューとして使用
- Kestrel
- 特徴
- シンプル
- メモリ上にキューが収まる限り、高性能
- Fanout用にSubscriber毎にキューを作成
- アイテムレベルのトランザクション管理可能
- DC間のレプリケーション
- 制約
- 各キューがファイル単位で分離しているため耐久性確保が困難
- Subscriber追加にキューを物理的にコピーする必要があるため大変
- 読み込み時大量のランダムIOが発生
- Queue数に伴うスケールアウトに乏しい
- 特徴
- Kafka
- 特徴
- 少数のTopicに対して優れたスループット/レイテンシをシーケンシャルIOで実現可能
- 不要なデータコピーを回避可能
- DC間のレプリケーション
- 制約
- ファイルシステムのページキャッシュに依存
- 1ディスクあたり数個以上のTopicを作成すると性能に課題
- Subscriberに障害が発生するとランダムIOが大量発生
- 特徴
- 問題点
- 上記の制約より、メンテナンスのオーバーヘッドが拡大
- ソフトウェアコンポーネントの管理
- 管理性と追従性
- デプロイ、アップグレード、ハードウェアメンテへの対応や最適化
- 技術的ノウハウ
- 上記の制約より、メンテナンスのオーバーヘッドが拡大
- メッセージングには何が必要か?
- 統一したスタック
- 様々なワークロードに統一されたスタック内でトレードオフの調整が可能
- 耐久性とクラスタ間、地域間のレプリケーション
- マルチテナンシ
- ハードリソースの独立した追加ができ、コスト優位性
- 管理容易性
- 統一したスタック
- Layered Architecture
- Data Model
- Log Streamモデル
- Log Segment
- Entry(Log Segment中のレコード群)
- Sequence(Entry中のインデックス)
- DLSN(LogSegmentSegmentName, EntryId, Sequence Id)で指定
- SequenceId + Transaction Idを保持
- Log Streamモデル
- Software Stack
- Application Layer(Write Clients + Read Clients)
- Stateless Serving Layer(WriteProxy + ReadProxy)
- Core Layer(Writer + Reader)
- Persistent Storage Layer
- Zookeeper(Metadata Store)
- Bookie(in Memory, Bookkeeper)
- Cold Storage(HDFS)
- Data Flow
- 書込
- 1.Write Client > Write Proxyに書き込み
- 2.バッファ転送
- 3.Write Proxy > Bookieにバッチ書き込み&flush
- 4.Write Proxy > Write ClientにAck
- 5.Write Proxy > Bookieに制御レコード書き込み
- 読込
- 1.Read Proxy > BookieにLong poll Read
- 2.Read Proxy > Bookieに投機的読み込み
- 3.Read Proxyでキャッシュ
- 4.Read Client > Read ProxyにLong poll Read
- 書込
- Data Model
- Design Details
- Consistency
- LastAddConfirmed => Consistent views among readers
- Log書き込み後、LogSegment単位でConfirmed化することでReaderから読めるように
- Fencing => Consistent views among writers
- ZookeeperのEphemeralNodeで書き込みオーナー追跡
- 高速な障害検知
- TickTime = 500(ms)
- Session Timeout = 1000(ms)
- 高速な障害検知
- 書き込みオーナー以外はLogSegmentに追記が出来ない
- 1LogSegment内でもオーナーは切り替わる
- ZookeeperのEphemeralNodeで書き込みオーナー追跡
- LastAddConfirmed => Consistent views among readers
- Global Replicated Log
- Region Aware Data Placement
- リージョンを跨いで書き込みオーナーが移動
- リージョンベースの配置ポリシーをWrite Proxy / Bookie間に構築
- Readerはリージョンを跨いだ投機的読み込みを実施
- Hierarchical Data Placement
- データは稼働しているリージョンに一様に配分
- 各リージョン内でラックを考慮した配置を実施
- Ackは過半数のリージョンに書き込みができた場合に返る
- Cross Region Speculative Reads
- Readerが下記の優先度で読み込みを実施
- 1.Clientから近いBookie
- 2.異なるラックでClientから最も近いBookie
- 3.異なるリージョンでClientから最も近いBookie
- Readerが下記の優先度で読み込みを実施
- Region Aware Data Placement
- Consistency
- Performance
- Latency vs Throughput
- 何レコード毎にwriteをするかでレイテンシに大きく影響
- トレードオフのため、システムのニーズに合わせて要調整
- Scalability
- Stream増加に応じて遅延は増大するが、1000Streamsで99.9パーセンタイル160ms程に収まる
- Stream増加に応じてスループットはほぼリニアに拡大する
- Writerに比べてReaderが多い場合に非常に効果的
- Latency vs Throughput
- Scale @Twitter
- Use Cases
- Manhattan KVS
- 繰り返されるRPC
- リアルタイム検索インデクシング
- 自前のPubSub Systemを用いたStream処理
- DCを跨いだレプリケーション
- Scale
- Global Clusterは1個、DC毎に数個のCluster
- O(10^3) Bookie Nodes
- O(10^3) Global Log Streams and O(10^4) Local Log Streams
- O(10^6) Live log segments
- データ種別ごとに保持期間は数時間~年単位
- PubSub流量
- O(1) trillion records per day
- O(10) PB per day
- Use Cases
- 学んだこと
- 基盤は耐久性と一貫性が重要
- Filesystemを信用するな
- ワークロードを考慮し、IOを隔離する
- 保持する状態は極力シンプルに保つ
- DistributedLog is the new messaging foundation
- Layered Architecture
- StatelessなServingレイヤ
- StatefulなStoreageレイヤ
- CPU/Memory/NetworkをMesosで共有、独立したストレージレイヤを持つ(hybrid mesos)
- Messge Driven
- Write / Read の隔離
- Fan-in と独立した Fan-out機構を保持
- Global Replicated Log
- Layered Architecture
Created
June 13, 2016 09:42
-
-
Save kimutansk/2f02059ca4476f93a5eedfdc6303d51f to your computer and use it in GitHub Desktop.
Building Durable Real-time Data Pipeline:Apache BookKeeper at Twitter
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment