StackExchange.Redis 系列 4:Keys, Values and Channels 说明

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

Keys

  • 在 redis 的数据库中,key 是唯一的。
  • 在集群或者分片系统中,key定义了包含该数据的节点,因此 key 对于 routing commands而言相当重要。
  • 在 StackExchange.Redis 中,通过 RedisKey 这个类型来表示 keys。内部已经做好了 string 和 byte[] 类型之间的转换。并且允许你使用”字符串“作为键,或者”字节数组“作为键,如:

string key = ...;
db.StringIncrement(key);
//以上命令等价于
byte[] key = ...
db.StringIncrement(key);
  • StackExchange.Redis 提供了获取 key 的操作,且相当便利,如下:

//随机获取一个 db 中的 key
string randomKey = db.KeyRandom();

Values

  • 跟 key 不同,values 是你存储的东西(单独存储(如 String),或者批量存储,如(如Hash,List 等))。
  • values 不影响路由命令(注:不包括显式使用 BY 或者 GET 的排序(SORT) 命令)。
  • redis 中的值是自解释的,最终由 redis 自己,根据不同的操作指令来进行解释,如:
    • incr (及其他类似方法):会把 String Values 作为 数值。
    • 排序会使用数值或者 unicode 规则来进行。
    • 其他。

数据类型转换

  • StackExchange.Redis 使用 RedisValue 类型来表示 redis 中存储的值。StackExchange.Redis 为该类型提供了隐式转换,大多数情况下你不需要显式进行转换,如在设置的时候,可以直接使用字符串(而不需要显式转换为 RedisValue):

db.StringSet("mykey", "myvalue");
  • 其他可以隐式转换为 RedisValue 的 .NET 数据类型有 Int32,Int64,Double,Boolean 等。
    • 当你需要从 RedisValue 转换为 .NET 数据类型的时候,需要显式转换,如下:

db.KeyDelete("abc");
int i = (int)db.StringGet("abc"); // this is ZERO

检测 key 对应的 value 是否为 “nil无值”

nil 和 null 在本质上是不一样的,前者偏向于对象,后者偏向于指针,但在使用 StackExchange.Redis 库的时候,你可以把 nil 等效于 null 来使用。

db.KeyDelete("abc");
var value = db.StringGet("abc");
bool isNil = value.IsNull; // true
//也可以直接使用 可空类型 来进行转换,如下:
db.KeyDelete("abc");
var value = (int?)db.StringGet("abc"); // value=null

hash 数据类型中的 ”hashkey“

  • hash 类型中的 field(hashkey) 跟 key 是不同的,它们不影响命令路由,严格意义上来说,它们并非 key,但(field/hashkey)依然可以通过“文本和二进制”来进行命名,对于 API 而言,它们算是 Values。

Channels

  • 使用 pub/sub 的时候会用到 频道(channels)。
  • 频道名称由 RedisChannel 数据类型来表示,该类型跟 RedisKey 很类似,但两者是独立处理的。同样 channels 不影响命令路由
  • 频道和 key 以及 value 是完全不同的东西,需区别对待。

Scripts

  • redis 内部使用给 lua 脚本,有 2 个特征:
    • 输入的时候,需要把 key 和 value 分开输入设置,在脚本内部会自动分别变成 KEYS 和 ARGV。
    • 根据你的脚本来返回特定的数据格式,并非提前定义。
  • 介于以上 2 个特征,ScriptEvaluate(StackExchange.Redis 2.x版本已经取消同步方法,改用 ScriptEvaluateAsync) 方法的签名如下:
  • 使用 ScriptEvaluateAsync 的时候,需要显式指定 RedisKey[] 和 RedisValue[] 数据类型,这里无法自动隐式转换。
  • ScriptEvaluateAsync 的返回数据类型为 Task,这是使用 Scripts 时的特有类型,该类型提供了一定范围的转换,比 RedisValue 更多,如下:

结论

StackExchange.Redis 针对 “键-值” 提供了 RedisKey,RedisValue 数据类型,以及 RedisChannel,RedisResult。大部分情况下,你都可以无感操作这些数据类型,客户端已经为你做好了很多隐式转换。