Redis 字符串保存字节,不固定数据模式
Redis 字符串是在一个键下保存的一段二进制安全字节序列,可以装文本、序列化文档,也可以装十进制计数器。这里的“基础类型”描述的是对外的数据模型,不代表所有 Redis 数据结构都由字符串拼接实现。哈希、列表等类型有各自的命令、内部表示和更新规则,不能只凭字符串命令推断其他类型的行为。 先确定字节,再解释内容 SET 与 GET 能原样存取字节,包括零字节和不是有效 UTF-8 的内容。STRLEN 返回字节数,GETRANGE 的起止位置也是字节偏移,而且两端都包含在结果中,并不是按人眼看到的字符切片。因此,一个范围完全可能只取到某个多字节字符的一部分。客户端是否自动把返回值解码成文本,是另一层选择;任意二进制数据应关闭自动解码,只对应用明确知道编码的内容进行转换。 把 JSON 文本存进去,不会让这个键自动变成 Redis 哈希,也不会让哈希命令获得按字段访问 JSON 的能力。同样,整数命令是在执行时解释现有字节,并没有给这个键设置永久的数字类型约束。序列化方式、键名约定和读写双方对值类型的理解,都需要应用自己维护。文档给出的单个字符串默认上限是 512 MiB,但上限不是推荐负载大小,更不应该拿它作为每个缓存对象的设计目标。 原子自增有明确边界 INCR 把不存在的键当作零,再对十进制有符号六十四位整数执行加一。不能解释为整数的内容和越界运算都会报错,而不是回绕。INCRBY 用来改变步长;INCRBYFLOAT 遵循另一套浮点语义,如果需要精确的整数序列,就不能把它当作等价替代。 一条 INCR 消除了先 GET、再计算、最后 SET 之间的丢失更新窗口。不过,服务器已经完成自增而响应在途中丢失时,客户端重试仍可能再加一次。命令原子性不等于请求幂等,也不意味着经历删除、到期、复制故障或主从切换后还能提供持久且全局唯一的编号。下面的并发实验只验证一个正在运行的实例,不给这些跨故障场景背书。 坏掉的样子 对 JSON 字符串调用 HGET 会得到 WRONGTYPE。普通 SET 则有相反的风险:它能够把已有哈希整体替换成字符串,原来的字段随之丢失。因此需要按值的契约区分键名空间,并检查所有写入方实际使用的命令。某个键过去存过哈希,并不意味着这个名字以后会被 Redis 强制约束为哈希。 ...