Skip to content

在 ASP.NET 使用 Redis 實作分散式快取

TLDR

  • Windows 環境建議使用 WSL 2 或 Docker 安裝 Redis,不建議使用微軟封存的舊版安裝檔。
  • 開發環境可使用 Memurai 作為 Redis 的 Windows 相容替代方案。
  • Docker 安裝 Redis 時,若外部無法連線,需調整 redis.conf 中的 bindprotected-mode 設定。
  • ASP.NET Core 建議使用 IDistributedCache 介面實作分散式快取;若僅為單機環境,使用 IMemoryCache 效能更佳。
  • ASP.NET Framework 可直接使用 StackExchange.Redis 套件透過 ConnectionMultiplexer 存取 Redis。

在 Windows 上安裝 Redis

Redis 原生並未支援 Windows,若需在 Windows 環境進行開發或測試,建議採取以下方式:

  • WSL 2:官方推薦方案,效能與穩定性最佳。
  • Memurai:兼容 Redis 的 Windows 分支,適合開發與測試環境。
  • Docker:透過官方 Image 安裝,適合容器化部署。

使用 Docker 安裝注意事項

什麼情況下會遇到問題:在 Docker 容器內執行 Redis,但外部應用程式無法連線時。

  • 若需自訂設定,請掛載 redis.conf 檔案。
  • 若發生 Connection refused,請檢查 redis.conf 設定:
    • bind 127.0.0.1 -::1 註解掉以允許外部連線。
    • protected-mode yes 改為 protected-mode no

範例 docker-compose.yml 設定:

text
version: '3.8'

services:
  Redis-Server:
    image: redis:7
    container_name: Redis-Server
    ports:
      - 6379:6379
    volumes:
      - .\Volumes\Data:/data
      - .\Volumes\Config:/usr/local/etc/redis
    command: redis-server /usr/local/etc/redis/redis.conf
    restart: always

在 ASP.NET Core 使用快取

MemoryCache (單機快取)

什麼情況下會遇到問題:當應用程式僅部署於單一伺服器,且不需要跨機器共享狀態時。

  • 使用 IMemoryCache 介面。
  • 策略選擇:
    • Absolute:絕對到期時間,時間一到即刪除。
    • Sliding:滑動過期時間,若持續存取則會延長存活時間。

IDistributedCache (分散式快取)

什麼情況下會遇到問題:當應用程式部署於多台伺服器,需要共享快取資料時。

  • 使用 Microsoft.Extensions.Caching.StackExchangeRedis 套件。
  • 註冊服務:
csharp
builder.Services.AddStackExchangeRedisCache(options => {
    options.Configuration = builder.Configuration.GetConnectionString("Redis");
    options.InstanceName = "SampleInstance";
});

WARNING

若 App Server 僅有一台,建議優先使用 IMemoryCache。因為 IMemoryCache 讀取本機記憶體效能優於遠端 Redis,且 API 支援更豐富的型別存取,而 IDistributedCache 原生僅支援 string


在 ASP.NET Framework 使用 Redis

什麼情況下會遇到問題:在舊版 .NET Framework 專案中需要整合 Redis。

  • 使用 StackExchange.Redis 套件。
  • 建議使用單例模式(Singleton)管理 ConnectionMultiplexer 以維持連線穩定。
csharp
public sealed class RedisConnection {
    private static readonly Lazy<RedisConnection> lazy = new Lazy<RedisConnection>(() => new RedisConnection());

    private RedisConnection() {
        ConnectionMultiplexer = ConnectionMultiplexer.Connect("127.0.0.1:6379");
    }

    public static RedisConnection Instance => lazy.Value;
    public ConnectionMultiplexer ConnectionMultiplexer { get; }
}

使用範例:

csharp
IDatabase db = RedisConnection.Instance.ConnectionMultiplexer.GetDatabase(0);
string cachedValue = await db.StringGetAsync("CacheKey");

異動歷程

    • 初版文件建立。