0
点赞
收藏
分享

微信扫一扫

Redis第二章之键类型

艾晓雪 2022-03-12 阅读 57

Redis第二章之键类型

文章目录

普通键类型

字符串

最大不能超过512M

内部编码

  1. int:8个字节的长整型。
  2. embstr:小于等于39个字节的字符串。
  3. raw:大于39个字节的字符串。

Redis会根据当前值的类型和长度决定使用哪种内部编码实现。

哈希

在使用hgetall时,如果哈希元素个数比较多,会存在阻塞Redis的可能。

内部编码

  1. ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀。

  2. hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)。

列表

一个列表最多可以存储2^32-1个元素

内部编码

  1. ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使用。

  2. linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。

集合

内部编码

  1. intset(整数集合):当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实现,从而减少内存的使用。

  2. hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内部实现。

有序集合

内部编码

  1. ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使用。
  2. skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因为此时ziplist的读写效率会下降。

操作:

参考链接:[附A.键类型操作(nodejs版).note] – 未发布

说明:虽然为nodejs版的,但是与其他客户端操作中关键字、返回类型、参数都一致。

特殊键类型

Bitmaps

Bitmaps本身不是一种数据结构,实际上它就是字符串,但是它可以对字符串的位进行操作。

应用场景:统计某段时间内的大量用户是否活跃或商品(两百万个以上才适合使用)是否被访问,比使用其他类型来判断更省内存。

HyperLogLog

HyperLogLog并不是一种新的数据结构(实际类型为字符串类型),而是一种基数算法,通过HyperLogLog可以利用极小的内存空间完成独立总数的统计。

只为了计算独立总数,不需要获取单条数据。

该算法存在一定的偏差,Redis官方给出的数字是0.81%的失误率。

方法:

  1. 添加(pfadd key element [element …])

    直接支持内部去重,添加多个相同的值,结果还是1。

  2. 计算一个或多个key的总数(pfcount key [key …])

    如果是多个key,取的值是他们之间的去重后的个数。

  3. 合并(pfmerge destkey sourcekey [sourcekey …])

    将多个key的值合并到新的key中,合并后原来的key依旧存在。

应用场景:计算网站或者商品的访问量。(与字符串直接存储总数相比,该算法的优势在于不用在程序中去重)

GEO(地理信息定位)

暂时还没研究 =_=

命令使用注意事项

  1. dbsize命令在计算键总数时不会遍历所有键,而是直接获取Redis内置的键总数变量,所以dbsize命令的时间复杂度是O(1)。而keys命令会遍历所有键,所以它的时间复杂度是O(n),当Redis保存了大量键时,线上环境禁止使用。

  2. del命令可以支持删除多个键

  3. 由于Redis的单线程架构,所以需要每个命令能被快速执行完,否则会存在阻塞Redis的可能,理解Redis单线程命令处理机制是开发和运维Redis的核心之一。

  4. 批量操作(例如mget、mset、hmset等)能够有效提高命令执行的效率,但要注意每次批量操作的个数和字节数。

  5. 了解每个命令的时间复杂度在开发中至关重要,例如在使用keys、hgetall、smembers、zrange等时间复杂度较高的命令时,需要考虑数据规模对于Redis的影响。

  6. persist命令可以删除任意类型键的过期时间,但是set命令也会删除字符串类型键的过期时间,这在开发时容易被忽视。

  7. scan命令可以解决keys命令可能带来的阻塞问题,同时Redis还提供了hscan、sscan、zscan渐进式地遍历hash、set、zset。

举报

相关推荐

0 条评论