ぷろじぇくと、みすじら。

KumoDictionary: クラウドのNoSQLをIDictionary<TKey, TValue>として使う

Created at:

KumoDictionary というライブラリーを公開しました。

このライブラリは何かというと IDictionary<TKey, TValue> を操作すると、裏側ではネットワークの先にあるNoSQL的なもの、例えばAzure Storage TableやAmazon DynamoDBなどへ透過的に記録、読み取りを行うものです。

作った動機

Azure FunctionsやAWS LambdaのようなServerlessアプリ、もしかしたら単なるCLIで小さいツールといったものを作るということはよくありますが、その際にちょっとしたデータを保存したいということも同時によくあります。

例えばFunctionsでWebhookを作ったとして、特定のパラメータに対して最後にアクセスされた時刻を記録する…などなど。

じゃあデータ保存しましょうとなると、ファイルは永続化できる書き込み先はないし、Redisやデータベース的なデータアクセスはサーバーを用意するのもオーバーキル。そうなるとお手軽なのはNoSQL系かとなるのですが、いざSDKを入れて使ってみるとテーブルの設計と呼び出しがめんどくさいものです。

欲しいのは雑に Dictionary<TKey, TValue> が永続化されてくれるような程度でいいのですがーという気持ちからスタートしています。

IDictionary ということはブロッキングだし筋があまりよくないのではという疑問はごもっともですが、クラウド内であればレイテンシーも小さいことやそもそも低負荷のアプリであることをこのライブラリは期待しています。

パフォーマンスを真面目に気にする段階になったときは、Asyncメソッドをご利用いただくか、そもそも普通にSDKでアクセスしてください。

使い方

使い方はとりあえず Azure Storage Table であれば簡単です。

まずポータルやCLIでストレージアカウントを作成しておきます。

次に KumoDictionary.AzureStorageTable NuGetパッケージをインストールします。

そしてプログラムの頭で一度だけデフォルトのバックエンドの設定を行います。

using KumoDictionary;
using KumoDictionary.Provider;

// Set backend provider for Microsoft Azure Storage Table
var tableName = "MyTestTable";
var connectionString = "DefaultEndpointsProtocol=https;AccountName=...";

KumoDictionaryAzureStorageTableProvider.UseAsDefault(connectionString, tableName);

あとは KumoDictionary<TValue> クラスを使うだけです。ちなみにこれは KumoDictionary<string, TValue> の別名です。

// KumoDictionary を作るときにディクショナリーの名前を付けてあげる
var dict = new KumoDictionary<MyClass>("dictionaryName1");

// インデクサで値をセット
dict["key1"] = new MyClass { ValueA = 1234 };
dict["key2"] = new MyClass { ValueA = 5678 };

// インデクサで値を取得
Console.WriteLine(dict["key1"].ValueA); // => 1234

つまり最初のProviderの設定以外は普通のDictionaryっぽく扱えるのです(もちろん一部機能は実装されていなかったりはしますが)。

DynamoDB の場合

DynamoDBの場合にはテーブルの作成があらかじめ必要ですが、逆を言えばそれぐらいです。

裏側

裏側は単純にMessagePackでシリアライズして適当にストアに保存しているだけです。

ただ、値がもしデータストア側がネイティブで対応している型の場合にはそのままそれを使います。例えばAzure Storage TableやDynamoDBはStringを直接扱えるのでそのまま突っ込むことで管理画面や別なツールからもフレンドリーになるのです。

またキーの方も独自のクラスを使えますが、クラスの構造(プロパティやフィールドの名前、型、順番、数)が変更されると壊れるのであまりお勧めはできません。

雰囲気的にはRedis向けのCloudStructuresに近いですし、Redisに値を詰めたい or 詰めるのでよいのであればCloudStructuresを使うのをお勧めします。

まとめ

これでちょっとしたものを作るときにデータや設定の保存の手助けとなれば幸いです。