Redis 常见数据结构以及使用场景?
• String
–介绍 :string 数据结构是简单的 key-value 类型。虽然 Redis 是用 C 语言
写的,但是 Redis 并没有使用 C 的字符串表示,而是自己构建了一种
简单动态字符串(simple dynamic string,SDS)。最大能存储 512MB。
–常用命令: set,get,strlen,exists,decr,incr,setex 等等。
–应用场景: 计数、缓存文章标题、微博内容等。
• List
–介绍 :list 即是 链表。链表是一种非常常见的数据结构,特点是易于数据
元素的插入和删除并且可以灵活调整链表长度,但是链表的随机访问困
难。最多可存储 232 - 1 元素(4294967295, 每个列表可存储 40 亿)
–常用命令: rpush,lpop,lpush,rpop,lrange,llen 等。
–应用场景: 发布与订阅或者说消息队列。
• Hash
–介绍 :hash 类似于 JDK1.8 前的 HashMap,内部实现也差不多(数组 + 链
表)。不过,Redis 的 hash 做了更多优化。另外,hash 是一个 string 类
型的 field 和 value 的映射表, 特别适合用于存储对象,后续操作的时
候,你可以直接仅仅修改这个对象中的某个字段的值。 比如我们可以
hash 数据结构来存储用户信息,商品信息等等。每个 hash 可以存储
232 -1 键值对(40 多亿)
–常用命令:hset,hmset,hexists,hget,hgetall,hkeys,hvals 等。
–应用场景: 系统中对象数据的存储。
• Set
–介绍 : set 类似于 Java 中的 HashSet 。Redis 中的 set 类型是一种无序
集合,集合中的元素没有先后顺序。当你需要存储一个列表数据,又不
希望出现重复数据时,set 是一个很好的选择,并且 set 提供了判断某
个成员是否在一个 set 集合内的重要接口,这个也是 list 所不能提供
的。可以基于 set 轻易实现交集、并集、差集的操作。比如:你可以将
一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。
Redis 可以非常方便的实现如共同关注、共同粉丝、共同喜好等功能。
这个过程也就是求交集的过程。最大的成员数为 232 -1(4294967295, 每
个 集合可存储 40 多亿个成员)。
–常用命令:sadd,spop,smembers,sismember,scard,sinterstore,sunion 等。
–应用场景: 需要存放的数据不能重复以及需要获取多个数据源交集和并集
等场景
• SortedSet(zset)
–介绍:SortedSet 和 set 相比,SortedSet 增加了一个权重参数 score,使得
集合中的元素能够按 score 进行有序排列,还可以通过 score 的范围来
获取元素的列表。有点像是 Java 中 HashMap 和 TreeSet 的结合体。
–常用命令:zadd,zcard,zscore,zrange,zrevrange,zrem 等。
–应用场景: 需要对数据根据某个权重进行排序的场景。比如在直播系统中,
实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可
以理解为按消息维度的消息排行榜)等信息。
Redis 的缓存雪崩、缓存穿透、缓存击穿
• 缓存穿透
–缓存穿透:缓存中和数据库中都没有所查询的东西,从而使数据库崩掉。
–解决方案:将一条数据库不存在的数据也放入缓存中这样即使数据库不存在,但缓存中有,还可以使用布隆过滤器。
• 缓存击穿
–缓存击穿:缓存中没有但数据库中有,如果同一时间访问量过大会使数据崩掉。
–解决方案:加分布式锁,一条数据访问数据库;将数据存储到缓存中,其他线程从缓存中拿。
• 缓存雪崩
–缓存雪崩:缓存中的数据正好在一个时间删除,当请求来时穿过缓存访问数据库。
–解决方案:1.提前预热;2.设置随机缓存中数据的过期时间;3.做缓存备份
Redis 内存淘汰策略?
Redis 提供 6 种数据淘汰策略:
• volatile-lru (least recently used) ):从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
• volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期
的数据淘汰
• volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
• allkeys-lru (least recently used) ):当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)
• allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
• no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。这个应该没人使用吧!
4.0 版本后增加以下两种:
• volatile-lfu (least frequently used) ):从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰
• allkeys-lfu (least frequently used) ):当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的 key