Redis数据结构和主要命令

redis 是一个开源的 , 基于内存的结构化数据存储媒介 , 可以作为数据库、缓存服务或消息服务使用 。
Redis 支持多种数据结构 , 包括字符串、哈希表、链表、集合、有序集合、位图、Hyperloglogs 等 。
Redis 具备 LRU 淘汰、事务实现、以及不同级别的硬盘持久化等能力 。
支持副本集和通过 Redis Sentinel 实现的高可用方案 , 同时还支持通过 Redis Cluster 实现的数据自动分片能力 。
Redis 的主要功能都基于单线程模型实现 , 也就是说 Redis 使用一个线程来服务所有的客户端请求 , 同时 Redis 采用了非阻塞式 IO , 并精细地优化各种命令的算法时间复杂度 。
这些信息意味着:
【Redis数据结构和主要命令】Redis 是线程安全的(因为只有一个线程) , 其所有操作都是原子的 , 不会因并发产生数据异常 。
Redis 的速度非常快(因为使用非阻塞式 IO , 且大部分命令的算法时间复杂度都是 O(1)) 。
使用高耗时的 Redis 命令是很危险的 , 会占用唯一的一个线程的大量处理时间 , 导致所有的请求都被拖慢 。(例如时间复杂度为 O(N) 的 KEYS 命令 , 严格禁止在生产环境中使用)
常用命令一:Key
Redis 采用 Key-Value 型的基本数据结构 , 任何二进制序列都可以作为 Redis 的 Key 使用(例如普通的字符串或一张 JPEG 图片)
关于 Key 的一些注意事项:
不要使用过长的 Key 。
例如使用一个 1024 字节的 key 就不是一个好主意 , 不仅会消耗更多的内存 , 还会导致查找的效率降低 。
Key 短到缺失了可读性也是不好的 。
例如”u1000flw” 比起”user:1000:followers” 来说 , 节省了寥寥的存储空间 , 却引发了可读性和可维护性上的麻烦 。
最好使用统一的规范来设计 Key , 比如”object-type:id:attr” , 以这一规范设计出的 Key 可能是”user:1000” 或”comment:1234:reply-to” 。
Redis 允许的最大 Key 长度是 512MB(对 Value 的长度限制也是 512MB)
常用命令二:String
String 是 Redis 的基础数据类型 , Redis 没有 Int、Float、Boolean 等数据类型的概念 , 所有的基本类型在 Redis 中都以 String 体现 。
与 String 相关的常用命令:
SET:为一个 key 设置 value , 可以配合 EX/PX 参数指定 key 的有效期 , 通过 NX/XX 参数针对 key 是否存在的情况进行区别操作 , 时间复杂度 O(1)
GET:获取某个 key 对应的 value , 时间复杂度 O(1)
GETSET:为一个 key 设置 value , 并返回该 key 的原 value , 时间复杂度 O(1)
MSET:为多个 key 设置 value , 时间复杂度 O(N)
MSETNX:同 MSET , 如果指定的 key 中有任意一个已存在 , 则不进行任何操作 , 时间复杂度 O(N)
MGET:获取多个 key 对应的 value , 时间复杂度 O(N)上文提到过 , Redis 的基本数据类型只有 String 。
但 Redis 可以把 String 作为整型或浮点型数字来使用 , 主要体现在 INCR、DECR 类的命令上 。
INCR:将 key 对应的 value 值自增 1 , 并返回自增后的值 。
只对可以转换为整型的 String 数据起作用 。时间复杂度 O(1)
INCRBY:将 key 对应的 value 值自增指定的整型数值 , 并返回自增后的值 。
只对可以转换为整型的 String 数据起作用 。时间复杂度 O(1)
DECR/DECRBY:同 INCR/INCRBY , 自增改为自减 。
INCR/DECR 系列命令要求操作的 value 类型为 String , 并可以转换为 64 位带符号的整型数字 , 否则会返回错误 。
也就是说 , 进行 INCR/DECR 系列命令的 value , 必须在 [-2^63 ~ 2^63 - 1] 范围内 。
Redis 采用单线程模型 , 天然是线程安全的 , 这使得 INCR/DECR 命令可以非常便利的实现高并发场景下的精确控制 。
例 1:库存控制
在高并发场景下实现库存余量的精准校验 , 确保不出现超卖的情况 。
设置库存总量:
SET inv:remain "100"
库存扣减 + 余量校验:
DECR inv:remain
当 DECR 命令返回值大于等于 0 时 , 说明库存余量校验通过;
如果返回小于 0 的值 , 则说明库存已耗尽 。
假设同时有 300 个并发请求进行库存扣减 , Redis 能够确保这 300 个请求分别得到 99 到 - 200 的返回值 , 每个请求得到的返回值都是唯一的 。


推荐阅读