.NETやjavaなどのSDKを利用することで、簡単にCosmosDBにアクセスできます。しかし、実際にどのようにCosmosDBと通信しているのかについては、普段意識することはないと思います。CosmosDBへの接続には2つのモードがあるため、今回はこの2モードについて調査た内容をまとめます。
結論
- CosmosDBの接続モードは「Gatewayモード」と「Directモード」の2種類ある
- 「Directモード」のほうがパフォーマンス効率がいい
- .NET SDKでアクセスする際はデフォルトで「Directモード」に設定されている
接続モード
CosmosDBに接続する際は、「Gatewayモード」と「Directモード」の2種類があります。GatewayモードではGatewayノードを経由してCosmosDBに接続しますが、Directモードでは直接接続します。そのため、DirectモードはGatewayモードに比べてネットワークホップ数が少なく、パフォーマンスが向上します。
公式ドキュメントに記載されている図を見るとイメージが掴みやすいです。
Directモードは.NETとJavaでサポートされています。.NET SDkから接続する際は、デフォルトでDirectモードに設定されています。
また、初回接続時にコンテナ情報やルーティング情報を取得します。これらの情報はSDK上でローカルにキャッシュされるため、以降の処理はキャッシュ情報を利用します。
動作確認
2種類の接続モードについて概要が理解できたため、簡単なサンプルで動作確認をしてみたいと思います。CRUD処理を1回ずつ行うAzure Functionsを使用します。不要な個所は省略しています。
[Function("Test1")]
public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
{
var id = "partitionKey";
var name = "test1";
var cosmosData = new CosmosEntity(id, name);
var con = this._cosmosClient.GetContainer(containerName, colletionName);
// Create new item
var createResult = await con.CreateItemAsync<CosmosEntity>(cosmosData);
// Read item
var readResult = await con.ReadItemAsync<CosmosEntity>(id, new PartitionKey(id));
// Update item
cosmosData.name = "test2";
var updateResult = await con.UpsertItemAsync<CosmosEntity>(cosmosData);
// Delete item
var deleteResult = await con.DeleteItemAsync<CosmosEntity>(id, new PartitionKey(id));
}
CosmosDBクライアントはDIで利用できるように設定します。
public static void Main()
{
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(s =>
{
// CosmosDBクライアントの登録
s.AddSingleton<CosmosClient>(serviceProvider =>
{
return new CosmosClient(endpoint, key, options);
});
})
.Build();
host.Run();
}
デフォルトの状態で実行した結果
まずはデフォルトの設定で実行して、CDBDataPlaneRequestsログを見てみます。CDBDataPlaneRequestsログにはCosmosDBへの読み書きリクエストが出力されます。
下記のログを確認すると、初めにCollectionに対するReadが記録されています。これは、CosmosDBのコンテナ(Collection)情報を取得していると思われます。Functionsを起動したまま複数回実行してみると、最初の1回しかCollectionのReadは記録されず、2回目以降はCRUDのみログに記録されていました。一方、毎回Functionsを起動し直して実行すると、必ず最初にCollectionに対するReadがログに記録されます。
CRUD(Create、Read、Upsert、Delete)についてはすべて設定どおりDirectモードで接続していることが分かります。
Gatewayモードに変更してみる
続いて、接続モードをGatewayに変更してみます。CosmosDBClientsOptionsを利用することで、様々な設定情報を変更できます。接続モードに関してはConnectionModeを使用します。
s.AddSingleton<CosmosClient>(serviceProvider =>
{
var options = new CosmosClientOptions()
{
ConnectionMode = ConnectionMode.Gateway
};
return new CosmosClient(endpoint, key, options);
});
Gatewayに変更後、再度Functionsを起動して接続を行った結果のログを書きにしまします。CRUD処理がすべてGatewayモードで実行されていることがわかります。
まとめ
CosmosDBの接続には「Directモード」と「Gatewayモード」の2種類のモードが存在します。.NET SDKではデフォルトでパフォーマンスが高い「Gatewayモード」が使用されます。基本的にはデフォルトの設定のままで問題ないと思います。
しかし、企業のファイアウォールなどのネットワーク設定によってはDirectモードで必要な通信を許可できないこともあるかと思います。そのような時は、Gatewayモードが選択肢になるのではないでしょうか。
コメント