C# 串接 Redis

Posted by Max Lin on 2022-06-15

前言

先前 Docker 佈署 Redis 記錄如何佈署 Redis,這篇來記錄如何在 C# 串接 Redis 資料庫和一些基本的資料結構使用

介紹

Redis 是一個 open source 且 in-memory 的 NoSQL 資料庫( key-value 類型 )

  • 特點
    • 支持持久化,可將內存資料存於硬碟,備份模式如:RDBAOF
    • 豐富資料類型,如:StringListSetZSetHashSet
    • 支持高可用及高擴充 Solution,如:Master-Slave(主從)、Sentinel(哨兵)、Cluster(叢集)模式
    • 性能極高,特性:I/O Multiplex、In-memory
    • 豐富功能,如:pub/sub 訂閱、data expired
  • 應用場景
    • 具有時效性的資料控制,如:驗證碼、Token
    • 分散式架構資料共享,如:快取
    • 即時訊息查詢,如:在線人數、廣播訊息

下載套件與串接

  • 下載 StackExchange.Redis 套件

  • 串接
    ※ Redis 使用多路複用(Multiplex),也就是單一個執行緒可以同時處理多個連線,所以沒有 connection pool 的情況,不需使用 using 來建立 & 釋放

  1. // 連線字串
  2. string address = "127.0.0.1:6379";
  3. // 建立連線,不需 using
  4. ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(address);
  5. // 取得實體
  6. IDatabase db = redis.GetDatabase();

String

  1. // 設定資料
  2. var stringKey = "Hello";
  3. await db.StringSetAsync(stringKey, "0523");
  4. // 取得資料
  5. string value = await db.StringGetAsync(stringKey);
  6. // 刪除資料
  7. await db.KeyDeleteAsync(stringKey);

List

value 為一個 List 結構,且 Redis 的集合 Index 都是從 1 開始

  1. var listkey = "List";
  2. // 從頭部加入元素
  3. await db.ListRightPushAsync(listkey, "AAA");
  4. // 從尾部加入元素
  5. await db.ListLeftPushAsync(listkey, "BBB");
  6. // 取出指定 Index 元素
  7. var indexValue = await db.ListGetByIndexAsync(listkey, 1);
  8. // 取出陣列
  9. var array = (await db.ListRangeAsync(listkey)).ToStringArray();
  10. // 取出子陣列,取 index 1 之後的 2 個
  11. var subArray = (await db.ListRangeAsync(listkey, 1, 2)).ToStringArray();
  12. // 插入多筆資料
  13. var insertCount = await db.ListRightPushAsync(listkey, new RedisValue[] { "B", "B", "B", "D" });
  14. // 刪除特定資料,將 A 的資料全部刪除
  15. await db.ListRemoveAsync(listkey, "A", 0);
  16. // 刪除特定資料,從頭開始刪除 1 筆 B 的資料
  17. await db.ListRemoveAsync(listkey, "B", 1);
  18. // 刪除特定資料,從尾開始刪除 2 筆 B 的資料
  19. await db.ListRemoveAsync(listkey, "B", -2);
  20. // 保留一段範圍的資料,取 index 1 之後的 2 個
  21. await db.ListTrimAsync(listkey, 1, 2);

Set

value 為一個 Set,且為一個 不重複 的集合

  1. var setKey = "set";
  2. // 建立一筆資料
  3. await db.SetAddAsync(setKey, "1");
  4. // 建立多筆資料
  5. await db.SetAddAsync(setKey, new RedisValue[] { 1, 1, 2, 3 });
  6. // 刪除指定元素 1 的資料
  7. await db.SetRemoveAsync(setKey, 1);
  8. // 取得 Set 長度
  9. var setLength = await db.SetLengthAsync(setKey);
  10. // 取得 Set 所有元素
  11. var setItems = await db.SetMembersAsync(setKey);
  12. // 判斷指定元素 1 是否存在
  13. var itemExists = await db.SetContainsAsync(setKey, 1);

ZSet(Sorted Set)

value 為一個 SortedSet,為一個 排序且不重複 的集合,寫入時會依照 Score 進行排序

  1. var sortedSetKey = "sortedSet";
  2. // 新增一筆資料
  3. await db.SortedSetAddAsync(sortedSetKey, "Amy", 5);
  4. // 新增多筆資料
  5. await db.SortedSetAddAsync(sortedSetKey, new SortedSetEntry[]
  6. {
  7. new SortedSetEntry("Andy", 8),
  8. new SortedSetEntry("Danny", 4)
  9. });
  10. // 取得 SortedSet 長度
  11. var sortedSetLength = await db.SortedSetLengthAsync(sortedSetKey);
  12. // 取得 SortedSet 所有元素
  13. var sortedSetItems = await db.SortedSetRangeByValueAsync(sortedSetKey);
  14. // 取得 SortedSet 所有元素包含分數
  15. var sortedSetItemsAndSorce = await db.SortedSetRangeByScoreWithScoresAsync(sortedSetKey);
  16. // 取得分數遞減排序後 Danny 的排名,默認從索引 0 開始排
  17. var rankDanny = await db.SortedSetRankAsync(sortedSetKey, "Danny", Order.Descending);
  18. // 取得分數遞減前10名元素的排名,默認從索引 0 開始排
  19. var rankValues = await db.SortedSetRangeByRankAsync(sortedSetKey, start: 0, stop: 10, order: Order.Descending);
  20. // 取得分數遞減前10名元素的排名和分數,默認從索引 0 開始排
  21. var rankValueAndScore = await db.SortedSetRangeByScoreWithScoresAsync(sortedSetKey, start: 0, stop: 10, order: Order.Descending);
  22. // 刪除指定元素
  23. await db.SortedSetRemoveAsync(sortedSetKey, "Andy");

HashSet

value 為一個像是 C# Dictionary 結構

  1. var hashKey = "hashData";
  2. // 新增資料
  3. await db.HashSetAsync(hashKey, new HashEntry[]
  4. {
  5. new HashEntry ("Number", "1"),
  6. new HashEntry ("Name", "Max"),
  7. new HashEntry ("Phone", "3345678")
  8. });
  9. // 查看指定資料的所有值
  10. var hashSetValues = await db.HashValuesAsync(hashKey);
  11. // 查看指定資料的所有 Key
  12. var hashSetKeys = await db.HashKeysAsync(hashKey);

資料過期(data expired)

  1. // 過期時間
  2. var expiredTime = TimeSpan.FromSeconds(5);
  3. // 加入測試資料
  4. await db.StringSetAsync("sample", "hello world");
  5. // 設定過期時間
  6. var success = await db.KeyExpireAsync("sample", expiredTime);

原始碼

參考

Redis系列 - C#存取Redis

.NET 6使用Redis