dbsize的时间复杂度为O(1),keys的时间复杂度为O(n)。
Redis的数据类型(使用type命令查看)和内部编码结构/类型(使用object encoding命令查看):
类型type | 编码方式object encoding | 特点 | 编码转换触发条件 |
---|---|---|---|
string | raw动态字符串编码 | 大于39个字节 | 大于39个字节的字符串,也就是短字符串 |
embstr字符串编码 | 优化了内存分配,小于等于39个字节 | 小于等于39个字节的字符串,也就是长字符串 | |
int整数编码 | 8个字节的长整型 | 整数类型 | |
hash | hashtable散列表 | 普通散列表 | value最大空间(字节)>hash-max-ziplist-value或field个数>hash-max-ziplist-entries |
ziplist压缩列表 | 节省内存,读写最坏O(n^2) | value最大空间(字节)<=hash-max-ziplist-value且field个数<=hash-max-ziplist-entries | |
list | linkedlist双向链表 | 普通双向链表 | value最大空间(字节)>list-max-ziplist-value或链表长度>list-max-ziplist-entries |
ziplist压缩列表 | 节省内存,读写最坏O(n^2) | value最大空间(字节)<=list-max-ziplist-value或链表长度<=list-max-ziplist-entries | |
quicklist快表/快速列表3.2版本后 | 全局linkedlist,每个节点ziplist | 3.2后废弃list-max-ziplist-value和list-max-ziplist-entries 使用新配置: list-max-ziplist-size最大压缩空间/长度 list-compress-depth最大压缩深度。默认为0不压缩 |
|
set | hashtable散列表 | 普通散列表 | 元素非整数类型或集合长度>set-max-intset-entries |
intset整数集合 | 只存储整数,内部整数长度变长可能导致自动升级,节省内存 | 元素必须为整数且集合长度<=set-max-intset-entries | |
zset | skiplist跳表/跳跃表 | value最大空间(字节)>zset-max-ziplist-value或有序集合长度>zset-max-ziplist-entries | |
ziplist压缩列表 | 节省内存,读写最坏O(n^2) | value最大空间(字节)<=zset-max-ziplist-value且有序集合长度<=zset-max-ziplist-entries |
Redis使用了单线程架构和I/O多路复用模型来实现高性能的服务。
Redis为什么快:
- 纯内存访问,纳秒级。
- 非阻塞I/O,Redis使用epoll作为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间。
- 单线程避免了线程切换和竞态消耗。
string类型
string底层可以存储字符串,数字,二进制。
Redis的批处理命令:N次get时间=1次网络时间+N次命令时间。使用时需要小心每次批处理操作时操作的数据过多,有可能会造成阻塞和网络拥塞。
string使用场景:缓存、计数、共享Session、限速(通过计数)等。
缓存功能:加速读写、降低后端压力。
因为Redis没有命名空间,所以需要自己维护。推荐的方式:业务名:对象名:id[属性]
hash类型
如果要获取全部field-value,可以使用hscan命令,它会渐进式遍历哈希类型,有效避免阻塞。
hash使用场景:存储对象信息等。
list类型
list元素是有序的,list中的元素可重复。
list使用场景:消息队列、用户的文章列表等。
list口诀:
- lpush+lpop=栈
- lpush+rpop=队列
- lpush+ltrim=有限集合
- lpush+brpop=消息队列
set类型
set中元素无序,不重复。
set使用场景:标签(用户和标签的关系维护应当在一个事务内执行)等。
zset类型
zset中元素不重复,但是有序(每个元素设置了一个分数score)。
zset的add的时间复杂度为O(log(n))
zset的使用场景:排行榜系统等。
Redis迁移键的方式:move(用于Redis内部迁移,不建议使用)、dump+restore(不同的Redis实例之间迁移,非原子)、migrate(不同Redis实例之间迁移,原子性,可选是否删除源Redis上的key)。
Redis的渐进式遍历就是每次只扫描一个字典中的一部分键。通过游标实现,对应的命令有hscan、sscan、zscan。如果在scan的过程中如果有键的变化,scan不能保证遍历出完全一致的数据。