Redis数据说明

一、使用场景

  • 缓存(会话、结构数据)。
  • 取最新N个数据的。将最新的放在List集合中,使用lpush向list集合中插入数据,插入完成后再用ltrim命令使其永远只保存最新。zset,时间作为score。
  • 取top n。将要排序的值设置成zset的score,将具体的数据设置成相应的value。
  • zset的score设置为过期时间,通过过期时间排序,定时清除过期数据。
  • 利用incr、decr指令实现计数器。
  • set的排重。排重规则?
  • 使用list构建队列、栈、阻塞队列。
  • 使用zset构建优先级队列。

二、键 key

redis本质是一个key-value 内存数据库。key是字符串类型,但是key中不能包括边界字符。由于key不是binary safe的字符串,所以不允许像"my key"和"mykey\n"这样包含空格和换行。但在redis内部并不限制使用binary字符,这是因redis协议限制,"\r\n"在RESP协议会作为特殊字符。redis 1.2以后的协议中部分命令已经开始使用新的协议格式(比如MSET)。总之目前还是把包含边界字符当成非法的key,以免出现bug。

三、值 value

1 string(字符串)

Redis的字符串是动态字符串,是可以修改的,内部结构的实现类似于java的arrayList,采用预分配冗余空间的方式来减少频繁分配内存。最大长度512M。扩容1M。
string类型是二进制安全的。因为string本质上就是byte数组。所以可以包含任何数据。比如jpg图片或者序列化的对象。另外,string类型可以被部分命令按int处理。其他值类型(list, set, sorted set, hash)包含的元素都只能是string类型。

2 list(列表)

Redis的列表相当于java里的linkedList,注意是链表而不是数组。
在列表元素较少时,使用一块连续的内存存储,ziplist,即压缩列表。当数据量较多时,使用quicklist。quicklist是由链表和ziplist组成,也就是将多个ziplist使用双向指针串联起来。
list是双向链表。list会记录链表的长度。链表的最大长度是(2的32次方-1)。可以通过push,pop操作从链表的头部或者尾部添加删除元素。这使得list既可以用作栈,也可以用作队列。pop操作还有阻塞版本。

3 set(集合)

Redis的set相当于java里的hashset,两者的内部键值对都是无序的、唯一的。
set元素最大可以包含(2的32次方-1)个元素。内部是通过hash table实现的。hash table会随着添加或者删除自动的调整大小。调整hash table大小时需要同步(获取写锁),会阻塞其他读写操作。可能会改用跳表(skip list)来实现。set操作类型包含取集合的并,交,差集。通过这些操作可以实现sns中的好友推荐和blog的tag功能。

4 zset(有序集合)

Redis的zset相当于java里的sortedSet和hashmap的结合体。内部使用skip list(跳跃列表)。跳跃列表类似于组织层级。跳跃列表之所以跳跃,是因为内部的元素可以“身兼数职”。
sorted set的实现是skip list和hash table的混合体。sorted set的元素会关联一个double类型的score。当元素被添加到集合中时,一个元素到score的映射被添加到hash table中,另一个score到元素的映射被添加到skip list,并按照score排序。

5 hash(字典)

Redis的hash相当于java里的hashmap。都是“数组+链表”的二维结构。hashmap的再哈希是一次性全部rehash,但redis的是渐进式rehash。
hash适合存储对象。省内存的原因是新建hash对象时开始是用zipmap存储。如果field或者value的大小超出限制后,redis会自动将zipmap替换成正常的hash实现。

6 bitmap(位图)

存储bool型数据,比如职工一年的打卡记录。
setbit、getbit、bitcount(指定范围内1的个数)、bitpos(指定范围内出现的第一个0或1)。

7 hyperloglog

提供不精确的去重计数方案,标准误差是0.81%。
比如,统计每个页面每天的UV。可以为每个页面设置独立的set集合存储当天访问此页面用户ID,但非常浪费空间。
hyperloglog需要占据12KB的存储空间,因此不适合统计单个用户相关的数据。

8 bloomfilter(布隆过滤器)

不精确的set结构,使用contains方法判断某个对象存在时,可能会误判。
当布隆过滤器说某个值存在时,这个值可能不存在,因此有误差;说某个值不存在时,那肯定不存在。常用于判断用户是否浏览某些内容。
Redis4.0提供插件功能后才有布隆过滤器。布隆过滤器中存储的是元素的指纹,而非元素的内容。

9 漏斗限流

Redis4.0提供Redis-Cell限流模块。该模块使用漏斗算法,并提供原子的限流指令。

10 geoHash

Redis3.2提供地理位置Geo模块,实现类似“附近的XX”功能。数据放在zset集合中。
一般地理数据较多,建议geo的数据使用单独的redis实例,而不是集群。

11 stream

stream是一个支持多播的可持久化消息队列。借鉴kafka。

12 scan

keys指令的是遍历算法。其他scan:zscan hscan sscan。
scan特点:

  • 复杂度是O(n),但是通过游标分步进行,不会阻塞线程。
  • 提供limit参数,控制每次返回结果最大数目,但只是hint,结果可能多也可能少。不确定性。
  • 提供模式匹配。
  • 服务器不保存游标状态,游标的唯一状态是scan给客户端的游标整数。
  • 返回结果可能重复。不确定性。
  • 遍历中数据有修改,改动后的数据有可能遍历不到。不确定性。
  • 游标值为零才意味着遍历结束,而不是返回结果为空时就结束。

参考

《Redis深度历险-核心原理与应用实践》

你可能感兴趣的:(Redis数据说明)