redis 经纬度_Redis扩展数据类型

一、简述

前面一篇文章中,我们已经介绍过了《Redis基本数据类型》,这些基本数据类型对于大多数的业务需求都可以很好的满足,但是对于这些基本数据类型,在一些特殊的场景中,却并不一定适用,下面我们来介绍一下Redis提供的一些扩展数据类型和时序数据库模块。

bitmap:基于bit位的存储,每一个bit存储0或1,一般用来进行海量数据的精准判重

HyperLogLog:一般用来对海量数据进行基于概率的基数统计,比如说网站的独立访客数、独立IP数等

Geo:基于地理空间的数据存储,常应用在那些基于位置服务,也就是我们常说的LBS(Location-Based Service)的应用,比如说打车等生活服务类应用

Stream:消息流,Redis自5.0版本之后,引入了消息队列的机制,也就是我们熟悉的Pub/Sub(发布/订阅)机制。

RedisTimeSeries:时间数据库模块,主要存储一些跟时间戳相关,需要范围查询,聚合计算等场景的数据集

二、Bitmap

Bitmap,也叫位图,通过二进制bit中的0或1来表示,某个位置的标记,因为每一个bit都只能是0或1,所以通常用来表示一个数据(通常对应于数组下标)是否已经存在(存在的话,该bit位上是1,否则为0)。下面,我们看看具体的存储结构,如下图所示:

d12e216b704692bd882f3023915568b3.png

其实在Redis中,bitmap是通常字符串来实现的,每一个字符的ASC2编码值代表一个字节,比如上面的数据就代表字符串"ab"。

Redis中的bitmap最多能存512M个字节,如果超出会报错,但这在绝大多数场景中已经足够了,因为512M可以表示:512*1024*1024*8 = 4294967296个。

bitmap一般用在什么场景呢?比如说,我们有一个id(id < 4294967296)集合A,要存储起来,然后和另外一个id集合B进行比较,找出重复的id有哪些?比如说有1亿个id吧。那么这种情况,采用bitmap就十分合适了。

bitmap的getbit和setbit的时间复杂度都是:O(1)

三、HyperLogLog

上面简述中,我们已对提到,HyperLogLog主要是用来做基数统计的,我们知道在计算机领域,可以做基数统计的还有其它的类型,比如set, hash, bitmap都可以实现,但是面对海量数据的基数统计,这些数据结构都将消耗大量内存,比如说set和hash可以适用少量数据的统计和滤重,bitmap适合海量数据的滤重,但不适合海量数据的统计。

其实HyperLogLog呢,它的底层也是采用bitmap来实现的,它是采用一种基数估算算法来实现的,如果你有兴趣,可以去研究一下基数估算算法。HyperLogLog,它仅仅只需要12KB的内存空间,可以完成对264个数据完成基数统计,而且标准误差只有0.81%。

采用PFADD命令往HyperLogLog中添加数据, PFCOUNT命令就可以返回HyperLogLog的基数统计结果。

添加与统计的时间复杂度都是:O(1)

四、Geo

基于LBS的应用,比如说生活服务类的应用,我们想要查询附近3公里内所有的餐馆,那么这个时候,我们输入的数据应该就是一个经纬度坐标,那么Redis就会从数据库中查找出以输入坐标为圆心3公里作为半径范围内所有数据。

那么Redis是存储经纬度坐标的呢?

其实对于地理空间数据的编码方式,通常来说有两种:

(1)、二分区间法;

(2)、坐标转换法;

关于上述两种算法的实现原理,如果你有兴趣,可以自行了解一下。

Redis采用的是性能更高的坐标转换法,基本思想就是将经纬度二维坐标数据转为整数存储。

最常见的命令有:

geoadd:输入坐标,将一个经纬度坐标添加到geo数据集中

georadius:输入坐标和半径,返回geo数据集中,所有在指定坐标为圆心指定半径范围内的所有其它坐标点。

geodist:输入两个坐标点,计算两点之间的距离。

五、Stream

Redis自5.0.0之后,引入了消息队列的功能,也就是开始支持Pub/Sub(发布/订阅)的功能。

Stream,消息流的底层存储结构采用的是listpack,就是一个序列化之后的字符串列表。因为它还是一个队列,那么它需要满足先进先出的特性。

Redis的消息队列相对于传统专门的消息中间件来说,有哪些优点和缺点:

优点:

(1)、高性能;

(2)、低延迟;

(3)、轻量级。

缺点:

(1)、容量小,基于内存,如果内存爆了,就无法写入新消息;

(2)、可靠性差,需要自己业务代码实现可靠性保证;

综合来看:如果业务对消息队列的容量要求不是那么大、可靠性要求也不是非常非常高,同时又不想引入专门的消息中间件使得架构变得更加复杂的话,那么Redis的消息队列功能也不失为一种办法。

六、RedisTimeSeries

RedisTimeSeries是Redis提供的时序数据库模块,那么时序数据库主要用来干什么呢?

比如说有这样的需求:

我们要存储北京市最近一年每一分钟的温度数据,然后查询需求有:

(1)、输入一个时间点,查询这个时间点的温度数据;

(2)、输入一个时间范围,同时返回这个时间范围的温度平均值,最高值,最低值。

如果采用之前的基本数据类型来存储,那么可能需要同时使用hash和sorted set。而且,要求一个时间范围的温度平均值的话,我们还必须把数据加载到客户端来进行聚合计算。

这里需要说明一下,RedisTimeSeries跟上面的扩展数据类型不一样,它并不是Redis内置的功能,它只是一个Redis扩展模块。它专门面向时间序列数据提供了数据类型和访问接口,并且支持在 Redis 实例上直接对数据进行按时间范围的聚合计算。

所以,你在使用RedisTimeSeries时,需要先把它的源码单独编译成动态链接库 redistimeseries.so,再使用 loadmodule 命令进行加载,如下所示:

loadmodule redistimeseries.so

常见的操作如下:

(1)、用 TS.CREATE 命令创建时间序列数据集合;

(2)、用 TS.ADD 命令插入数据;

(3)、用 TS.GET 命令读取最新数据;

(4)、用 TS.MGET 命令按标签过滤查询数据集合;

(5)、用 TS.RANGE 支持聚合计算的范围查询。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值