Redis学习总结—数据结构 (二)

Redis 除了有五种常用的数据类型外,还有几种特殊的数据类型,主要用来实现一些特定的场景数据存储。

HyperLogLog

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。Redis HyperLogLog 是用来做基数 (不重复的元素) 统计的算法,HyperLogLog 的优点是,对海量数据的计算基数统计所需的空间是固定的且很小,计算速度很快。
在 Redis 里面,每个 HyperLogLog 键只需要12 KB 的内存,就可以计算接近 264个不同元素的基数,不过数据量较小时,HyperLogLog 会占用实际使用的内存大小。但是 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,可以返回输入的各个元素。
另外,HyperLogLog 的统计规则是基于概率完成的,它给出的统计结果是有一定误差的,标准误算率是 0.81%。

HyperLogLog 通过存储元素的hash值的第一个1的位置,来计算元素数量。该结构在内存计算中使用固定的16384个桶(214),它有两种存储格式:
稀疏格式:HyperLogLog算法在刚开始的时候,大多数桶其实都是0,稀疏格式通过存储连续的0的数目,而不是每个0存一遍,大大减小了HyperLogLog刚开始时需要占用的内存。
紧凑格式:用6个bit表示一个桶,需要占用12KB内存。

HyperLogLog 常用操作命令

PFADD key element [element ...]  #添加指定元素到HyperLogLog中。
PFCOUNT key [key ...]  #返回给定的HyperLogLog的基数估算值。
PFMERGE destkey sourcekey [sourcekey ...]  #将多个HyperLogLog合并为一个HyperLogLog

场景应用

1,HyperLogLog 常用于统计网页的UV,网站访问IP数,在线用户数,搜索的词条个数等。

常见问题

1,为什么 HyperLogLog 的内存占用最多是12k?
因为 Redis 的 HyperLogLog 在实现中用到的是16384个桶,也就是214,每个桶的maxbits需要6个bits来存储,最大可以表示maxbits=63,总共占用内存就是214 * 6 / 8 = 12k 字节。

GEO 地理位置

Redis 3.2 版本中,新增加了存储地理位置信息的功能,即 GEO(geographic),它的底层通过 Redis 有序集合(zset)实现。不过 Redis GEO 并没有与 zset 共用一套的命令,而是拥有自己的一套命令。

GEO 常用操作命令

GEOADD key longitude latitude member [longitude latitude member ...]  # 将指定的地理空间位置(key后依次是位置的经度、纬度、名称)添加到指定的key中,以Zset的形式存储。

注意:
longitude 经度值取值范围是-180度 - 180度,
latitude 纬度值取值范围是-85.05112878度 - 85.05112878度。
当经纬度取值超过取值范围时会返回一个错误。

GEODIST key member1 member2 [m|km|ft|mi]  #获取两个地理位置间的距离,单位默认是米。

取值:
m 表示单位为米;
km 表示单位为千米;
mi 表示单位为英里;
ft 表示单位为英尺。
计算举例时存在0.5%左右的误差,这是因为Redis GEO把地球假设成了完美的球体。

GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]  #根据给定的经纬度为中心,计算出key包含的地理位置元素与中心的距离不超过给定最大距离的所有位置元素,并返回。

参数:
WITHDIST :在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。
WITHCOORD :返回位置元素的经度和维度。
WITHHASH :采用 GEOHASH 对位置元素进行编码,以 52 位有符号整数的形式返回有序集合的分值,该选项主要用于底层调试,实际作用不大。
COUNT:指定返回位置元素的数量,在数据量非常大时,可以使用此参数限制元素的返回数量,从而加快计算速度。
ASC|DESC:将返回的数据元素按从近到远或从远到近的顺序排列。

GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DES]  #根据给定的元素member的地理位置坐标(即经纬度)为中心,获取指定范围内的位置元素集合。同GEORADIUS类似,只是中心点设置不同。
GEOHASH key member [member ...]  #获取一个或多个位置元素的geohash值。
GEOPOS key member [member ...]  #从给定的key里返回所有指定名称(member)的位置(经度和纬度),不存在的返回nil。
ZREM key menber [menber ...]  #删除指定的地理位置元素。

场景应用

1,定位系统中的距离远近提示,例如外卖,打车软件中提示的“距离多少米”。数据库中存放着商家所处的经纬度,你的位置通过手机定位获取,计算最终的距离。
2,软件中附近的人、摇一摇、实时定位等。

Stream 消息队列

Stream 是 Redis 5.0 版本引入的一种新数据类型,同时它也是 Redis 中最为复杂的数据结构。它实际是一个具有消息发布/订阅功能的组件,借鉴了 Kafaka 系统。

Stream 消息队列主要由四部分组成,分别是:消息本身、生产者、消费者和消费组。
在这里插入图片描述
Stream direction:表示数据流,它是一个消息链,将所有的消息都串起来,每个消息都有一个唯一标识 ID 和对应的消息内容(Message content)。
Consumer Group :表示消费组,拥有唯一的组名,使用 XGROUP CREATE 命令创建。一个 Stream 消息链上可以有多个消费组,一个消费组内拥有多个消费者,每个消费者都有一个唯一的 ID 标识。
last_delivered_id :消费组内的游标,每个消费组都会有一个游标,任意一个消费者读取了消息。游标就往前移动。
pending_ids :PEL,消费者的状态变量,维护消费者的未确认 (ACK) 的消息ID,记录已经被客户端读取但还未返回ACK的消息。如果有消息被 ACK,它就会减少。

ACK(Acknowledge character)即确认字符,在数据通信中,接收方传递给发送方的一种传输类控制字符。表示发来的数据已确认接收无误。 ACK 信号有自己固定的格式,长度大小。

Strean 相较于发布订阅 (pub/sub) 的优势是 Stream 提供了消息的持久化存储及主从复制功能,从而解决了网络断开、Redis 宕机情况下,消息丢失的问题,即使重启 Redis,存储的内容也会存在。

Stream 常用操作命令

消息队列相关命令:
XADD key ID field value [field value ...]  #添加消息到指定队列(key)的末尾,ID是消息ID,如果是*,表示由redis自己生成;自定义ID的话需要保证递增性。返回值是毫秒时间戳格式的字符串,如 1632157620063-1,表示在该毫秒内产生的第1条消息
XTRIM key MAXLEN [~] count  #对流进行修剪,限制长度(MAXLEN)。count是指定的长度数量
XDEL key ID [ID ...]  #删除队列中指定的消息
XLEN key  #获取流包含的元素数量,即消息长度
XRANGE key start end [COUNT count]  #获取指定数量的消息列表,会自动过滤已经删除的消息。start开始值,用 - 表示最小值;end结束值,用 + 表示最大值
XREVRANGE key end start [COUNT count]  #反向获取消息列表,ID从大到小,同XRANGE相反
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]  #以阻塞或非阻塞方式获取指定数量的消息列表。milliseconds阻塞毫秒数,没有设置就是非阻塞模式
消费者组相关命令:
XGROUP [CREATE key groupname id-or-$] [SETID key groupname id-or-$] [DESTROY key groupname] [DELCONSUMER key groupname consumername]
XGROUP CREATE key groupname id-or-$  #创建消费者组。id是需要传递的起始消息的ID,为0-0表示从头开始消费,为$表示从尾部开始消费,只接受新消息,当前 Stream 消息会全部忽略。
XREADGROUP GROUP groupname consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]  #读取消费者组中的消息。groupname是消费者组名,consumer是消费者名,count是读取的数量
XACK -  #将消息标记为"已处理"
XGROUP SETID -  #为消费者组设置新的最后递送消息ID
XGROUP DELCONSUMER -  #删除消费者
XGROUP DESTROY -  #删除消费者组
XPENDING -  #显示待处理消息的相关信息
XCLAIM -  #转移消息的归属权
XINFO -  #查看流和消费者组的相关信息;
XINFO GROUPS -  #打印消费者组的信息;
XINFO STREAM -  #打印流信息

bitmap 位图操作

位图(bitmap)属于 string 数据类型。Redis 中一个字符串类型的值最多能存储 512 MB 的内容,每个字符串由多个字节组成,每个字节又由 8 个 Bit 位组成。位图正是使用“位”来实现存储的,它将比特位设置为1或0来存取数据,大大增加了 value 的存储数量,存储上限为232
bitmap 本质上是一个 bytes 数组,常用作 bool 类型数据的存取,是就为1,否则为0。结构如下
在这里插入图片描述

bitmap 常用操作命令

SETBIT key offset value  #设置或者清除某一位上的值,返回值是原来位上存储的值。初始状态下位的值都是0
GETBIT key offset  #获取某一位的值,offset比字符串长度大或不存在时返回0
BITCOUNT key [start end]  #统计指定区间上值为1的数量,start和end为指定区间的开始结束位置,为负数时表示从尾端开始

场景应用

1,某段时间内用户的签到次数,登录次数等。用户ID为key,签到设置值为1,未签到值为0。
2,网页的活跃用户数。时间为key,用户ID为 offset 偏移量,用户活跃过,就设值为1。

参考资料:
http://c.biancheng.net/redis/hyperloglog.html
http://c.biancheng.net/redis/geo.html
http://c.biancheng.net/redis/streams.html
http://c.biancheng.net/redis/bitmap.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值