従来の展開
Kongクラスタでは、より多くのリクエストを処理するマシンをさらに追加することで、システムを水平方向に拡張できます。これらは同じデータベースを指しているため、同じ構成となります。 同じデータストア を指しているKongノードは、同じKongクラスターの一部になります。
利用可能なノード全体でトラフィックを分散するには、Kongクラスターの前にロードバランサーが必要です。
flowchart TD A[(Database)] B( Kong Gateway instance) C( Kong Gateway instance) D( Kong Gateway instance) A <---> B & C & D style B stroke:none,fill:#0E44A2,color:#fff style C stroke:none,fill:#0E44A2,color:#fff style D stroke:none,fill:#0E44A2,color:#fff
図 1: 従来のデプロイメントでは、すべてのKong Gatewayノードがデータベースに接続します。 各ノードは、独自の構成を管理します。
Kong クラスタが行うことと行わないこと
Kongクラスタがあるからといって、そのままでクライアントのトラフィックが 自動的にKongノード間でロードバランシングされるわけではありません。 トラフィックを 分散させるためには、Kongノードの前にロードバランサーを設定する必要があります。Kong クラスタは、それらのノードが同じ設定を共有することを意味します。
パフォーマンス上の理由から、Kongはリクエストのプロキシ時にデータベース接続を回避し、メモリ内にデータベースの内容をキャッシュします。 キャッシュされたエンティティには、サービス、ルート、コンシューマ、プラグイン、認証情報などが含まれます。 これらの値はメモリ内にあるため、いずれかのノードのAdmin APIから実行された変更は他のノードに伝達される必要があります。
このドキュメントでは、キャッシュされたエンティティが無効になる方法と、パフォーマンスと一貫性の中間辺りに位置するユースケース向けにKongノードを構成する方法を説明しています。
単一ノードのKongクラスタ
サポートされているデータベースに接続された単一の Kong ノードは、1 つのノードの Kong クラスタを作成します。このノードの Admin API を通して適用された変更は、すぐに有効になります。以下に例を示します。
1つのKongノードA
について考えてみましょう。以前に登録したサービスを削除するために、以下を実行します。
curl -X DELETE http://127.0.0.1:8001/services/test-service
その後、A
へのリクエストはすべて即座に 404 Not Found
を返すようになります。ノードがローカルキャッシュからそれを削除したためです。
curl -i http://127.0.0.1:8000/test-service
複数ノードのKongクラスタ
複数の Kong ノードのクラスタでは、同じデータベースに接続されている他のノードに対して、サービスがノード A
によって削除されたことはすぐには通知されません。サービスがデータベースに 存在しなくなっても (ノード A
によって削除)、サービスはノード B
のメモリに まだ 残っています。
すべてのノードは定期的なバックグラウンドジョブを実行して、その他のノードによってトリガーされた変更を同期します。このジョブの頻度は、次を介して構成できます。
- [
db_update_frequency
][db_update_frequency] (デフォルト: 5 秒)
db_update_frequency
秒ごとに、実行中のすべてのKongノードがデータベースの更新をチェックし、必要に応じて関連するエンティティをキャッシュから削除します。
ノード A
からサービスを削除した場合、この変更はノード B
の次のデータベースポーリングまで、B
ノードでは有効になりません。これは最大でdb_update_frequency
秒後(もっと早く起こる可能性はありますが)に行われます。
これにより、Kong クラスタは 最終的に一貫性 が保たれます。
PostgreSQLでKongクラスターをデプロイするときは、読み取り専用のレプリカを使用してください
Postgres をバックエンドストレージとして使用する場合、オプションで Kongを 有効にして別のデータベースインスタンスからの読み取りクエリを処理することができます。
Kongで読み取り専用の接続サポートを有効にすると、読み取り専用クエリがメインのデータベースインスタンスに送信されなくなるため、当該データベースの負荷が軽減します。
この機能の設定方法の詳細については、構成リファレンスの データストアセクション を参照してください。
キャッシュの対象
サービス、ルート、プラグイン、コンシューマ、認証情報などのコアエンティティは、すべてKongによってメモリにキャッシュされ、ポーリングメカニズムを介した無効化に依存して更新されます。
さらに、Kongは データベースのミス もキャッシュします。つまり、プラグインなしでサービスを構成する場合、Kongはこの情報をキャッシュします。例:
ノードA
で、サービスとルートを追加します。
# node A
curl -X POST http://127.0.0.1:8001/services \
--data "name=example-service" \
--data "url=http://example.com"
curl -X POST http://127.0.0.1:8001/services/example-service/routes \
--data "paths[]=/example"
(ショートカットとして/services/example-service/routes
を使用していることに注意してください。代わりに/routes
エンドポイントを使用することもできますが、その場合は新しいサービスのUUIDとともに、service_id
を引数として渡す必要があります。)
A
と B
の両方のプロキシポートにリクエストすると、このサービスはキャッシュされますが、実際にはプラグインは何も構成されません。
# node A
curl http://127.0.0.1:8000/example
応答:
HTTP 200 OK
...
# node B
curl http://127.0.0.2:8000/example
応答:
HTTP 200 OK
...
ここで、ノード A
の Admin API を使ってこのサービスにプラグインを追加します。
# node A
curl -X POST http://127.0.0.1:8001/services/example-service/plugins \
--data "name=example-plugin"
このリクエストはノード A
の Admin API を通して発行されたため、ノード A
はローカルでキャッシュを無効にし、後続のリクエストでは、この API にプラグインが構成されていることを検出します。
ただし、ノード B
はまだデータベースポーリングを実行しておらず、このAPIには実行するプラグインがないことがキャッシュされています。これは、ノード B
がデータベースポーリング ジョブを実行するまで続きます。
結論 :すべてのCRUD操作はキャッシュの無効化を引き起こします。作成
(POST
、PUT
)はデータベースのキャッシュミスを無効にし、更新/削除
(PATCH
、DELETE
)はデータベースのキャッシュヒットを無効にします。
データベースキャッシュを構成する方法
Kong構成では3つのプロパティを構成できます。最も重要なのはdb_update_frequency
で、Kongノードがパフォーマンスと一貫性のどちらに依存するかを決定します。
Kongには、一貫性を保つために調整されたデフォルト値が用意されているので、予期せぬ事態を避けながら、クラスタリングの機能を試すことができます。本番環境のセットアップを準備する際には、パフォーマンスに関する制約が守られるように、これらの値を調整することを検討する必要があります。
[ db_update_frequency
][db_update_frequency] (デフォルト: 5秒)
この値は、Kongノードがデータベースに対して無効化イベントをポーリングする頻度を決定します。値を低くすると、ポーリングジョブの実行頻度が高くなりますが、Kongノードが適用した変更に追従することを意味します。 値を高くすると、Kongノードはポーリングジョブの実行時間を減らし、トラフィックのプロキシ処理に専念します。
注 :行われた変更は、最大
db_update_frequency
秒でクラスタ全体に伝達されます。
[db_update_propagation
][db_update_propagation](デフォルト:0秒)
このパラメータを設定することで、変更がデータベースノード全体で伝播する時間ができます。これが設定されると、ポーリングジョブから無効化ジョブを受信するKongノードは、キャッシュの消去をdb_update_propagation
秒先延ばしにします。
最終的に一貫したデータベースに接続されたKongノードがイベント処理の遅延を発生させていない場合、Kongノードはキャッシュを消去した後で、未更新の値を再びキャッシュする可能性があります(理由:変更がデータベースを通じてまだ伝播されていないため)。
この値は、変更の伝達にデータベースクラスタが費やすと推定される時間に設定する必要があります。
注 :この値を設定すると、変更はクラスタ全体に最大
db_update_frequency + db_update_propagation
秒で伝達されます。
[db_cache_ttl
][db_cache_ttl] (default: 0s)
Kongがデータベースエンティティ(ヒットとミスの両方)をキャッシュする時間(秒)。このTime-To-Live値は、Kongノードが無効化イベントを見逃した場合に、古いデータで長時間実行されないようにするための保護手段として機能します。TTLに達すると、値はキャッシュから消去され、次のデータベースの結果が再度キャッシュされます。
デフォルトでは、このTTLに基づいて無効化されるデータはありません(デフォルト値は0
)。
通常はこれで問題なく、KongノードはDBストアレベルで処理される無効化イベントに依存します。
Kongノードが何らかの理由で無効化イベントを見逃さないか心配な場合は、TTLを設定します。
それ以外の場合、ノードはキャッシュが手動で削除されるかノードが再起動されるまで、不特定期間キャッシュ内の古い値で実行される可能性があります。
Admin APIを使用したキャッシュとのやり取り
何らかの理由で、キャッシュされた値を調査したい場合や、Kongによってキャッシュされた値を手動で無効化したい場合(キャッシュヒットまたはキャッシュミス)は、Admin API /cache
エンドポイントを介してそれらを実行できます。
注 : Kong によってキャッシュされている各エンティティの
cache_key
を取得するプロセスは、現時点では文書化されていません。Admin API の将来のバージョンでは、このプロセスが簡単になります。
キャッシュされた値の検査
エンドポイント
レスポンス
そのキーを持つ値がキャッシュされている場合:
HTTP 200 OK
...
{
...
}
それ以外:
HTTP 404 Not Found
キャッシュされた値を消去
エンドポイント
レスポンス
HTTP 204 No Content
...
ノードのキャッシュを消去する
エンドポイント
レスポンス
HTTP 204 No Content
注 :ウォームキャッシュを使用して本番環境で実行しているノードでこのエンドポイントを使用する場合は注意が必要です。 このノードの受信トラフィックが大量の場合、同時にキャッシュを消去すると、データベースに対する多数のリクエストがトリガーされ、ドッグパイル効果につながる恐れがあります。