Jira Data Center でのドキュメントベースのレプリケーション
Jira 8.12.0 以降で導入されたドキュメント ベースのレプリケーション機能は、アプリよるデータのインデックスに時間がかかる場合でも、インデックス時間にアプリが与える影響を軽減し、Jira Data Center でインデックスの不整合が発生するのを防ぎます。DBR 機能をオンにすることで、Jira Data Center を水平方向により拡張できます。その結果、クラスター内のノードが増えたときに、検索の一貫性を維持しながら全体的なスループットを向上させることができます。
DBR の利点
Jira DC クラスターにおけるインデックス更新配布時間を短縮するため、DBR を導入しました。それによって、すぐに以下の結果が得られます。
インデックスの視点: Jira DC におけるノード間のインデックスの一貫性が改善され、より安定し、高速化されます。
ユーザーの視点: インデックスの変更は、ノード間でより速く配布されます。それによって、ノード間のデータの一貫性がより高くなるため、エンド ユーザーの負担が減ります。ユーザーは、効果的にコラボレーションできます。
DBR の考慮事項
導入されたアーキテクチャの変更には、各ノードが他のノードと直接通信する必要があり、それによってネットワーク トラフィックが 2 倍になる可能性があります。継続的なストレス負荷が 1 秒当たりリクエスト 400 件の 8 ノード クラスタでこれをテストすると、総ネットワーク トラフィック量は 1Gbps リンクの総容量の 25% に達しました。負荷またはクラスタ サイズを小さくすると、トラフィックが下がります。
DBR を使用しないときのメトリック (8.12.0 よりも前のバージョン)
グラフは、レプリケーション プロセスで課題の変更を取得して、すべてのノードに伝播するために実行する必要がある操作の数を示します。ジョブは 5 秒毎に実行され、各課題がローカルの Lucene インデックスに登録されるようにします。
青い点はノード間で一貫して複製されている健全なインデックスとデータを示します。点在する色付きの点は、データの不一致につながる表示中のインデックスを示しています。データ インデックスの遅延はゼロまたは最小限に抑えるのが望ましいです。
0ミリ秒のインデックス遅延は、アプリによる課題のインデックスへの影響なしで Jira DC が実行されていることを意味します。問題がない、健全な Jira DC を示します。ドットが高い密度で表示されているのは、レプリケーション ジョブが 5 秒毎にキューを消費し、何も蓄積されていないことを意味します。
Jira DC の悪い状態は、インデックス遅延が 100、200 または 500 ミリ秒の時に出現します。この状態では、テストに使用した 4 ノードの Jira DC は、課題のインデックス時間を 100 ミリ秒以上遅延させる、インストール済みのアプリに対応できません。ドットの間隔が大きくなり、各実行のキャッチアップに 5 秒かかっています。また、キューが徐々に増加し、ジョブが各実行で処理する項目が多くなります。
DBR を使用したときのメトリック (8.12.0+)
DBR をオンにすると "悪い状態" はほとんど完全になくなります。Jira DC では 20 秒のインデックス遅延にも対応できます。つまり、DBR により、アプリによるデータのインデックスに時間がかかる場合でも、一貫性の問題を軽減できます。
テストは、次のセットアップで実行されました。
4 つの Jira DC ノード (c5.9xlarge インスタンスで実行)。
Jira バージョン (8.12.0-SNAPSHOT)
テスト期間: 40 分
負荷: 400 のアクティブな同時ユーザー (10 分で増加後、20 分の間、均一な負荷を適用)
200 万件の課題
ストレス テスト
Jira DC 8.5 を使用した 8 ノード クラスタでのストレス テストの結果、負荷が 1 秒あたり 200 リクエストに達するとインデックスの不一致が大きくなることがわかっています。
Jira DC 8.13 は、インデックスを全体的に一致させたまま、1 秒当たりリクエスト 330 件のフラット負荷を処理できました。これは、Jira DC が高負荷によって引き起こされるインデックスの問題を処理できることを証明しています。
技術的な背景
Jira DC では複製されたインデックス操作 (RIO) データベース テーブルを使用して、インデックスの変更をクラスタ全体で複製します。ユーザーがノードでインデックスを変更するアクション (課題の作成、コメントの追加など) を実行すると、そのノードが送信者ノードとして RIO にエントリを作成します。次に、ほかのノードが 5 秒ごとにリプレイ プロセス (RP) を実行して、RIO テーブルの処理、DB からの課題の読み込み、その課題の Lucene エントリの作成を行います。RP は 1 つのスレッドのすべての変更を取得しようとします。各アクションが最後の実行から 5 秒以内に終了し、作成されたすべての RIO を処理できるかぎり、Jira DC は健全であり、インデックスの一貫性がクラスタ間で保たれます。
ドキュメント ベースのレプリケーション (DBR) は、キャッシュ レプリケーション メカニズムを使用して、送信者ノードで作成された Lucene ドキュメントを別のノードに直接共有します。他のノードは、DB から完全な課題データを読み取ったり、Lucene ドキュメントを準備する (これはリソースを消費します) 必要はありません。これらは、インデックスに送信される内容に適用されます (これはリソースをあまり消費しません)。
RIO/RP メソッドは引き続き存在しますが、これはエンティティのバージョン管理 (以下を参照) を使用して、DBR がすべての作業を完了したかどうかを確認し、DBR で処理していない作業があれば修正しますネットワークで問題が発生した場合、フォールバック メソッドとしても使用されます。
DBR では、変更される課題の数にかかわらず、インデックス作成による遅延が各ノードで 10 ~ 100 ミリ秒になるようにします。
エンティティのバージョン管理
インデックスの一貫性を維持するため、エンティティのバージョン管理を導入しました。エンティティのバージョン管理を使用すると、課題の各更新も、変更ごとに増加するバージョンの追加の影響を受けます。1 つの課題は、DB およびインデックス内の数字と関連付けられます。最新バージョン (バージョン番号が最高のもの) が、インデックス内に存在するものと想定されます。これにより、クラスタのバージョンの不一致 (例: 同時に発生した課題ステータスが変更) を防ぎ、データベースとノードとの間で一貫性を確保します。
DBR を使用したアクション
DBR メカニズムは通常、再インデックスをトリガーするユーザー アクションに適用されます。
DBR を使用したアクション | DBR を使用しないアクション |
---|---|
バックグラウンドでの再インデックス | フォアグラウンドでの完全な再インデックス |
プロジェクトアーカイブ | 課題のアーカイブ |
ノード起動時の再インデックス |
ログの DBR
DBR アクションに関するさらなるデータを見つけ、クラスタの挙動を監視するには、 atlassian-jira.log
ファイルでログを参照します。
標準の atlassian-jira.log には、特定のノードの DBR プロパティを示す DBR 関連の集約ログがあります。すべての DBR ログの先頭には [DBR]
が付いています。
DBR Sender 統計ログ
DBR sender ログは、Lucene (ドキュメント) 付きの DBR メッセージの準備を担当する部分を記述し、次のフォーマットを持ちます。
[DBR] [SENDER] snpapshot stats...
[DBR] [SENDER] total stats...
スナップショット統計は直近の ~5 分、合計の統計はノード開始からの時間を網羅します。
最も重要な統計は次のとおりです。
createDBRMessageUpdateInMillis / createDBRMessageUpdateWithRelatedInMillis
- DBR メッセージを作成する時間。これは非同期で行われ、ローカル インデックスで変更を生成するリクエスト スレッドではありません。createDBRMessageUpdateBytes / createDBRMessageUpdateWithRelatedBytes
- DBR メッセージのサイズsendDBRMessage
- トランスポート層 (宛先ノードではない) に正常に配信された DBR メッセージの数。これはインデックス更新の数と等しくなる必要があります。1 つの DBR メッセージには、1 つの課題と、いくつかのエンティティまたは関連するすべてのエンティティ (コメント、作業ログ、変更履歴) が含まれる場合があります。sendDBRMessageErrors
-トランスポート層に配信されなかった DBR メッセージの数。
DBR Receiver 統計ログ
DBR の受信者ログは、ほかのノードからの Lucene ドキュメントが添付された DBR メッセージの受信を担当する部分を説明し、次の形式となっています。
[DBR] [RECEIVER] snapshot stats...
[DBR] [RECEIVER] total stats...
スナップショット統計は直近の ~5 分、合計の統計はノード開始からの時間を網羅します。
最も重要な統計は次のとおりです。
receiveDBRMessage
- 受信した DBR メッセージの数receiveDBRMessageDelayedInMillis
- ソース ノード上での DBR メッセージの作成と、宛先ノード上での DBR メッセージの受け入れとの間の遅延。これは、2 つの異なるノードでのローカル時間の比較に基づきます。processDBRMessageUpdateSerializeInMillis / processDBRMessageUpdateWithRelatedSerializeInMillis
- DBR メッセージをローカルで処理するための時間の一部 - DBR メッセージから Lucene ドキュメントを逆シリアル化する時間。processDBRMessageUpdateIndexInMillis / processDBRMessageUpdateWithRelatedIndexInMillis
- DBR メッセージをローカルで処理するための時間の一部 - DBR メッセージのドキュメントを使用して、ローカル インデックスの条件付き更新を実行するのにかかる時間。
Cache Replication 統計ログ
これらは DBR 機能に固有ではありませんが、値でレプリケートされたすべてのリモート キャッシュの統計を含み、次の形式を持ちます。
[LOCALQ] [VIA-INVALIDATION] Cache replication queue stats per node: ... snapshot stats ...
[LOCALQ] [VIA-INVALIDATION] Cache replication queue stats per node: ... total stats ...
スナップショット統計は直近の ~5 分、合計の統計はノード開始からの時間を網羅します。
最も重要な統計は次のとおりです。
timeToAddMillis
- キャッシュ レプリケーション メッセージを他のノードに送信する前に、ローカル ストアに保存するのにかかる時間sendCounter
- 現在のノードから宛先ノードに送信されたキャッシュ レプリケーション メッセージの数timeToSendMillis
- 現在のノードから宛先ノードにキャッシュ レプリケーション メッセージを送信するのにかかる時間
ノード インデックス リプレイ統計ログ
ノード インデックス リプレイは、他のノードからのインデックス操作のリプレイに関するプロセスです。Jira 8.12 では、リプレイは条件付きで行われます。リプレイ対象のインデックス操作が DBR によってすでに提供されている場合、再インデックス プロセスはスキップされます。これは、DBR の有効性を測定するために使用できます。すべてのインデックス複製操作がスキップされる場合、すべてのインデックス アップデートが DBR 経由でクラスタ全体に伝播されたことを意味します (DBR の有効性 100%)。
ログは次の形式を持ちます。
[INDEX-REPLAY] [STATS] Node replay index operations stats (total)...
[INDEX-REPLAY] [STATS] Node replay index operations stats (snapshot)...
スナップショット統計は直近の ~5 分、合計の統計はノード開始からの時間を網羅します。
最も重要な統計は次のとおりです。
numberOfRemoteOperations
- 他のノードで処理されたインデックス操作の数numberOfLocalOperations
- 現在のノードから処理されたインデックス操作の数timeInMillis
- インデックス操作のバッチを処理するのにかかる時間。リプレイ プロセスは 5 秒毎に実行され、timeInMillis
は 5 秒よりも大幅に小さくする必要があります。filterOutAlreadyIndexedBeforeCounter
- ローカルで処理されるインデックス リプレイ操作の数filterOutAlreadyIndexedAfterCounter
- ローカルで処理されるインデックス リプレイ操作の数。filterOutAlreadyIndexedAfterCounter
= 0 の場合、DBR の有効性が 100% になります。