如果你了解redis,或者用过它,那你一定知道它的5个常用数据结构,如果你在面试中被问到过redis,那么这5个基本的数据结构肯定会被问到,但是今天我们不讨论这些,我们来讨论其他的数据结构,也许你以前没有用过,也许你没有理解过,但这不重要,重要的是它们是非常通用的数据结构,在解决特定问题时很有用。Btimap从理论上讲,位图不属于一种特殊的数据结构。本质上也是一个字符串类型的数据结构,只是存储的值是bit,也就是我们常说的二进制010101的数据。这样的数据结构可以帮助我们用极少的存储空间完成非常高效的数据查询。比如我们有这样一个需求。我们想统计每天登录的用户数。常规的方法是将数据放入set集合中,然后对数据进行求和。但是,如果数据量非常大,这样就很浪费了。超大的存储空间和位图完美解决了这个问题。首先,我们可以用每一天的日期作为key,然后把签到人的id转成bit值存储,也就是说如果签到了,那么对应位置的值为1,否则为0,这样就可以通过一个key:value来统计报名人数。需要注意的是,对于位操作,redis有bitcout可以快速统计和。从名字我们可以看出,HyeprLogLog有两条日志,意思是它通过两次取对数来节省存储空间。需要注意的是,这是一个概率数据结构,也就是说,它只能计算出高概率值,并不能准确得到精确值。但是在大数据问题中,能够以最小的代价得到一个大致准确的值,这就是我们所追求的。在redis中,每个hyperloglogkey只需要12kb的空间来存储2^64个元素,大大节省了内存存储空间。hyperloglog的数学原理是基于伯努利过程,是在相同条件下反复独立进行的随机实验。对于一段数据,我们通过计算它的哈希值得到二进制01值,然后进行分桶操作,然后计算在每个桶中的位置,因为存储的数据可以通过两次操作呈指数增长,另一方面,当我们想要存储一定量的数据,我们只需要取两个对数位来保存,所以这也是hyperloglog这个名字的由来。有了hyerploglog,如果我们还算上上面的check-in,我们的存储空间会大大减少。当然,这是以牺牲一定的准确性为代价的。Stream我们都知道,在redis中,我们可以通过list来实现消息队列的功能,不过那只是简单的实现而已。它缺少持久化和数据复制的功能,Steam就是为了解决这个问题而诞生的。当你觉得rabbitmq太大的时候,那么redis的流数据结构可以帮你实现消息队列几乎所有的功能,但是如果你的项目足够大,请使用普通的消息队列。GEO计算两点之间的距离。我们可以很容易地计算出来,但是如果我们计算两个地理经纬度坐标点之间的距离,就会变得很复杂。如果我们计算多个点呢?问题会变得比较复杂,但是这些计算问题,在redis中,可以通过GEO轻松实现。GEO主要用于存储指定的地理空间位置,可以在指定的key中添加一个或多个经度(longitude)、纬度(latitude)、位置名称(member)。在使用地图的时候,我们经常需要计算当前位置一定范围内的餐厅、剧院等建筑物的信息,而我们可以通过GEO轻松实现这一功能。在redis中,通过georadiusbymember函数,我们可以很方便的计算出周围点的信息。总结对比string、list、set、sortset、hash这五种结构,你会发现上面介绍的数据结构的使用场景都非常单一,或者说主要是为了解决某些特定问题而存在。没有说哪种数据结构更好,每种数据结构都有自己的应用场景,否则也不会被创造出来。
