1. redis存储结构:
- redis有0-15个db空间,每个db空间内存key-value
- redis的db 类似于db的命名空间, 但是没有隔离,如果没有特殊需求,请不要使用Redis的其他db
-
对于cluster模式, 只有db0, 也不支持select
2. 数据结构
2.1 string 类型:(bitmap只是string的一个扩展)
value 可以是字符串、浮点或者整数
对于整数,可以支持incr ,执行原子递增、递减,用于计数器-
内部数据结构:
i. int用来存放整型数据
ii. sds(simple dynamic string)存放字节/字符串和浮点型数据
sdsnewlen根据长度去判断使用哪种sdshdr, sdshdr16 长度为2^16 -1
当需要对sds进行修改时, 会在执行操作前,检查sds空间是否足够,如果不够先扩展SDS空间
用途: 共享session, ip限制, 短信验证(手机号限制)
2.2 list 列表
-
存储结构:3.2 以后是quicklist, 双向链表, 节点ziplist(有点像数组), 有时候会对ziplit进行压缩, 即quicklistLZF (LZF是一种无损压缩算法)
应用:
i. 栈: 先进后出 lpush lpop
ii. 队列: 先进先出 lpush rpop
iii. 消息队列: lpush brpop
2.3 hash 字典:
命令格式: redis命令 key field1 value1 [field2 value2]
value 不能嵌套其他类型-
存储结构:
dictht[0], dictht[1], 用于rehash, 从dictht[0] rehash到dictht[1], 每个dictht类似于java中的hashmap, 使用拉链法解决hash冲突
应用: 存储用户信息, key是用户id, value是用户信息
2.4 set 集合(无序)
- 数据结构:
i. intset(只包含整数型元素) 将整数元素顺序存储, 二分法查找降低时间复杂度
ii. hashtable: 只用key, vlaue(null) - 使用场景:
标签, 根据标签去推荐
交集: 共同爱好
差集: 不同点
2.5 zset 有序集合: 每个元素都关联一个score, 按score排序
-
数据结构:
i. ziplist:
(member长度小于 max_ziplist_value(可以修改,默认64字节))
ii. 同时使用skiplist+ hashtable:
a. 通过指针, 指向相同的元素的成员和分值, 所以并没有浪费太多的空间
b. 同时使用两种数据结构是出于性能上的考虑, zscore使用字典, zrank,zrange使用跳表
c. 跳表在插入元素时, 随机生成层数
2.6 geo 和地理位置相关的
- geoadd: 添加一个或多个经纬度地理位置
GEOADD Guangdong-cities 113.2278442 23.1255978 Guangzhou 113.106308 23.0088312 Foshan - geodist: 求两个位置的距离
GEODIST Guangdong-cities Qingyuan Guangzhou km - geohash: 返回一个位置或多个位置的hash值表示
- geopos: 返回给定元素的经纬度信息
- georadius: 查询特定范围内地点
2.7 HyperLogLog(估算基数个数, 占用用内存小)
- 可以接受多个元素作为输入,并给出输入集合中不同元素的数量值。比如 {'apple', 'banana', 'cherry', 'banana', 'apple'} 的基数就是 3 。
- 估算值:算法给出的基数并不是精确的,可能会比实际稍微多一些或者稍微少一些,但会控制在合理的范围之内。
- 优点是,即使输入元素的数量或者体积非常非常大,计算基数所需的空间总是固定的、并且是很小的。
- 但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以HyperLogLog 不能像集合那样,返回输入的各个元素。
i. pfadd
ii. pfcount
3. 其他命令
3. 1 过期时间(expire,setex, 单位s)
- 原理:(有延迟,2.6以后,延迟将为1ms内)
i. 消极删除: 访问时发现过期,然后删除
ii. 积极删除: 周期性从设置了过期时间的key中选择一部分去删除(防止一些key永远都不会被访问) - TTL可以查看过期时间,返回结果(-2: key 不存在, -1: 没有设置过期时间, 整数:过期时间)
- 条件允许的话打散过期时间,防止集中过期
4.1 pub/sub
- producer-> channel <- consumer , channel 可以是全名称或者正则表达式
- publish channl.name "hello"
返回订阅者的数量,因为消息发出去之后不会持久化,所以如果没有订阅者,则消息会丢失 - subscribe channel.name
应用: 站内通信
参考文献:
- 深入浅出Redis-redis底层数据结构(上) https://www.cnblogs.com/jaycekon/p/6227442.html
- 深入浅出Redis-redis底层数据结构(下)
https://www.cnblogs.com/jaycekon/p/6277653.html