(1)Redis常用的数据结构有哪些?
五种常用数据结构:String、Hash、Set、List、SortedSet/Zset。
三种特殊的数据结构:Bitmap、HyperLogLog、Geospatial ,其中Bitmap、HyperLogLog的底层都是 String 数据类型,Geospatial 的底层是 Sorted Set/Zset 数据类型。
五种常用的数据结构:
1、String:String是最常用的一种数据类型,普通的key- value存储都可以归为此类。其中Value既可以是数字也可以是字符串。使用场景:常规key-value缓存应用。常规计数: 微博数,粉丝数。
2、Hash:Hash是一个键值(key => value)对集合。Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象,并且可以像数据库中update一个属性一样只修改某一项属性值。
3、Set:Set是一个无序的天然去重的集合,即Key-Set。此外还提供了交集、并集等一系列直接操作集合的方法,适用于实现共同好友、共同关注的功能。
4、List:List是一个有序可重复的集合,其遵循FIFO的原则,底层是依赖双向链表实现的,因此支持正向、反向双重查找。通过List,可以实现最新回复这类的功能。
5、SortedSet/Zset:类似于java中的TreeSet,是Set的可排序版。此外还支持优先级排序,维护了一个score的参数来实现。适用于排行榜和带权重的消息队列等场景。
三种特殊的数据结构:
1、Bitmap:Bitmap位图,想象成一个以位为单位数组,数组中的每个单元只能存0或者1,数组的下标在Bitmap中叫做偏移量。使用Bitmap实现统计功能,更省空间。如果只需要统计数据的二值状态,例如商品有没有、用户在不在等,就可以使用 Bitmap,因为它只用一个 bit 位就能表示 0 或 1。
2、Hyperloglog:HyperLogLog是一种用于统计基数的数据结构,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。场景:统计网页的UV(Unique Visitor,不重复访客,一个人访问某个网站多次,但是还是只计算为一次)。
3、Geospatial:主要用于存储地理位置信息,并对存储的信息进行操作,适用场景如朋友的定位、附近的人、打车距离计算等。
(2)String 的应⽤场景有哪些?
常规数据的缓存(⽐如 session、token、、序列化后的对象);
计数,⽐如微博数、粉丝数、⽤户单位时间的请求数、⻚⾯单位时间的访问数;
分布式锁(利⽤ SETNX 命令可以实现⼀个最简易的分布式锁);
(3)String 还是 Hash 存储对象数据更好呢?
在绝⼤部分情况,建议使⽤ String 来存储对象数据。String 存储相对来说更加节省内存,缓存相同数量的对象数据,String 消耗的内存约是 Hash 的⼀半。String 存储的是序列化后的对象数据,存放的是整个对象。Hash 是对对象的每个字段单独存储,hash可以获取部分字段的信息,也可以修改、添加部分字段。如果对象中某些字段需要经常变动或者经常需要单独查询对象中的个别字段信息,Hash 就⾮常适合。比如存储购物⻋信息。
(4)使⽤ Redis 实现⼀个排⾏榜怎么做?
sorted set/zset的数据结构经常被⽤在各种排⾏榜的场景,⽐如直播间送礼物的排⾏榜、朋友圈的微信步数排⾏榜、王者荣耀中的段位排⾏榜、话题热度排⾏榜等等。
(5)使⽤ Set 实现抽奖系统需要⽤到什么命令?
SPOP key count:随机移除并获取指定集合中⼀个或多个元素,适合不允许重复中奖的场景。
SRANDMEMBER key count : 随机获取指定集合中指定数量的元素,适合允许重复中奖的场景。
(6)使⽤ Bitmap 统计活跃⽤户怎么做?
使⽤⽇期(精确到天)作为 key,然后⽤户 ID 为 offset,如果当⽇活跃过就设置为 1。通过这种方式,Redis位图可以高效地存储和查询海量用户的活跃状态。
(7)使⽤ HyperLogLog 统计⻚⾯ UV 怎么做?
为每个需要统计UV的页面创建一个唯一的HyperLogLog键,每当有新的用户访问页面时,将该用户的唯一标识符(如用户ID)作为元素添加到HyperLogLog集合中。当需要获取页面的不重复访客数量(UV)时,可以直接使用PFCOUNT命令来获取HyperLogLog集合的基数。注意,这个统计基数是有一定误差的(0.81%)。