1 はじめに
.NET Core は 1.0 リリース以来、さまざまな困難を経てきました。当初は多くのライブラリが欠けていましたが、現在では部分的に整備されるようになり、今日に至るまで決して楽な道のりではありませんでした。
たとえば、redis-cli SDK は問題が絶えません。
かつて .NET で最も有名だった ServiceStack.Redis は商用製品となり、.NETCore で使用するには課金が必要です。後発の StackExchange.Redis は一応使えますが、本番環境でさまざまなタイムアウトエラーが発生して手を焼かせ、2年以上も解決されず、最近リリースされた 2.0 バージョンで根本的に解決されたかどうかは不明です。
2 csredis v3.0.0 の更新内容
- すべてのメソッド名を redis-cli と一致させました。
Java/Python/Go/Node.js/PHP SDK のメソッド名は基本的に redis-cli と一致しており、再命名するライブラリには反対です。
逆シリアル化オブジェクトの取得機能を追加しました。例:
Get<byte[]>、HGet<byte[]>。すべての取得メソッドがオーバーロードされており、デフォルトの取得は引き続き string です。SafeObjectPool の導入。
3 使用方法
nuget Install-Package CSRedisCore
var rds = new CSRedis.CSRedisClient("127.0.0.1:6379,password=123,defaultDatabase=13,poolsize=50,ssl=false,writeBuffer=10240,prefix=key前辍");
rds.Set("test1", "123123", 60);
rds.Get("test1");
//関数名は redis-cli のコマンドと同じです。rds は必ずシングルトンである必要があります。
4 高度な使い方:パーティショニング
複数のサービスノードでストレージを分散する現実的な方法で、公式のパーティショニング、クラスタリング、高可用性ソリューションとは異なります。
例:キャッシュデータが 500GB に達した場合、1台の redis-server だけでメモリだけで保存するのは非常に困難であり、ハードディスクを使用するとパフォーマンスに影響します。
この機能を使用すると、複数の redis-server サーバーで自動的にストレージを分散管理でき、各サーバーは約 (500/N)GB のメモリで済み、各サーバーには公式の高可用性アーキテクチャを構成することもできます。
var rds = new CSRedis.CSRedisClient(null,
"127.0.0.1:6371,password=123,defaultDatabase=11,poolsize=10,ssl=false,writeBuffer=10240,prefix=key前辍",
"127.0.0.1:6372,password=123,defaultDatabase=12,poolsize=11,ssl=false,writeBuffer=10240,prefix=key前辍",
"127.0.0.1:6373,password=123,defaultDatabase=13,poolsize=12,ssl=false,writeBuffer=10240,prefix=key前辍",
"127.0.0.1:6374,password=123,defaultDatabase=14,poolsize=13,ssl=false,writeBuffer=10240,prefix=key前辍");
//実装の考え方:key.GetHashCode() % ノード総数 に基づいて接続先ノードを決定
//カスタムルールも可能(最初のパラメータで設定)
rds.MSet("key1", 1, "key2", 2, "key3", 3, "key4", 4);
rds.MGet("key1", "key2", "key3", "key4");
5 高度な使い方:パブリッシュ/サブスクライブ
//通常のサブスクライブ
rds.Subscribe(
("chan1", msg => Console.WriteLine(msg.Body)),
("chan2", msg => Console.WriteLine(msg.Body)));
//パターンサブスクライブ(ワイルドカード)
rds.PSubscribe(new[] { "test*", "*test001", "test*002" }, msg => {
Console.WriteLine($"PSUB {msg.MessageId}:{msg.Body} {msg.Pattern}: chan:{msg.Channel}");
});
//パターンサブスクライブで解決した問題:
//1. パーティションのノード一致ルールにより、ワイルドカードは最大ですべてのノードに一致する可能性があるため、すべてのノードでサブスクライブする必要がある
//2. このグループ "test*", "*test001", "test*002" をすべてのノードでサブスクライブする場合、同じメッセージが複数回実行されないようにする必要がある
//パブリッシュ
rds.Publish("chan1", "123123123");
//パーティションでも通常モードでも、rds.Publish は正常に通信できます
6 高度な使い方:キャッシュシェル
//キャッシュがない場合、データベースからクエリする
var t1 = Test.Select.WhereId(1).ToOne();
//一般的なキャッシュコードは、ラップしないとかなり煩雑
var cacheValue = rds.Get("test1");
if (!string.IsNullOrEmpty(cacheValue)) {
try {
return JsonConvert.DeserializeObject(cacheValue);
} catch {
//エラー時はキーを削除
rds.Remove("test1");
throw;
}
}
var t1 = Test.Select.WhereId(1).ToOne();
rds.Set("test1", JsonConvert.SerializeObject(t1), 10); //10秒キャッシュ
//キャッシュシェルを使用すると上記と同じ効果。以下は string と hash を使用したキャッシュの例
var t1 = rds.CacheShell("test1", 10, () => Test.Select.WhereId(1).ToOne());
var t2 = rds.CacheShell("test", "1", 10, () => Test.Select.WhereId(1).ToOne());
var t3 = rds.CacheShell("test", new [] { "1", "2" }, 10, notCacheFields => new [] {
("1", Test.Select.WhereId(1).ToOne()),
("2", Test.Select.WhereId(2).ToOne())
});
7 高度な使い方:パイプライン
パイプラインモードを使用して、複数のコマンドをまとめて実行し、パフォーマンスを向上させます。
var ret1 = rds.StartPipe().Set("a", "1").Get("a").EndPipe();
var ret2 = rds.StartPipe(p => p.Set("a", "1").Get("a"));
var ret3 = rds.StartPipe().Get("b").Get("a").Get("a").EndPipe();
//rds.MGet("b", "a", "a") とのパフォーマンス比較では、ほぼ差はありません
8 高度な使い方:複数データベース
どうしてもデータベースを切り替える必要がある場合は、以下のコードを参照してください。
var connectionString = "127.0.0.1:6379,password=123,poolsize=10,ssl=false,writeBuffer=10240,prefix=key前辍";
var redis = new CSRedisClient[14]; //シングルトンとして定義
for (var a = 0; a< redis.Length; a++) redis[a] = new CSRedisClient(connectionString + "; defualtDatabase=" + a);
//データベース1のデータにアクセス
redis[1].Get("test1");
9 パフォーマンス比較

10 おわりに
引き続きオープンソースを応援しています。ご覧いただきありがとうございました!
csredis ソースコード: https://github.com/2881099/csredis
本文執筆者:FreeSql & CSRedis
記事リンク:https://www.cnblogs.com/kellynic/p/9803314.html
ブログ運営者について:コメントや非公開メッセージはできるだけ早く返信します。直接非公開メッセージを送っていただいても構いません。
著作権表示:このブログのすべての記事は、特別な記載がない限り、BY-NC-SA ライセンスに従います。転載の際は出典を明記してください!
ブログ運営者への応援:記事が役に立ったと思われたら、記事右下の【おすすめ】をクリックしていただけると励みになります。