StackExchange.Redis 系列 2:配置

  • 本系列博文是“伪”官方文档翻译,并非完全将官方文档进行翻译,而是我在查阅、测试原始文档并转换为自己东西后进行的“准”翻译。
  • 原始文档见此:https://stackexchange.github.io/StackExchange.Redis/
  • 本系列本博文基于 redis 5.0.6,系列中部分博文跟官方文档有出入,有不同见解 / 说明不当的地方,还请大家不吝拍砖。

配置概述

StackExchange.Redis 提供了丰富的配置,你可以在调用 Connect / ConnectAsync 方法的时候进行设定,如下

var conn = ConnectionMultiplexer.Connect(configuration);
  • configuration 可以是一个 ConfigurationOptions “实例”或者一个 “代表配置内容的string 字符串”

使用说明

通过字符串来设定连接配置

基本使用:

//以下配置将使用本地搭建的 Redis 单节点服务,默认端口号为 6379
var conn = ConnectionMultiplexer.Connect("localhost");

增加额外选项:

  • Redis 的连接字符串跟 sql server 数据库连接字符串类似,可以在连接字符串中指定其他选项,唯一的区别在于不同配置之间使用“英文逗号”分割,如下:

// 配置间用 "英文逗号" 分隔,选项用 "=等号" 以键值对的形式表示
//使用  redis0 和 redis1 这 2 个节点,端口均为 6380,并同时设定 allowAdmin 为 true
var conn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,allowAdmin=true");
  • 注意,选项是用 “=” 号来区分属性和值,如这里的 allowAdmin,如果没有”=”号,会被识别为一个服务器节点。

字符串配置和配置实例之间的转换

字符串配置和 ConfigurationOptions 实例之间可以很方便的转换,如下:

// 配置字符串
var operationString = $"{_redisSettings.Address}:{_redisSettings.Port}";
// 配置字符串---->ConfigurationOptions 实例
var options = ConfigurationOptions.Parse(operationString);

//ConfigurationOptions 实例---->配置字符串
var operationString = options.ToString()

一个常规用法的例子

  • 一般将一些静态参数直接用字符串的形式表示,而一些动态参数用 ConfigurationOptions 对象来进行赋值
    • 静态参数:redis 连接字符串,虽然你可能会放到配置文件/配置系统系统中,但基本上可以认为连接字符串是”静态的“。
    • 动态参数:诸如客户端名,是否运行执行管理员命令等。

例子:

public RedisClient(IOptions<RedisSettings> redisSettings)
{
    _redisSettings = redisSettings.Value;
    var options = ConfigurationOptions.Parse($"{_redisSettings.Address}:{_redisSettings.Port}");

    options.ClientName = ConfigService.GetRedisClientName(); //动态从配置中心取
    options.AllowAdmin = ConfigService.GetIsAllowAdminOperation(); //动态从配置中心取

    var redis = ConnectionMultiplexer.Connect(options);
    _db = redis.GetDatabase(_redisSettings.DataBase);
}

配置选项说明

字符串配置方式 ConfigurationOptions 配置方式 默认值 说明
abortConnect={bool} AbortOnConnectFail true(Azure 中为 false) 若设定为 true,则当所有 redis 服务均不可用时,客户端不会自动创建连接。
allowAdmin={bool} AllowAdmin false 是否能使用风险命令,如 FLUSHDB 之类的命令。
channelPrefix={string} ChannelPrefix null 用于设定”发布/订阅“操作的频道前缀。
connectRetry={int} ConnectRetry 3 设定初始化连接时重试次数。
connectTimeout={int} ConnectTimeout 5000 单位:毫秒,用于设定连接超时时间。
configChannel={string} ConfigurationChannel __Booksleeve_MasterChanged 设定当配置更改时的广播频道名称。
configCheckSeconds={int} ConfigCheckSeconds 60 单位:秒,用于设定检查配置的时间。可以利用该配置来充当心跳包功能。
defaultDatabase={int} DefaultDatabase null 设定默认数据库,
keepAlive={int} KeepAlive -1 用于设定”会话保持“时间,默认情况下,客户端会每 60s 发送一条消息到服务端以保持 socket 连接
name={string} ClientName null 标识在 redis 中的连接名/客户端名
password={string} Password null 用于设定 Redis 连接密码
proxy={proxyType} Proxy Proxy.None 设定代理类型,枚举 Proxy.None 或 Proxy.Twemproxy
resolveDns={bool} ResolveDns false 用于设定是否在连接前解析 DNS 终结点。若为 true,则在连接失败后重新建立连接的时候,先解析 DNS 终结点。
responseTimeout={int} ResponseTimeout SyncTimeout 单位:毫秒,响应超时时间,不建议使用,已经被标记为 Obsolete。
serviceName={string} ServiceName null (截至本文发布,客户端尚未实现Sentinel相关功能)用于通过sentinel解析服务的服务名。
ssl={bool} Ssl false 显式指定是否使用 SSL 加密。
sslHost={string} SslHost null 设定使用 SSL 证书时的主机地址,一旦设定了该值,说明启用 SSL 模式。
sslProtocols={enum} SslProtocols null 设定加密连接协议,使用 ‘或运算符’ 来提供多个值,使用的是 SslProtocols 枚举值。
syncTimeout={int} SyncTimeout 5000 单位:毫秒,设定同步超时的时间
tiebreaker={string} TieBreaker __Booksleeve_TieBreak 主从部署的时候,当master节点挂掉的时候,用于显式设定主节点,设定的时候终结点必须完全匹配
version={string} DefaultVersion 2.0(Azuer中为3.0) 设定Redis的版本号,当且仅当Redis服务端没有设定版本的时候有效
writeBuffer={int} WriteBuffer 4096 设定输出缓冲区的大小,不建议使用,已经标记为[Obsolete]
  • twemproxy: 由 Twitter 开源的一套代理机制,解决了 Redis 单实例承压问题,可以将多个 redis 服务器作为一个服务器来使用,类似于集群,更多 关于 twemproxy 可见此
  • 默认情况下,当未开启 SSL 时,默认端口号为 6380,当开启 SSL 的时候,默认端口号为 6379。
  • 在使用字符串配置的时候,使用”$”作为前缀来表示 CommandMap,如下:
    • 通过 CommandMap,可以显式指定哪些命令可用,哪些命令不可用,以及设定命令的别名。

例1:禁用 CONFIG,INFO命令

public RedisClient(IOptions<RedisSettings> redisSettings)
{
    _redisSettings = redisSettings.Value;
    var options = new ConfigurationOptions
    {
        EndPoints =
         {
             { _redisSettings.Address, Convert.ToInt32(_redisSettings.Port) },
             { "127.0.0.1", 6380 }
         },
        CommandMap = CommandMap.Create(new HashSet<string>
        {
            "CONFIG","INFO"
        }, false), //禁用 CONFIG 和 INFO 命令
        KeepAlive = 300,
        DefaultVersion = System.Version.Parse("5.0.6")

    };
    var temp = options.ToString();//结果为:"192.168.117.43:6379,127.0.0.1:6380,keepAlive=300,version=5.0.6,$CONFIG=,$INFO="
    var redis = ConnectionMultiplexer.Connect(options);
    _db = redis.GetDatabase(_redisSettings.DataBase);
}

例2:通过 CommandMap 来实现禁用命令和设置命令别名

public RedisClient(IOptions<RedisSettings> redisSettings)
{
    _redisSettings = redisSettings.Value;
    var options = new ConfigurationOptions
    {
        EndPoints =
         {
             { _redisSettings.Address, Convert.ToInt32(_redisSettings.Port) },
             { "127.0.0.1", 6380 }
         },
        CommandMap = CommandMap.Create(new Dictionary<string,string>
        {
            {"CONFIG",string.Empty }, //值为null/string.Empty,均表示禁用该命令
            {"INFO","DISP" } //设定INFO的别名为 DISP
        }),
        KeepAlive = 300,
        DefaultVersion = System.Version.Parse("5.0.6")
    };

    var temp = options.ToString();//结果为:"192.168.117.43:6379,127.0.0.1:6380,keepAlive=300,version=5.0.6,$CONFIG=,$INFO=DISP"

    var redis = ConnectionMultiplexer.Connect(options);
    _db = redis.GetDatabase(_redisSettings.DataBase);
}

常言道:学然后知不足,教然后知困。

我知道你的焦虑,一起共进加油:P

关不关注都无所谓,会根据生活节奏紧凑度定期分享些开发经验、搬砖生涯、痛点、感悟。

欢迎关注我的订阅号:P