StackExchange.Redis

キャッシュライブラリ.NETC#Redis高性能分散キャッシュNoSQL

GitHub概要

StackExchange/StackExchange.Redis

General purpose redis client

スター6,084
ウォッチ306
フォーク1,542
作成日:2014年3月14日
言語:C#
ライセンス:Other

トピックス

c-sharpredisredis-client

スター履歴

StackExchange/StackExchange.Redis Star History
データ取得日時: 2025/10/22 08:06

キャッシュライブラリ

StackExchange.Redis

概要

StackExchange.Redisは、.NET環境向けの高性能Redisクライアントライブラリです。多重化接続、非同期操作、Redis Cluster対応などの高度な機能を提供し、分散キャッシングやリアルタイムアプリケーションに最適化されています。

詳細

StackExchange.Redisは、Redis(Remote Dictionary Server)との効率的な通信を実現する.NET用クライアントライブラリです。シングル接続を多重化して複数のスレッドから共有利用する設計により、接続オーバーヘッドを最小化しつつ高いパフォーマンスを実現します。

主要技術特徴

  • 多重化接続(ConnectionMultiplexer): 物理的な接続を論理的に分割し、複数のスレッドから効率的に利用
  • 非同期ファーストAPI: async/awaitパターンによるノンブロッキング操作を標準サポート
  • Redis Cluster対応: 自動スロット検出とコマンドルーティング機能
  • Redis Sentinel統合: 自動フェイルオーバーと高可用性構成のサポート
  • パイプライニング: 複数コマンドの一括送信による通信最適化
  • エラー回復機能: 接続断発生時の自動再接続とコマンド再実行

対応プロトコルとデータ型

  • RESP2/RESP3プロトコルサポート
  • 全Redisデータ型(String、Hash、List、Set、Sorted Set、Stream)
  • Pub/Sub(Publish/Subscribe)メッセージング
  • Lua スクリプト実行(EVAL/EVALSHA)
  • Redis Modules対応

メリット・デメリット

メリット

  • 高性能: 多重化接続とパイプライニングによる効率的な通信
  • 堅牢性: 自動再接続、エラー回復、バックログシステム搭載
  • 拡張性: Redis Cluster、Sentinel対応による大規模分散環境での利用
  • 豊富な機能: 全Redis機能の包括的サポート
  • .NET統合: Task/async パターンとの自然な統合
  • コミュニティ: Stack Overflowによる開発・保守で高い信頼性

デメリット

  • 学習コスト: Redis自体の理解に加え、多重化アーキテクチャの理解が必要
  • 設定複雑性: 高可用性構成時の設定が複雑になりがち
  • メモリ使用量: 接続管理とバックログシステムによるメモリオーバーヘッド
  • .NET依存: .NET環境に限定され、他の言語との互換性なし

参考ページ

書き方の例

基本的な接続とデータ操作

using StackExchange.Redis;

// 接続マルチプレクサーの作成(再利用推奨)
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redis.GetDatabase();

// 基本的なString操作
string value = "Hello Redis";
await db.StringSetAsync("mykey", value);
string result = await db.StringGetAsync("mykey");
Console.WriteLine(result); // "Hello Redis"

// 有効期限付きデータ
await db.StringSetAsync("temp_key", "temporary", TimeSpan.FromMinutes(5));

Hash操作とパイプライニング

// Hash操作
await db.HashSetAsync("user:1000", new HashEntry[] {
    new("name", "John Doe"),
    new("email", "[email protected]"),
    new("age", 30)
});

string userName = await db.HashGetAsync("user:1000", "name");

// パイプライニング(バッチ処理)
IBatch batch = db.CreateBatch();
Task<bool> setTask1 = batch.StringSetAsync("key1", "value1");
Task<bool> setTask2 = batch.StringSetAsync("key2", "value2");
Task<long> incrTask = batch.StringIncrementAsync("counter");

batch.Execute();
await Task.WhenAll(setTask1, setTask2, incrTask);

Pub/Sub(リアルタイム通信)

// Subscriber側
ISubscriber sub = redis.GetSubscriber();

await sub.SubscribeAsync("notifications", (channel, message) => {
    Console.WriteLine($"Received: {message}");
});

// Publisher側
await sub.PublishAsync("notifications", "Hello Subscribers!");

Redis Cluster接続

// Cluster環境への接続
var options = new ConfigurationOptions {
    EndPoints = {
        { "node1.redis.cluster", 7000 },
        { "node2.redis.cluster", 7000 },
        { "node3.redis.cluster", 7000 }
    },
    CommandMap = CommandMap.Create(new HashSet<string> { "INFO" }, false)
};

ConnectionMultiplexer cluster = ConnectionMultiplexer.Connect(options);
IDatabase clusterDb = cluster.GetDatabase();

// Cluster対応のデータ操作
await clusterDb.StringSetAsync("cluster_key", "cluster_value");

Lua スクリプト実行

// Lua スクリプトによる原子的操作
string luaScript = @"
    local current = redis.call('GET', KEYS[1])
    if current == false then
        redis.call('SET', KEYS[1], ARGV[1])
        return 1
    end
    return 0
";

RedisResult result = await db.ScriptEvaluateAsync(
    luaScript, 
    new RedisKey[] { "atomic_key" }, 
    new RedisValue[] { "new_value" }
);

設定とモニタリング

// 詳細設定オプション
var configOptions = new ConfigurationOptions {
    EndPoints = { "localhost:6379" },
    ConnectTimeout = 5000,
    SyncTimeout = 5000,
    AbortOnConnectFail = false,
    ConnectRetry = 3,
    KeepAlive = 60
};

ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(configOptions);

// 接続状態とメトリクス監視
Console.WriteLine($"Is Connected: {redis.IsConnected}");
Console.WriteLine($"Operation Count: {redis.OperationCount}");
Console.WriteLine($"Configuration: {redis.Configuration}");

// サーバー情報取得
IServer server = redis.GetServer("localhost", 6379);
DateTime lastSave = server.LastSave();
ClientInfo[] clients = server.ClientList();