Slide 1

Slide 1 text

膨大なデータをどうさばく? Java × MQで作るPub/Subアーキテクチャ 信頼性の⾼い⼤量データ処理システムの構築

Slide 2

Slide 2 text

バッチが朝までに終わらず、 冷や汗をかいたことが ある⽅?

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

自己紹介 - パート1 紹介 ECサイトのバックエンドエンジニアをしています。 業務:SpringBootベースのプロダクトのDevOps 名前  igu (いぐ)

Slide 5

Slide 5 text

自己紹介 - パート2 セッションの背景 以前、散々やった広告のシステムのPub/Subの DevOpsの経験元に⾊々話したい

Slide 6

Slide 6 text

自己紹介 - パート2 セッションの背景 以前、散々やった広告のシステムのPub/Subの DevOpsの経験元に⾊々話したい セッションで話すこと Javaとメッセージキューを使⽤して膨⼤なデータを効率的に 処理するためのPub/Subアーキテクチャの構築と運⽤について解説  ポイント1  「⽌まらない」システム設計の重要性と実現⽅法  ポイント2  システム運⽤で⾒え来る課題と対策  ポイント3  Grafanaを活⽤した監視と可視化の⼿法

Slide 7

Slide 7 text

セッションアジェンダ Pub/Subアーキテクチャの設計‧運⽤に関する6つのセクションです。 1. イントロダクション ⾃⼰紹介とセッションの⽬的、ゴールの説明 2. システム概要とPub/Sub基盤 システム全体の構成、データ特性、Pub/Sub基盤の役割 3. "⽌まらない"を実現する設計 キー設計、並列度、再処理と冪等性など 4. 運⽤の現場で磨いた改善サイクル∕再発防⽌策 監視 → 改善 → 再発防⽌ → 横展開 5. Grafanaによる監視と可視化 相関指標の可視化、ダッシュボード例、メトリクスの選び⽅ 6. まとめ キーポイントの振り返りとクリティカルな話

Slide 8

Slide 8 text

システム概要と Pub/Sub基盤の位置づけ システム概要とPub/Sub基盤の位置づけ

Slide 9

Slide 9 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 パターン1: API連携型 MQ Broker Subscriber External System API Publisher RDB RDB Router

Slide 10

Slide 10 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 パターン1: API連携型 MQ Broker Subscriber External System API Publisher RDB RDB Router ピークを吸収し ⾮同期に届ける 特徴: APIがRDBに書き込み、その結果をPulsarにpublish。Pulsarがピークを吸収し、Consumerへ⾮同期に届ける構造。

Slide 11

Slide 11 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 パターン1: API連携型 MQ Broker Subscriber External System API Publisher RDB RDB Router サービス特徴:API投⼊後から外部システム登録完了までのSALを超過した場合、⼤変な事故が起きる。 ピークを吸収し ⾮同期に届ける 特徴: APIがRDBに書き込み、その結果をPulsarにpublish。Pulsarがピークを吸収し、Consumerへ⾮同期に届ける構造。

Slide 12

Slide 12 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 パターン2: 定期実⾏型 MQ Broker Subscriber External System Cron Publisher RDB RDB Router

Slide 13

Slide 13 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 パターン2: 定期実⾏型 MQ Broker Subscriber External System Cron Publisher RDB RDB Router 特徴: 定期実⾏のCronアプリがRDBからデータを読み込み、Pulsarにメッセージをpublish。複数のConsumerへ配信することで、定時処理を効率的に分散させる仕組み 複数Subscriberに よる並列処理

Slide 14

Slide 14 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 パターン2: 定期実⾏型 MQ Broker Subscriber External System Cron Publisher RDB RDB Router サービス特徴:定時から開始され決められた時間までに全てのイベント処理が完了しない場合、コールセンタに問い合わせがくる。 特徴: 定期実⾏のCronアプリがRDBからデータを読み込み、Pulsarにメッセージをpublish。複数のConsumerへ配信することで、定時処理を効率的に分散させる仕組み 複数Subscriberに よる並列処理

Slide 15

Slide 15 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 パターン3: ハイブリッド型 MQ Broker Subscriber External System API Publisher RDB RDB Cron Publisher Router

Slide 16

Slide 16 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 パターン3: ハイブリッド型 MQ Broker Subscriber External System API Publisher RDB RDB Cron Publisher Router 特徴: APIのピーク吸収もあり、定期実⾏の⼀括並列処理も両⽅の要件に対応する ピークを吸収し ⾮同期に届ける 複数Subscriberに よる並列処理

Slide 17

Slide 17 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 パターン3: ハイブリッド型 MQ Broker Subscriber External System API Publisher RDB RDB Cron Publisher Router 特徴: APIのピーク吸収もあり、定期実⾏の⼀括並列処理も両⽅の要件に対応する サービス特徴:API投⼊後から外部システム登録完了までのSALを超過した場合、⼤変な事故が起きる。       :定時から開始され決められた時間までに全てのイベント処理が完了しない場合、コールセンタに問い合わせがくる。 ピークを吸収し ⾮同期に届ける 複数Subscriberに よる並列処理

Slide 18

Slide 18 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 パターン3: ハイブリッド型 MQ Broker Subscriber External System API Publisher RDB RDB Cron Publisher Router 特徴: APIのピーク吸収もあり、定期実⾏の⼀括並列処理も両⽅の要件に対応する サービス特徴:API投⼊後から外部システム登録完了までのSALを超過した場合、⼤変な事故が起きる。       :定時から開始され決められた時間までに全てのイベント処理が完了しない場合、コールセンタに問い合わせがくる。       :機能要件の特性で冪等性の担保がしづらく、イベント処理が途中失敗数すると、コールセンタに問い合わせがくる。 ピークを吸収し ⾮同期に届ける 複数Subscriberに よる並列処理

Slide 19

Slide 19 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 Router パターン4: メッセージルーティング型 MQ Broker Router Subscriber External System API Publisher RDB RDB MQ Broker Subscriber

Slide 20

Slide 20 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 Router パターン4: メッセージルーティング型 MQ Broker Router Subscriber External System API Publisher RDB RDB MQ Broker Subscriber 特徴: Cronアプリが⽣成したメッセージをRouterが内容に応じて振り分け、軽い処理と重い処理を適切なTopicに分離。処理特性に合わせて最適化された独⽴した Consumerによって効率的に処理される構造。 イベントの特性を⾒て 適切なSubscriberに割 当て、効率的に処理する

Slide 21

Slide 21 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 Router パターン4: メッセージルーティング型 MQ Broker Router Subscriber External System API Publisher RDB RDB MQ Broker Subscriber 特徴: Cronアプリが⽣成したメッセージをRouterが内容に応じて振り分け、軽い処理と重い処理を適切なTopicに分離。処理特性に合わせて最適化された独⽴した Consumerによって効率的に処理される構造。 サービス特徴:定時から開始され決められた時間までに全てのイベント処理が完了しない場合、コールセンタに問い合わせがくる。 イベントの特性を⾒て 適切なSubscriberに割 当て、効率的に処理する

Slide 22

Slide 22 text

シンプルシステム構成図 4つのパターンを簡略化した構成図 パターン2: 定期実⾏型 MQ Broker Subscriber External System Cron Publisher RDB RDB パターン1: API連携型 MQ Broker Subscriber External System API Publisher RDB RDB パターン3: ハイブリッド型 MQ Broker Subscriber External System API Publisher RDB RDB Cron Publisher Router Light Topic パターン4: メッセージルーティング型 MQ Broker Router Subscriber External System API Publisher RDB RDB Router MQ Broker Subscriber イベントの特性を⾒て 適切なSubscriberに割 当て、効率的に処理する ピークを吸収し ⾮同期に届ける 複数Subscriberに よる並列処理 複数Subscriberに よる並列処理 ピークを吸収し ⾮同期に届ける

Slide 23

Slide 23 text

システム全体の特性 Pub/Subアーキテクチャを⽀える基盤の特性 Pub/Sub基盤の位置づけ • システムの各コンポーネント間の疎結合を実現 • ピークトラフィックの吸収 • ⾮同期処理による柔軟性の確保 • 複数のConsumerへの並列配信 扱うデータの特性 • ⼤量のイベントデータ • リアルタイム性が求められる処理 • 複数の後続処理が必要なデータ • ⼀度のみの確実な処理が必要 要求される可⽤性 • ⾼可⽤性(システムを⽌めない) • スケーラビリティ(負荷に応じた拡張) • 耐障害性(部分的な障害でも継続稼働)

Slide 24

Slide 24 text

3. "止まらない "を実現する設計の勘所 ⾼い並列度と順序保証を両⽴するメッセージングパターン

Slide 25

Slide 25 text

セッションアジェンダ Pub/Subアーキテクチャの設計‧運⽤に関する6つのセクションです。 1. キー設計のベストプラクティス Key_Sharedモードとカーディナリティ確保で順序保証と並列処理を両⽴ 2. 適切な並列度の設計 メッセージ量と処理能⼒から必要Consumer数を算出し、バックプ レッシャーで過負荷を防⽌ 3. 再処理と冪等性の実装パターン メッセージIDまたは業務キーで重複処理を防ぎ、NackとDLQでリト ライ制御 4. グレースフルシャットダウンの設計 デプロイ時に処理中メッセージを完了させてから終了し、データ不整合 を防⽌ Page 4/24

Slide 26

Slide 26 text

キー設計 トピックとパーティションの基本概念 トピック メッセージが流れる「チャネル」 メッセージの論理的な分類単位 パーティション トピックを分割した物理的な単位 並列処理の基本単位になる "user-events" トピック パーティション 1 → Consumer 1 パーティション 2 → Consumer 2 パーティション 3 → Consumer 3 キーの役割 メッセージ + キー → hash(key) % パーティション数 → パーティションに配置 • 同じキーを持つメッセージは同⼀パーティションに配置される • キーを指定しなければランダムまたはラウンドロビンで配置 • パーティションごとにメッセージの順序は保証される

Slide 27

Slide 27 text

Key_Sharedモード パーティション1つでも並列処理できる? 従来の考え⽅では、並列度を上げるにはパーティション数を増やす必要がありました。 しかし、 Key_Sharedモード を使うことで、 パーティション1つでも複数Consumerで並列処理 が可能になります。 • パーティション数: 1個(固定) • 並列度の制御: Consumer数で調整 • 順序保証: キーごとに保証 4つのサブスクリプションタイプ タイプ 並列処理 順序保証 ⽤途 Exclusive (1台のみ) 順序重視 Failover (1台アクティブ) ⾼可⽤性 Shared スループット重視 Key_Shared  (キーごと) 両⽴ Key_Sharedモード は 並列処理 と 順序保証 を両⽴させる強⼒な機能です。キーごとに⼀貫した順序を保ちながら、異なるキーのメッセージを並列に処理できます。

Slide 28

Slide 28 text

Key_Sharedの仕組み . value (event) . send (); // ConsumerはKey_Sharedモードで接続 Consumer consumer = client . newConsumer () . topic ( "user-events" ) . subscriptionType ( SubscriptionType. ) . (); 動作イメージ トピック: "user-events" (パーティション: 1つ) Consumer1 user123のメッセージ 順序保証✅ Consumer2 user456のメッセージ 順序保証✅ Consumer3 user789のメッセージ 順序保証✅ 結果: 3台のConsumerが並列処理! パターン⽐較 パーティション1つ + Key_Shared ✅ 利点 • 設計がシンプル • パーティション数調整不要 • Consumer数を⾃由に増減 向いているケース • 中規模メッセージ量 • ⾼いキーカーディナリティ パーティション複数 + Exclusive/Failover ✅ 利点 • 超⼤規模対応 • 地理的データ分散 • 単⼀障害点回避 向いているケース • 超⼤規模メッセージ • 地理分散必要 Key_Sharedモードのメリット シンプルな設計で⾼スループット キーごとの順序保証維持

Slide 29

Slide 29 text

キー設計の 3原則 重要: Key_Sharedモードでは並列度の上限になる 実際の並列度 = min(Consumer数, ユニークキーの数) 良い例: Consumer数: 30台 ユニークキー(ユーザーID): 100,000種類 → 20台が並列処理可能 ✅ 悪い例: Consumer数: 20台 ユニークキー(カテゴリ): 3種類 → 3台のConsumerしか稼働しない ❌ 順序が不要な場合: ランダムキーで最⼤限分散 String key = UUID.randomUUID().toString(); // → 全Consumerに均等分散 → 最大スループット バランスの取れたキー設計 • ⾼カーディナリティ • 必要な順序保証のみ • 均等な負荷分散

Slide 30

Slide 30 text

キー設計の 3原則 重要: Key_Sharedモードでは並列度の上限になる 実際の並列度 = min(Consumer数, ユニークキーの数) 良い例: Consumer数: 30台 ユニークキー(ユーザーID): 100,000種類 → 20台が並列処理可能 ✅ 悪い例: Consumer数: 20台 ユニークキー(カテゴリ): 3種類 → 3台のConsumerしか稼働しない ❌ 順序が不要な場合: ランダムキーで最⼤限分散 String key = UUID.randomUUID().toString(); // → 全Consumerに均等分散 → 最大スループット バランスの取れたキー設計 • ⾼カーディナリティ • 必要な順序保証のみ • 均等な負荷分散 ■個⼈的な⾒解  ①Subscriber(Consumer)へのイベント分配に関しては、キー設計での分配より、   中間のRuter機能を実装するとより柔軟に設計と運⽤ができた   → システム構成のパターン4: メッセージルーティング型  ②最終的には、どのアーキテクチャもSubscriberへのイベント分配は   ランダム(ラウンドロビン)のみとなった。

Slide 31

Slide 31 text

適切な並列度の設計 Consumer数の決定 基本の計算式: 必要なConsumer数 = ピーク時のメッセージ数/秒 ÷ Consumer1台の処 理能力/秒 ※ 余裕を持たせるために、計算結果の1.5倍程度を準備 計算例 • ピーク時: 10,000 msg/s • Consumer 1台: 500 msg/s(実測値) • 必要数: 10,000 ÷ 500 = 20台 • 余裕を持たせて: 20 × 1.5 = 30台 実際の並列度の制約 Consumer数とキーのカーディナリティのうち、⼩さい⽅が実際の並列度の上限となります。 実際の並列度 = min(Consumer数, ユニークキーの数) Consumer1台あたりの処理能⼒の測定 理論値と実測値の差 理論値 1メッセージ100ms → 1秒で10件処理で きるはず 実測値 RDB接続待ち、外部API遅延 → 1秒で3件 しか処理できない ボトルネックの特定 DB コネクションプール増、インデックス最適化 外部API タイムアウト短縮、バルク化 CPU 処理ロジックの最適化 パフォーマンステスト重要ポイント • 本番に近い環境で負荷テストを実施 • 実際のメッセージサイズ‧内容で検証 • ピーク時の1.5倍の負荷を想定 • バックプレッシャーが働くポイントを特定

Slide 32

Slide 32 text

適切な並列度の設計 Consumer数の決定 基本の計算式: 必要なConsumer数 = ピーク時のメッセージ数/秒 ÷ Consumer1台の処 理能力/秒 ※ 余裕を持たせるために、計算結果の1.5倍程度を準備 計算例 • ピーク時: 10,000 msg/s • Consumer 1台: 500 msg/s(実測値) • 必要数: 10,000 ÷ 500 = 20台 • 余裕を持たせて: 20 × 1.5 = 30台 実際の並列度の制約 Consumer数とキーのカーディナリティのうち、⼩さい⽅が実際の並列度の上限となります。 実際の並列度 = min(Consumer数, ユニークキーの数) Consumer1台あたりの処理能⼒の測定 理論値と実測値の差 理論値 1メッセージ100ms → 1秒で10件処理で きるはず 実測値 RDB接続待ち、外部API遅延 → 1秒で3件 しか処理できない ボトルネックの特定 DB コネクションプール増、インデックス最適化 外部API タイムアウト短縮、バルク化 CPU 処理ロジックの最適化 パフォーマンステスト重要ポイント • 本番に近い環境で負荷テストを実施 • 実際のメッセージサイズ‧内容で検証 • ピーク時の1.5倍の負荷を想定 • バックプレッシャーが働くポイントを特定 ■個⼈的な⾒解  ①Consumer(Subscriber)は、適正値を割り出すのは難しく   できればクラウド環境などの柔軟なスケールアップが   できる環境で構築するがことが望ましい

Slide 33

Slide 33 text

Consumerの設定パラメータ

Slide 34

Slide 34 text

Consumerの設定パラメータ ■個⼈的な⾒解  ①プリフェッチサイズを0にすることで、Cosumerの効率的な運⽤ができる

Slide 35

Slide 35 text

再処理と冪等性の実装パターン なぜ冪等性が必要? Pulsarは At-Least-Once(最低1回)配信保証 → 同じメッセージが複数回届く可能性あり パターン1: メッセージIDで管理 @Entity public class ProcessedMessage { @Id private String messageId; // Pulsarのメッセージ ID private Instant processedAt; } // 一意制約違反で重複を検出 processedMessageRepo.save( new ProcessedMessage(messageId, now())); メリット • 確実に重複を防げる • 業務ロジックと分離できる デメリット • DB書き込みが増える • 別テーブルの管理が必要 パターン2: 業務キーでチェック // 業務キー(注文ID)で既存データを確認 Optional existing = orderRepo.findById(order.getOrderId()); if (existing.isPresent() && "COMPLETED".equals(existing.get().getStatus())) { // 既に処理済み → スキップ consumer.acknowledge(msg); return; } メリット • 別テーブル不要 • ⾃然な実装 • 業務データの整合性確保 デメリット • 業務キーが複雑だと難しい • 複合条件判定が必要な場合も メッセージID⽅式のポイント: • • 定期的に古いレコードをクリーンアップ • • ID保持期間は最⼤再送期間の2倍程度に設定 業務キー⽅式のポイント: • • 業務状態を明確に定義(ex. 注⽂ステータス) • • 処理前後でステータスが変わるようにする 冪等性実装のベストプラクティス トランザクション境界 処理とIDの記録を⼀つに ロールバック処理 失敗時の状態復元 DB整合性制約活⽤ ユニーク制約での強制 重要: 冪等性はシステム信頼性の要!確実な実装を⼼がけましょう

Slide 36

Slide 36 text

再処理と冪等性の実装パターン なぜ冪等性が必要? Pulsarは At-Least-Once(最低1回)配信保証 → 同じメッセージが複数回届く可能性あり パターン1: メッセージIDで管理 @Entity public class ProcessedMessage { @Id private String messageId; // Pulsarのメッセージ ID private Instant processedAt; } // 一意制約違反で重複を検出 processedMessageRepo.save( new ProcessedMessage(messageId, now())); メリット • 確実に重複を防げる • 業務ロジックと分離できる デメリット • DB書き込みが増える • 別テーブルの管理が必要 パターン2: 業務キーでチェック // 業務キー(注文ID)で既存データを確認 Optional existing = orderRepo.findById(order.getOrderId()); if (existing.isPresent() && "COMPLETED".equals(existing.get().getStatus())) { // 既に処理済み → スキップ consumer.acknowledge(msg); return; } メリット • 別テーブル不要 • ⾃然な実装 • 業務データの整合性確保 デメリット • 業務キーが複雑だと難しい • 複合条件判定が必要な場合も メッセージID⽅式のポイント: • • 定期的に古いレコードをクリーンアップ • • ID保持期間は最⼤再送期間の2倍程度に設定 業務キー⽅式のポイント: • • 業務状態を明確に定義(ex. 注⽂ステータス) • • 処理前後でステータスが変わるようにする 冪等性実装のベストプラクティス トランザクション境界 処理とIDの記録を⼀つに ロールバック処理 失敗時の状態復元 DB整合性制約活⽤ ユニーク制約での強制 重要: 冪等性はシステム信頼性の要!確実な実装を⼼がけましょう ■個⼈的な⾒解  ①イベントの重複実⾏をさけるため、投⼊前、投⼊中、処理完了(OK or NG)の   3状態が管理ができる望ましい

Slide 37

Slide 37 text

再処理の制御

Slide 38

Slide 38 text

再処理の制御 ■個⼈的な⾒解 ① イベントの状態として、投⼊前、投⼊中、処理完了(OK or NG)があり  更に、イベント単位で再投⼊回数を保持し、ある⼀定のしきい値を超えたら  再投⼊しない仕組みを別DB管理  補⾜  以下サービスは類似機能が実装されている    1. Amazon SQS - 設定が簡単、マネージドサービス   2. RabbitMQ - より細かい制御が可能、オンプレミス対応 ② イベント未処理時間の監視

Slide 39

Slide 39 text

グレースフルシャットダウンの設計 Spring Bootでの実装ポイント

Slide 40

Slide 40 text

Kubernetesでのグレースフルシャットダウン Kubernetes設定の重要点 lifecycle: preStop: exec: command: ["/bin/sh", "-c", "sleep 10"] terminationGracePeriodSeconds: 60 preStop設定の効果 • ロードバランサーからの切り離し待機時間を確保 • サービスエンドポイント削除〜実際の反映のラグをカバー terminationGracePeriod設定 • SIGTERM後、強制終了までの最⼤待機時間 • 設定値 > (処理完了平均時間 + 余裕) を確保 シャットダウンのタイムライン 1 Kubernetesデプロイ開始 2 preStop実⾏(10秒待機) 3 SIGTERM送信 4 新規メッセージ停⽌(consumer.pause()) 5 処理完了待ち(executor.awaitTermination()) 6 終了(リソース解放) 設計のポイント タイムアウト時間 の適切な設定 ⻑時間処理への対策 (定期的なハートビート) メトリクスでの監視 (処理中タスク数、シャットダウン時間) グレースフルシャットダウンで、デプロイ時もメッセージを失わない!

Slide 41

Slide 41 text

Kubernetesでのグレースフルシャットダウン Kubernetes設定の重要点 lifecycle: preStop: exec: command: ["/bin/sh", "-c", "sleep 10"] terminationGracePeriodSeconds: 60 preStop設定の効果 • ロードバランサーからの切り離し待機時間を確保 • サービスエンドポイント削除〜実際の反映のラグをカバー terminationGracePeriod設定 • SIGTERM後、強制終了までの最⼤待機時間 • 設定値 > (処理完了平均時間 + 余裕) を確保 シャットダウンのタイムライン 1 Kubernetesデプロイ開始 2 preStop実⾏(10秒待機) 3 SIGTERM送信 4 新規メッセージ停⽌(consumer.pause()) 5 処理完了待ち(executor.awaitTermination()) 6 終了(リソース解放) 設計のポイント タイムアウト時間 の適切な設定 ⻑時間処理への対策 (定期的なハートビート) メトリクスでの監視 (処理中タスク数、シャットダウン時間) グレースフルシャットダウンで、デプロイ時もメッセージを失わない! ■個⼈的な⾒解  ①記載例の場合、最⼤待ち時間があるため、本当に⻑期実⾏イベントをする   Consumer(Subscriber)の場合、Pod管理(Podの再起動)ができる環境で   やるのが望ましい。  ②実際は、外部からTopic離脱できるAPI機能、イベント完了チェックAPI機能を実装して   それCICDのプロセスからコールして実現

Slide 42

Slide 42 text

まとめ: 設計の勘所 キー設計 Key_Sharedモード ならパーティション1つでも並列処理可能 カーディナリティ確保(ユニークキー数 = 並列度の上限) 順序保証の要件を明確化 ホットキー回避 並列度 Consumer数 = ピーク時メッセージ数 ÷ Consumer1台の処理能⼒ × 余裕 率 実際の並列度 = min(Consumer数, ユニークキー数) 実測でボトルネック特定(DB/外部API/CPU) バックプレッシャーで下流システムを保護 設定パラメータ ReceiverQueueSize: メモリと相談(1000〜5000) MaxConcurrentMessages: I/O待ちに応じて(10〜50) AckTimeout: 実測の2〜3倍 冪等性と再処理 メッセージID、業務キーで重複処理を防ぐ Nack/DLQで再処理を制御 リトライ間隔を適切に設定 グレースフルシャットダウンで安全なイベント処理

Slide 43

Slide 43 text

4. 運用の現場で磨いた 改善サイクル/再発防止策

Slide 44

Slide 44 text

改善サイクルの全体像

Slide 45

Slide 45 text

想定例1: ReceiverQueueSizeの最適化

Slide 46

Slide 46 text

想定例2: BackLog肥大化による Publisher障害

Slide 47

Slide 47 text

再発防止策 : ポストモーテムの作成と共有

Slide 48

Slide 48 text

想定例3: メトリクスから見えたオーバースペック

Slide 49

Slide 49 text

改善サイクルを回すための仕組み

Slide 50

Slide 50 text

改善サイクルを回すための仕組み ■個⼈的な⾒解  ①多少⾯倒ではありますが、こうした作業を少しでも続けていく   Pub/Subモデルの恩恵を段々感じられるます   武器を鍛えているような感じでもあります

Slide 51

Slide 51 text

まとめ: 監視が改善サイクルの起点 監視メトリク ス 分析 対策 効果測定 横展開 監視メトリクスの重要性 異常の早期発⾒ 重要メトリクスで問題発⽣を早期検知 予測と予防 傾向分析で将来の問題を事前対策 インシデントからの学び ポストモーテム⽂化 失敗を組織の学びに変えるBlameless⽂化 教訓のドキュメント化 同じ失敗を繰り返さない組織の記憶を作る 対策の横展開 チェックリスト化 対策を標準ガイドラインとして整備 組織全体での共有 他チーム‧他システムにも改善を適⽤ 継続的な改善 定期的なレビュー ⽉次‧四半期での分析と改善計画の⾒直し 最適なバランス 性能‧コスト‧安定性のバランスを意識 では、具体的にどんなメトリクスをどう監視するのか? 次のセクションでは、Grafanaを⽤いた監視と可視化の実践⼿法を詳しく⾒ていきます。

Slide 52

Slide 52 text

5. Grafanaによる監視と可視化

Slide 53

Slide 53 text

Grafana画面イメージ セクション5:Grafanaによる監視と可視化 Page 34/39

Slide 54

Slide 54 text

監視の基本思想

Slide 55

Slide 55 text

Pulsarダッシュボードの設計

Slide 56

Slide 56 text

MQ(Pulsar)ダッシュボードの実例

Slide 57

Slide 57 text

バックログサイズ監視

Slide 58

Slide 58 text

レンジ違いの2つのグラフのダッシュボード

Slide 59

Slide 59 text

まとめ: 監視ダッシュボード設計の原則

Slide 60

Slide 60 text

6. まとめ

Slide 61

Slide 61 text

"⽌まらない"を実現するための3つの柱 3つの柱が⽀える"⽌まらない"システム 1. 設計 キー設計と並列度の最適化によ り、スケールしながらも順序保証 を実現 2. 運⽤ 監視からの改善サイクルを通じた 継続的な進化と最適化 3. 監視 ⼀⽬で異常がわかるダッシュボー ドによる迅速な問題発⾒ 3つの柱の連携が不可⽋ 設計‧運⽤‧監視が連携することで、真に"⽌まらない"システムを実現できます

Slide 62

Slide 62 text

1. 設計:キー設計と並列度の最適化 効率的な分散処理を実現するための設計ポイント 並列処理と順序保証の両⽴ キーごとに順序を保ちながら並列処理 Consumer数で柔軟にスケーリング 運⽤負荷を⼤幅に軽減 適切なキー設計 実際の並列度 = min(Consumer数, ユニークキー数) ⼗分な種類のキーを確保 ビジネス要件に応じたキー選択 冪等性の実装 メッセージID or 業務キーで重複を防ぐ 失敗メッセージの隔離 Producer キー設計 A B C Consumer Pool

Slide 63

Slide 63 text

2. 運⽤:監視からの改善サイクル 継続的な改善で"⽌まらない"システムを作り上げる 2つの改善トリガー インシデントから学ぶ (事後分析) 発⽣した問題から教訓を得て再発を防⽌ メトリクス監視から気づく (予防) 傾向を分析して問題発⽣前に対処 ポストモーテム⽂化 犯⼈探しではなく、組織全体で学ぶ 失敗は個⼈ではなく、システムの問題として捉える 失敗を共有し、再発防⽌策を横展開 障害事例をドキュメント化して知⾒を蓄積 定期的なメトリクス振り返り キャパシティプランニングとコスト最適化 リソース使⽤状況から適切な設定を⾒極める ボトルネックの早期発⾒ 性能傾向を分析して将来の障害を未然に防ぐ 継続的な改善サイクル 監視 分析 改善

Slide 64

Slide 64 text

3. 監視:⼀⽬で異常がわかるダッシュボード 素早く問題を検知し、効率的に調査できる監視設計 視覚的な異常検知 正常時 背景⾊のまま = 対応不要 異常時 ⾊がつく = 即対応必要 システム特性に応じた監視設計 製品固有の挙動を理解する ⾒えない問題を可視化する 例: バックログ、消費ラグ、処理速度など、各システムの特性に合わせた指 標を監視 情報の階層化 ダッシュボード構成の例 重要メトリクス(常時表⽰) バックログサイズ 消費ラグ エラー件数 詳細メトリクス(デフォルト閉じる) 調査⽤グラフ(デフォルト閉じる) 重要な情報だけ常時表⽰ 詳細はデフォルトで閉じる 効果的なダッシュボードの3要素 視認性 異常が⼀⽬でわかる視覚設計 整理 情報の適切な階層化 連続性 過去の調査ノウハウを活⽤できる仕組み

Slide 65

Slide 65 text

最も重要なメッセージ 「設計」×「運⽤」×「監視」の三位⼀体で、 システムは"⽌まらない"ものになる 設計 キー設計と並列度の最適化 運⽤ 監視からの改善サイクル 監視 ⼀⽬で異常がわかるダッシュボード 継続的な改善サイクル 良い設計 監視で状況把握 運⽤で改善 さらに良いシステムへ サービス品質向上の好循環 設計‧運⽤‧監視の三位⼀体で、⽌まらないだけでなく継続的に進化するシステムを実現できます。

Slide 66

Slide 66 text

実践チェックリスト 以下のチェックリストで、あなたのPub/Sub基盤を評価してみましょう 設計 適切なメッセージ分配により効率的な並列処 理設計がされているか スパイクに耐えられるスケール設計がされている か 冪等性を実装しているか(重複処理を防げる か) 失敗メッセージのリトライ設計がされているか 運⽤ インシデント発⽣時にポストモーテムを作成 しているか 定期的にメトリクスを振り返っているか メトリクス監視から予防的に改善しているか 失敗を隠さず共有できる⽂化があるか 監視 ⼀⽬で異常がわかるダッシュボードになって いるか システム固有の問題を可視化しているか グラフのプライオリティが考慮され、表⽰位置 や表⽰状態(開閉)が考慮されいるか グレースフルシャットダウンが必要

Slide 67

Slide 67 text

最後に Pub/Sub基盤は「設計して終わり」ではありません。 運⽤しながら監視し、改善し続けることで、 本当に"⽌まらない"システムになります。 設計 監視 運⽤ 進化 皆さんのシステムが、安定して稼働し続けることを願っています。

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

参考資料 本セッションの内容は、以下のApache Pulsar公式ドキュメントおよびAPIリファレンスに基づいています。 Apache Pulsar 公式ドキュメント Apache Pulsar 4.1.x Documentation https://pulsar.apache.org/docs/4.1.x/ 主要な参照ドキュメント カテゴリ ドキュメント名 URL 基本概念 Concepts and Architecture https://pulsar.apache.org/docs/4.1.x/c oncepts-overview/ アーキテクチャ Architecture Overview https://pulsar.apache.org/docs/4.1.x/c oncepts-architecture-overview/ メッセージング Messaging Concepts (Key_Shared‧DLQ含む) https://pulsar.apache.org/docs/4.1.x/c oncepts-messaging/ パーティショニング Partitioned Topics https://pulsar.apache.org/docs/4.1.x/c ookbooks-partitioned/ 冪等性 Message Deduplication https://pulsar.apache.org/docs/4.1.x/c ookbooks-deduplication/ Retention‧BackLog Message Retention and Expiry https://pulsar.apache.org/docs/4.1.x/c ookbooks-retention-expiry/ Java Client Java Client Libraries https://pulsar.apache.org/docs/4.1.x/cl ient-libraries-java/ 監視 Monitoring https://pulsar.apache.org/docs/4.1.x/d eploy-monitoring/ メトリクス Metrics Reference https://pulsar.apache.org/docs/4.1.x/r eference-metrics/ Java Client API リファレンス( Javadoc) ConsumerBuilder API Reference (4.1.x) https://pulsar.apache.org/api/client/4.1.x/org/apache/pulsar/client/api/ConsumerBuilder.html ソースコード(最新版) https://github.com/apache/pulsar/blob/master/pulsar-client-api/src/main/java/org/apache/pulsar/clien t/api/ConsumerBuilder.java 主なConsumer設定パラメータ • - プリフェッチキューサイズ • - ACKタイムアウト • - Nack時の再配信遅延 • - DLQポリシー • - サブスクリプションタイプ(Key_Shared含む) 補足資料 Apache Pulsar公式サイト https://pulsar.apache.org/ Apache Pulsarリリースノート https://pulsar.apache.org/release-notes/ Apache Pulsar GitHubリポジトリ https://github.com/apache/pulsar