パフォーマンス・チューニング
- MongoDB の設定
- データベース・インデックス
- 書き込み確認
- MongoDB ドライバ・パフォーマンス・カウンタ
- 通知モードとパフォーマンス
- フロー制御メカニズムの更新
- ペイロードとメッセージのサイズとパフォーマンス
- HTTP サーバのチューニング
- Orion スレッド・モデルとその意味
- ファイル・ディスクリプタのサイジング
- semWait 統計を見るボトルネックの特定
- ログによるパフォーマンスへの影響
- メトリクスによるパフォーマンスへの影響
- ミューテックス・ポリシーによるパフォーマンスへの影響
- 発信 HTTP 接続のタイムアウト
- サブスクリプション・キャッシュ
- ジオ・サブスクリプションのパフォーマンスに関する考慮事項
MongoDB の設定
パフォーマンスの観点から、特に Update-Intensive シナリオでは、WireTiger で MongoDB 4.4 を使用することをお勧めします。
さらに、パフォーマンスに影響を与える可能性があるため、公式の MongoDB のドキュメントから次の情報を考慮してください :
- システムの ulimit 設定が正常であることを確認してください。MongoDB は、このドキュメントで説明されているように、以下の推奨を提供しています。 RHEL/CentOS では、ソフト/ハード・プロセス制限を少なくとも32000に設定するには、
/etc/security/limits.d/99-mongodb-nproc.conf
ファイルを作成する必要があります (引用文献の詳細を確認してください)。 - また、パフォーマンスを向上させるために、このドキュメントの説明に従い、透過的な巨大ページ (HTP) を無効にする必要があります。
データベース・インデックス
Orion Context Broker は、データベース管理者に柔軟性を提供するために、このセクションの最後で説明されている2つの例外を除いて、任意のデータベースコレクションにインデックスを作成しません。インデックスの使用には、読取り効率 (インデックスの使用率は一般的に読取り速度を向上させる) と書込み効率 (インデックスの使用量が書込みを遅くする) と記憶域 (インデックスはデータベースおよびマップ RAM メモリーのスペースを消費する) の間のトレードオフがあります。管理者 (Orion ではなく) が優先順位を決定する必要があります。
ただし、このタスクの管理者を支援するために、次の一般的な (general) インデックスを推奨します。これらは、読み取りおよび書き込みのパフォーマンスを向上させます:
- エンティティのコレクション
{_id.servicePath: 1, _id.id: 1, _id.type: 1}
(これは複合インデックスであり、この場合のキー順は重要です)creDate
_id.id
_id.type
_id.servicePath
attrNames
さらに、クエリによっては 追加 インデックスが必要になるかもしれません。
-
クエリで属性フィルタを使用する場合 (例えば
GET /v2/entities?q=A<10
)、それらに対して、インデックスを作成することをお勧めします。特に、与えられた属性 'A' でフィルタリングしているのなら、インデックス{attrs.A.value: 1}
を作成するべきです。同じクエリの中で複数の属性でフィルタリングしている場合 (例えばGET /v2/entities?q=A<10;B>20
)、それらすべてを複合インデックス{attrs.A.value: 1, attrs.B.value: 1}
にまとめてください。(この場合、キーの順序は関係ありません) -
orderBy
クエリ (つまりGET /v2/entities?orderBy=A
) を使用する場合、それらのインデックスを 作成することをお勧めします。特に、指定された属性 'A' によって昇順 (つまりorderBy=A
) に 並べ替える場合は、インデックス{attrs.A.value: 1}
を作成する必要があります。指定された属性 'A' を 降順で並べ替える場合 (つまり、orderBy=!A
)、インデックス{attrs.A.value: -1}
を作成する必要があります。順序付けに複数の属性を使用する場合 (つまりorderBy=A,!B,C
)、順序付けの方向を考慮して複合インデックスを作成する必要があります。つまり{attrs.A.value: 1, attrs.B.value: -1, attrs.C.value: 1}
(この場合、キーの順序は重要です) -
フィルタが
dateCreate
またはdateModified
の場合、上記の規則は少し修正されています。エンティティの作成/修正日 (たとえばGET /v2/entities?dateModified<2019-01-01
) の場合、attrs.A.value
の代わりにcreDate
とmodDate
を使用してください。属性の作成/修正日 (たとえばGET /v2/entities?mq=A.dateModified<2019-01-01
) の場合、attrs.A.value
の代わりにattrs.A.creDate
とattrs.A.modDate
を使用してください
Orion Context Broker が実際に保証している唯一のインデックスは以下のものです。どちらも Orion の起動時またはエンティティの作成時に保証されます。
- ジオロケーション機能の機能的な必要性のために、エンティティ・コレクション内にある
location.coords
フィールドの "2dsphere" インデックス - 一時的なエンティティ機能の機能的な必要性のために、エンティティ・コレクション内にある
expDate
フィールドにexpireAfterSeconds: 0
を持つインデックス
このドキュメントでは、古い Orion バージョンをベースにしていますが、インデックスの影響についての分析を見つけることができますが、古くなった可能性があります。さらに、MongoDB の公式ドキュメントから、複合インデックス および インデックスを使用した結果の並べ替え に関する有用な参考文献を見つけてください。
書き込み確認
書き込み確認 (Write concern) は、MongoDB の書き込み操作のパラメータです。デフォルトでは、Orion は MongoDB がオペレーションをメモリに適用したことを Orion が確認するまで待機することを意味する "承認された" 書き込み確認を使用します。この動作は、-writeConcern
CLI オプションで変更できます。"承認されていない" 書き込み確認が設定されている場合、Orion は確認を待つことがないため、書き込み操作をはるかに高速に実行できます。
ただし、パフォーマンスと信頼性にはトレードオフがあります。"承認されていない" 書き込み確認を使用するとパフォーマンスは向上しますが、情報を失うリスクは高くなります (Orion は書込み操作が成功したという確認を得られません)。
MongoDB ドライバ・パフォーマンス・カウンタ
Orion で使用される MongoDB ドライバには、DB に関連するいくつかのパフォーマンス・カウンタを 取得できる優れた機能があります。
この機能を使用するには、ドライバに付属の mongoc-stat
ツールが必要です。そのため、
このドキュメントで説明されている手順に従ってドライバをインストールする
必要があります。
"contextBroker" プロセスの PID を取得します, 例:
ps ax | grep contextBroker
次に、その PID をパラメータとして使用して mongoc-stat
ツールを実行します, 例:
mongoc-stat <contextBroker PID>
Context Broker の起動時に MONGOC_DISABLE_SHM=true
を使用して、パフォーマンス・カウンタの生成を無効に
することができます。
使用可能なカウンタとこの機能の一般的な詳細については、 ドライバの公式ドキュメント を参照してください。
通知モードとパフォーマンス
Orion は、-notificationMode
値に応じて異なる通知モードを使用できます。
デフォルトモードは '一時的 (transient)' です。このモードでは、通知が送信されるたびに通知を処理するための新しいスレッドが作成されます。通知が送信され、レスポンスが受信されると、その接続コンテキストを持つスレッドは破棄されます。これは、負荷の低いシナリオで推奨されるモードです。高い水準の場合、スレッド枯渇問題が発生する可能性があります。
持続的モード (Persistent mode) は、接続コンテキストが最後に破棄されない点を除いて同様です。したがって、同じ接続コンテキスト (つまり、同じ宛先 URL) に関連付けられた新しい通知は、接続を再利用して HTTP 接続時間 (つまり TCP ハンドシェイクなど) を保存できます。もちろん、これはサーバ、つまり通知を受け取るコンポーネントも接続を開いたままにする必要があります。場合によっては、HTTP 接続の作成と破棄に必要な時間が節約されるため、持続的モードでパフォーマンスが向上する可能性があります。それ以外の場合は、同じ接続コンテキストに関連付けられた通知を待たなければなりません (そのうちの1つだけが一度に接続を使用できます)。つまり、一度に1つの通知スレッドだけが接続を使用できます。したがって、通知リクエスト/レスポンス送信時間が通知間トリガ時間を超えた場合、スレッドはブロックされます。この状況は、統計情報の connectionContext
値が異常に高い時、この状況が検出されます。
最後に、スレッド・プールのモードは、下図に示すように、通知のキューと、キューからの通知を受け取り、実際にワイヤで送信するワーカースレッドのプールに基づいています。これは、待ち行列の長さとワーカー数を注意深く調整した後、高負荷シナリオで推奨されるモードです。良い出発点は、更新を送信する予定の同時クライアントの数にワーカーの数を設定し、ワーカーの数の N 倍のキュー制限を設定することです (N は10に等しくなりますが、期待される更新バースト長に依存する可能性があります)。notifQueue
ブロックの統計は、調整するのに役立ちます。
(実験的機能) サービスごとに予約済みのキュー/プールを設定することもできます。これは、負荷の高いサービスの 通知によって他のサービスの通知が枯渇する可能性があることを回避したい場合に非常に便利です。この場合、 スレッド・プール・モードに定義されたキュー (q) とワーカーのプール (n) がデフォルトです (したがって、予約済みキューのないサービスはそれを使用します)。ただし、さらに、次の構文でサービスごとに追加の キュー/プールを定義できます:
-notificationMode threadpool:q:n,service1:q1:n1,...,serviceN:qN:nN
たとえば、次の設定を検討してください:
-notificationMode threadpool:q:n,serv1:q1:n1,serv2:q2:n2
次のように動作します:
- サービス
serv1
に関連付けられた通知 (つまり、fiware-service: serv1
ヘッダを使用する更新リクエストに よってトリガーされる通知) は、キュー q1 とワーカー・プール n1 を使用します - サービス
serv2
に関連付けられた通知は、キュー q2 とワーカー・プール n2 を使用します - その他の通知 (つまり、
serv1
またはserv2
に関連付けられていない通知は、キュー q とワーカー・プール n を使用します。
したがって、たとえば serv1
に通知の負荷ピークがある場合、そのサービスの通知は破棄されます
(ログに Runtime Error (serv1 notification queue is full)
エラーが表示されます) が、そのキューの飽和は
他のサービスに悪影響を及ぼしません。
動作中のサービスごとの予約済みキュー/プールの詳細な例は このドキュメント にあります。
フロー制御メカニズムの更新
Orion は、クライアントから送信された更新フローを遅くするフロー制御メカニズムを実装しています。 Orion は、フロー制御を使用して、更新要求にすぐに応答するのではなく、更新によってトリガーされた通知 が送信されたとき (フロー制御構成に応じて全体的または部分的に) に応答します。 このようにして、 通知キューに大量の通知が蓄積されることによる Orion の飽和を回避します (最終的に、キューがいっぱい になると通知が破棄されます)。
フロー制御メカニズムは、3つのパラメータを取る -notifFlowControl
を使用して構成されます :
-notifFlowControl gauge:stepDelay:maxInterval
(その意味と使用方法については以下で説明します)。
スレッド・プール通知モードが必要です (つまり、-notificationMode
は threadpool
でなければ
なりません)。
フロー制御は、flowControl
オプションを使用する更新に適用されます。たとえば、
POST /v2/op/update?options=flowControl
です。その場合、Orion は更新にすぐに応答せず、
次のように機能するフロー制御メカニズムを適用します :
1. ターゲット・キュのサイズが計算されます。この計算は、次の式に基づいています :
target = q0 + (1 - gauge) * notifSent
、ここで、q0
は更新の処理を開始する前の通知キュー
のサイズで、gauge
は起動時に Orion に対してグローバルに定義された0〜1の値で、notifSent
は、更新によってトリガーされ、通知キューに追加される通知です。これらの特別な場合に注意して
ください :
* ゲージが1 (積極的なフロー制御) の場合、target = q0
。 つまり、ターゲットは、更新の処理を
開始する前に、キューと同じサイズを取得することです。これは、ゲージの推奨構成です
* ゲージが0 (許容フロー制御) の場合、target = q0 + notifSent
。つまり、ターゲットは、更新
の処理を開始する前のキューと同じサイズであるということです。同時更新が発生しない場合、
これはフロー制御メカニズムが開始前であってもターゲットに到達したことを意味します
2. フロー制御はいくつかのパスで行われます。各パスで、現在の通知キュー (現在の更新により増加し、
スレッドプール・ワーカーが通知を送信することにより減少する) が評価されるため、
* 現在の通知キューがターゲット以下の場合、フロー制御メカニズムが制御を返し、更新レスポンス
が最終的に送信されます
* 現在の通知キューがターゲットよりも大きい場合、フロー制御メカニズムはしばらく待機し
(stepDelay
パラメータ) 、新しいパスを実行します
3. あまり待たないために (最終的にはクライアントがタイムアウト接続を閉じる可能性があります)、
maxInterval
パラメータがあります。これはクライアントの絶対待機時間を指定するため、特定の
パスで maxInternval
時間に達すると、ターゲットに到達したかどうかに関係なく、フロー制御
メカニズムが制御を返します
フロー制御は、これら2つの場合に特に興味深い :
* バッチ更新 (POST /v2/update
)。複数の個別のエンティティ更新が含まれる場合があり、各更新には
潜在的に複数の通知が含まれます
* 1回の更新で複数の通知が発生するため、1:N サブスクリプション関係のエンティティ (同じ
エンティティの N サブスクリプション)での更新 (バッチまたは定期)。特にNが大きい場合
動作中のフロー制御の詳細な例は
このドキュメント.
にあります。
なお、サービス別予約キュー/プールを利用する場合、フロー 制御に使用するキューはサービスに対応したキュー (または、サービスに予約済みキューがない場合は デフォルトのキュー) です。
ペイロードとメッセージのサイズとパフォーマンス
Orion Context Broker は、ペイロードと HTTP メッセージ・サイズに関連する 2つのデフォルト制限を使用します。特に :
- 着信 HTTP リクエストのペイロードには1MBのデフォルト制限があります
- 送信 HTTP リクエスト・メッセージ (HTTP リクエスト・ライン, ヘッダ, ペイロードを含む にはデフォルトで8MBの制限があります。これは通知と転送リクエストに適用されます
ほとんどのユースケースではこの制限で十分であり、同時に、大きすぎる要求によるサービス拒否を 回避することができます。次の CLI フラグ を使用してこれらの制限を変更できます :
-inReqPayloadMaxSize
(バイト) で、着信 HTTP リクエストのペイロードの制限を変更します-outReqMsgMaxSize
(in bytes)で、HTTP リクエスト・メッセージの送信制限を変更します
制限を減らすとパフォーマンスに良い影響を与える可能性がありますが、Context Broker リクエストに制限を課すことがあります。制限値を大きくするとパフォーマンスに悪影響が 出る可能性がありますが、より大きなリクエストが可能になります。 一般に、デフォルトを変更することはお勧めできません。
HTTP サーバのチューニング
Orion が実装する REST API は、デフォルトでポート1026をリッスンする HTTP サーバによって提供されます (これは、-port
CLI パラメーターによってオーバーライドできます)。次の CLI パラメータを使用して動作を調整できます (対応するドキュメントの詳細を参照) :
-
connectionMemory : HTTP サーバ・ライブラリーが内部的に使用する接続ごとの接続メモリー・バッファーのサイズ (KB 単位) を設定します。デフォルト値は64 KB です
-
maxConnections : 同時接続の最大数です。デフォルト値は1020であり、下限は1で上限はありません (オペレーティング・システムのファイル・ディスクリプタの最大数によって制限されます)
-
reqPoolSize : 着信接続のスレッド・プールのサイズです。デフォルト値は0です。つまり、スレッド・プールがまったくないことを意味します。つまり、新しいスレッドが作成され、新しい HTTP リクエストを管理し、使用後に破棄されます。スレッド・プールのモードでは
epoll()
システムコールが内部的に使用されます。これは、スレッド・プールが使用されていないときに使用されるシステムコールよりも効率的です (poll()
)。これに関するいくつかのパフォーマンス情報は、HTTP サーバ・ライブラリー自体の資料に記載されています -
reqTimeout : 接続が閉じられるまでの無活動タイムアウト値 (秒単位) です。デフォルト値は0秒で、無限大を意味します。これは推奨される動作であり、無限のタイムアウトに設定すると、要求を完了する前に Orion が接続を閉じる可能性があります (たとえば、複数の CPr 転送を含むクエリ要求に長時間かかる可能性があります)。サーバ (Orion) の観点から見ると、この場合、接続を閉じることを決定したクライアントである必要があるという点で、"HTTP-unpolite" 動作と考えることができます。ただし、このパラメータはサーバ側 (Orion) でのリソース消費を制限するために使用できます。注意して使用してください
スレッドの作成と破壊はコストのかかる操作であるため、負荷の高いシナリオで -reqPoolSize
を使用することをお勧めします。特に、MHD のフィードバックによれば、プールは、利用可能な CPU コアの数に等しいかまたは近い数のサイズでサイズ調整する必要があります。-reqPoolSize
に CPU コアの数よりも大きな値を設定すると、ほとんどの場合パフォーマンスが低下します。
他の3つのパラメータ (-reqTimeout
, -maxConnections
および -connectionMemory
) は、通常、デフォルト値で正常に動作します。
Orion スレッド・モデルとその意味
Orion はマルチスレッド・プロセスです。デフォルトの起動パラメータとアイドル状態 (つまり無負荷) では、Orion は4つのスレッドを消費します :
- メインスレッド (broker を起動してから、MQTT 接続の経過時間チェックなどの定期的なプロセスを実行するスレッド)
- サブスクリプション・キャッシュ同期スレッド (
-noCache
が使用されている場合は、このスレッドは作成されません) - IPv4 サーバのリスニング・スレッド (
-ipv6
使用されている場合、このスレッドは作成されません) - IPv6 サーバのリスニング・スレッド (
-ipv4
使用されている場合は、このスレッドは作成されません)
-logSummary
が使用されている場合、ログ・サマリ・トレース を印刷するための追加のスレッドが作成されます。
ビジー状態では、スレッド数が多くなります。デフォルト設定では、着信要求ごとおよび発信通知ごとに新しいスレッドが作成されます。これらのスレッドは、作業が完了すると破棄されます。
低負荷から中負荷のシナリオでは、デフォルトの設定で問題ありません。高負荷のシナリオでは、多数の同時要求と通知があるため、スレッド数がプロセスごとのオペレーティング・システムのレベルに達する可能性があります。これはスレッドの枯渇の問題として知られており、Orion は正常に動作せず、新しい着信要求と発信通知を処理できません。その状況を2つの症状で検出することができます。
- まず、プロセスに関連付けられたスレッドの数が、プロセスごとのオペレーティング・システムの制限に非常に近い
- 次に、ログに次のようなエラーメッセージが表示されます :
Runtime Error (error creating thread: ...)
この問題を回避するために、Orion はスレッド・プールをサポートしています。スレッド・プールを使用すると、Orion プロセスが使用するスレッドの数を静的に設定し、スレッドの作成/破壊のダイナミクスを削除し、スレッドの枯渇の問題を回避できます。つまり、プールは、Orion プロセスがプロセスごとのオペレーティング・システムのスレッド制限を超えないことを保証する方法として、Orion の動作をより予測可能にします。
独立して設定できる2つのプールがあります :
- 着信要求プール。
-reqPoolSize c
パラメータによって設定されます。c
は、このプール内のスレッド数です。詳細については、このページの HTTP サーバのチューニングを参照してください - 通知プール。
-notificationMode threadpool:q:n
で設定されます。n
はこのプール内のスレッド数です。 通知モードとパフォーマンスのセクションを参照してください。サービスごとの 予約済みキュー/プールを使用する場合、n
はすべてのサービスごとのプール内のスレッドとデフォルト・プール内の スレッドの合計であることに注意してください。
アイドル状態またはビジー状態のいずれの状況でも、両方のパラメータを使用すると、Orion は一定数のスレッドを消費します :
- メインスレッド (broker を起動してから、MQTT 接続の経過時間チェックなどの定期的なプロセスを実行するスレッド)
- サブスクリプション・キャッシュ同期スレッド (
-noCache
が使用されている場合は、このスレッドは作成されません) c
は IPv4 サーバのリスニング・スレッド (-ipv6
が使用されている場合、これらのスレッドは作成されません)c
は IPv6 サーバのリスニング・スレッド (-ipv4
が使用されている場合、これらのスレッドは作成されません)n
は通知スレッド・プール内のワーカーに対応するスレッド
-logSummary
が使用されている場合、ログ・サマリ・トレース を印刷するための追加のスレッドが作成されます。
スレッドの枯渇問題を避けることとは別に、スレッド・プールを使用するかどうかのトレードオフがあります。スレッド・プールの使用は、スレッドの作成/破壊時間を節約するので有益です。一方、スレッド・プールを設定することはスループットを "キャッピング (capping)" する方法です。スレッド・ワーカーが常にビジー状態になっていると、最後にキューが飽和して、進行中の通知が失われてしまいます。
ファイル・ディスクリプタのサイジング
次の不等式は、Orion によって使用されるファイル・ディスクリプタの数がオペレーティング・システムの制限を下回ることを保証します :
max fds > 5 * n + max cons + db pool size + extra
ここで
- max fds は、プロセスごとのファイル・ディスクリプタの制限です。つまり
ulimit -n
コマンドの出力です。それはulimit -n <new limit>
で変更することができます - n は、通知スレッド・プール内のスレッド数です。ファクター5は、各スレッドが最大5つの接続(libcurl pool)を保持できることに起因します
- max cons は、着信接続用のスレッド・プールのサイズで、
-reqPoolSize
CLI パラメータで設定されます。このパラメータを使用しない場合、デフォルトでは着信接続にプールが使用されないことに注意してください。したがって、十分に大きな入力接続のバーストは、理論上はすべての利用可能なファイル・ディスクリプタを使い果たす可能性があります - db pool size は、
-dbPoolSize
CLI パラメータを使用して設定された DB 接続プールのサイズで、デフォルト値は10です - extra は、ライブラリによって使用されるログ・ファイル、リスニングソケット、およびファイル・ディスクリプタによって使用されるファイル・ディスクリプタの数です。この値には一般的なルールはありませんが、100から200の範囲で1つのケースで十分です
上記の不等式が成り立たない場合、ファイル・ディスクリプタが枯渇 し、Orion Context Broker が正しく機能しなくなる可能性があります。特に、Orion がファイル・ディスクリプタの不足により新しい着信接続を受け入れることや通知を送信できないことがあります。
Orion で多数のクライアント接続を CLOSE_WAIT 状態にすることは問題ではないことに注意してください。これは、接続を再利用して時間を節約するために、libcurl 接続キャッシュ戦略の一部です。このトピックに関する libcurl の電子メールの議論から :
CLOSE_WAIT ソケットはおそらく、libcurl が接続キャッシュに持っているが、すでに libcurl によってサーバによって "閉じられている" (FIN が送信された) ものです。接続キャッシュにはサイズが限られているため、最終的に古い接続が閉じられるため、"無期限に" (実際には接続できません) というわけではありません。
semWait 統計情報によるボトルネックの特定
統計情報オペレーション出力の semWait セクションには、潜在的なボトルネックを検出するために使用できる貴重な情報が含まれています。
-
connectionContext : このメトリックの値が異常に高いのは、多くの通知で同じ永続的な接続を使用したいことが原因である可能性があります。その場合は、永続通知モードの使用を停止し、代わりに一時的またはスレッド・プールを使用します (永続通知モードを使用しない場合は、このメトリックの値は常に0です)
-
dbConnectionPool : Orion は DB 接続プールを保持しています (このサイズは
-dbPoolSize
で確立されています)。このメトリックが異常に高い値をとることは、Orion スレッドがプールからの接続を取得するのに多すぎることを意味します。これは、プールのサイズが不十分である (その場合は-dbPoolSize
値を増やす) か、DB に他のボトルネックがあることが原因です (その場合は、DB の設定と構成を確認してください) -
request : このメトリックの値が異常に高い場合は、要求を処理する内部ロジック・モジュールに入る前にスレッドが多すぎる時間待機することを意味します。その場合、"none" ポリシーを使用することを検討してください ("none" ポリシーが使用されている場合、このメトリックの値は常に0です)。mutex ポリシーに関するセクション を見てください
その他のメトリック (timeStat, transaction, subcache) は、内部の低レベルセマフォ用です。これらのメトリックは、主に Orion 開発者向けで、コード内のバグを識別するのに役立ちます。これらの価値はあまり高くありません。
ログによるパフォーマンスへの影響
ログはパフォーマンスに重大な影響を与えます。したがって、高レベルのシナリオでは、-logLevel
ERROR または WARN を使用することをお勧めします。いくつかの状況で、-logLevel WARN
と -logLevel INFO
間の節約は、パフォーマンスが約50%になる可能性があることを発見しました。
メトリクスによるパフォーマンスへの影響
システムコールとセマフォが関係しているため、メトリックの測定値はパフォーマンスに影響を与える可能性があります。-disableMetrics
CLI パラメータを使用して、この機能を無効にすることができます (パフォーマンスが向上します)。
ミューテックス・ポリシーによるパフォーマンスへの影響
Orion は4種類のポリシーをサポートしています (-reqMutexPolicy
で設定可能) :
-
"all" は、同時に複数の要求が内部ロジックモジュールによって処理されていないことを保証します
-
"read" は、特定の CB ノードにおいて、同時に複数の読み出し要求が内部論理モジュールによって処理されていることを確実にします。書き込み要求は同時に実行することができます
-
"write" は、特定の CB ノードにおいて、同時に2つ以上の書込み要求が内部論理モジュールによって処理されていないことを確実にします。読取り要求が同時に実行できます
-
"none" は、すべての要求を同時に実行できます
デフォルト値は "all" です。これは、主にレガシーな理由 (競合状態の問題が発生する可能性のある時間の残り) に起因します。しかし、当面は "none" を安全に使用することができ、パフォーマンスが向上します (内部ロジックモジュールのエントリで他のスレッドを待つスレッドがブロックされないため)。実際、Active-Active Orion 構成では "none" 以外のものを使用しても、mutex ポリシーは Orion プロセスのローカルなので、利点はありません。
発信 HTTP 接続タイムアウト
特定の通知受信者またはクエリ/更新が転送されたコンテキスト・プロバイダが、HTTP 要求に応答するには時間がかかりすぎることがあります。場合によっては、受信側もリッスンしていないため、要求が失敗したとみなして送信側のスレッドのブロックを解除する前に、長いタイムアウト (オペレーティング・システムによって設定されたデフォルトのタイムアウト値) が経過しなければなりません。これは大きな影響を与える可能性があります。
通知の場合、スレッド (一時的、永続的またはスレッド・プール内) がブロックされます。一時的または永続的なモードでは、プロセス内のアイドル状態のスレッドが含まれ、プロセスごとの最大スレッド数にカウントされますが、有効な作業はありません。永続モードの場合は特に重大です。同じ URL に送信してください。2番目のケースでは、待っている間に新しい仕事をすることができない w ワーカーがプールにいることを意味します。
コンテキスト・プロバイダに転送されるクエリ/更新の場合、元のクライアントが応答を得るのに時間がかかります。実際、一部のクライアントは接続をあきらめて接続を閉じることがあります。
このような状況では、-httpTimeout
CLI パラメータは、デフォルトのオペレーティング・システムのタイムアウトを上書きして、Orion が発信 HTTP 接続を待機する時間を制御するのに役立つ場合があります。このパラメータは、サブスクリプションに対して個別に定義できることに注意してください。サブスクリプションの JSON で timeout
が定義されている場合、デフォルトのパラメータは無視されます。
サブスクリプション・キャッシュ
Orion は、通知トリガーを高速化するために、コンテキスト・サブスクリプション・キャッシュを実装しています。
キャッシュ同期期間は、-subCacheIval
により制御されます (デフォルトでは60秒です)。同期には2つの異なるタスクがあります :
-
データベース内のコンテキスト・サブスクリプション・コレクションの変更を読み取り、それに基づいてローカル・キャッシュを更新します。multi-CB 構成では、1つのノードがコンテキスト・サブスクリプション・コレクションを変更する可能性があるので、これは他のノードが変更を認識するための方法です
-
各サブスクリプションに関連付けられた一時的な情報をデータベースに書き込む。つまり、モノ CB 構成であっても、0以外の値を
-subCacheIval
に使用する必要があります (-subCacheIval 0
は許可されていますが、推奨されません)
ロードバランシングを使用する multi-CB 構成では、あるクライアントが通知を送信し、すべての CB ノードがそれを認識するまでに時間がかかります (その上限はキャッシュの更新間隔です)。この期間中、1つの CB (サブスクリプションを処理してキャッシュ内にある CB) のみが、それに基づいて通知をトリガーします。したがって、CB はこれに関して "最終的な整合性" を実装します。
また、キャッシュの更新間隔とのトレードオフがあることにも注意してください。短い間隔は、コンテキスト・サブスクリプションに関する変更が CB ノード間でより速く伝播することを意味します (つまり、"最終的な一貫性" から完全な一貫性に移行する時間が短くなければなりません) が、CB および DB にはより大きなストレスがあります。間隔が長いと変更には伝搬に時間がかかりますが、CB と DB へのストレスは低いことを意味します。
最後の注意として、-noCache
CLI パラメータを使用して完全にキャッシュを無効にすることはできますが、それは推奨される構成ではありません。
ジオ・サブスクリプションのパフォーマンスに関する考慮事項
NGSIv2 サブスクリプション、別名ジオ・サブスクリプションの georel, geometry, coords の表現フィールドの現在のサポートは、MongoDB のジオクエリー機能に依存しています。サブスクリプション (例えば、クエリ・フィルタなど) に関連する他のすべての条件は、更新されたエンティティのメモリイメージ上で評価されますが、特定のサブスクリプションの georel, geometry, coords に関連するものは、DB 内のクエリを必要とします。
ただし、パフォーマンスへの影響はあまり重すぎないようにしてください。MongoDB での count()
操作は比較的軽いです。
将来の計画は、他の条件と同様に、ジオ・サブスクリプション・マッチングをメモリに実装することですが、これは現時点では優先事項ではありません。