Redis~Geospatial(地理空间)、Hyperloglog(基数统计)、Bitmap(位图)

Geospatial(地理空间) 简称Geo

  • 在Redis3.2中也引入了推算地理信息的数据结构,即Geospatial, 它可以帮助我们我们实现地理空间上的距离, 比如显示附近的人、外卖距离、剩余路径等功能

实现原理

  • 把某个具体的位置信息(经度,纬度,名称)添加到指定的key中数据将会用一个sorted set存储,以便稍后能使用 GEORADIUS和 GEORADIUSBYMEMBER命令来根据半径来查询位置信息。
  • 这个命令(指GEOADD)的参数使用标准的x,y形式,所以经度(longitude)必须放在纬度(latitude)之前,对于可被索引的坐标位置是有一定限制条件的:非常靠近极点的位置是不能被索引的, 在EPSG:900913 / EPSG:3785 / OSGEO:41001指定如下:

有效的经度是-180度到180度
有效的纬度是-85.05112878度到85.05112878度

  • 上面是官方文档的描述,其实Geo并没有我们想象中的复杂,它的本质就是一个Zset,通过将坐标以Geohash的方式进行处理,将经度纬度错位后形成一个52位整数,所以我们同样能够使用Zset提供的接口来操作Geo。

用法

GEOADD key 经度 纬度 地点名称 将指定的地理空间位置(经度、纬度、名称)添加到指定的key中
GEODIST key 地点1 地点2 返回两个给定位置之间的距离
GEOPOS key 地点 从key里返回所有给定位置元素的位置(经度和纬度)
GEOHASH key 地点 返回一个或多个位置元素的 Geohash 表示
GEORADIUS key 经度 纬度 半径 以给定的经纬度为中心, 找出某一半径内的元素
GEORADIUSBYMEMBER key 地点 半径 找出位于指定范围内的元素,中心点是由给定的位置元素决定

# 为了方便示范,下面加入一些城市的地理信息——GEOADD 
127.0.0.1:6379> GEOADD CHINA 108.94683  34.29296  "xian"
(integer) 1
127.0.0.1:6379> GEOADD CHINA 116.405285 39.904989 "beijing"
(integer) 1
127.0.0.1:6379> GEOADD CHINA 121.472644 31.231706 "shanghai"
(integer) 1
127.0.0.1:6379> GEOADD CHINA 113.280637 23.125178 "guangzhou"
(integer) 1
127.0.0.1:6379> GEOADD CHINA 114.085947 22.547    "shenzhen"
(integer) 1
127.0.0.1:6379> GEOADD CHINA 110.33119  20.031971 "hainan"
(integer) 1

# 获取北京和上海的距离——GEODIST 
127.0.0.1:6379> GEODIST CHINA beijing shanghai km
"1067.5980"

# 获取西安的坐标——GEOPOS 
127.0.0.1:6379> GEOPOS CHINA xian
1) 1) "108.94683212041854858"
   2) "34.29296115814533863"

# 以经度120 纬度35位置为中心,获取半径1000千米内的城市——GEORADIUS 
127.0.0.1:6379> GEORADIUS CHINA 120 35 1000 km
1) "beijing"
2) "shanghai"

# 获取在广州半径500千米内的城市——GEORADIUSBYMEMBER  
127.0.0.1:6379> GEORADIUSBYMEMBER CHINA guangzhou 500 km
1) "shenzhen"
2) "guangzhou"
3) "hainan"

# 将广州和深圳的坐标转换为11为的GEO哈希值——GEOHASH
127.0.0.1:6379> GEOHASH CHINA guangzhou shenzhen
1) "ws0e9cb3yj0"
2) "ws10k0dcg10"

Hyperloglog(基数统计)

  • 在我们为网站统计访问量、日活量时,由于我们统计的是用户数量而非访问次数,因此即使一个用户多次访问也只会统计一次,这种不重复的数据通常被称为基数
  • 在传统的做法中,我们通常会采用set来保存用户的ID来进行计数,因为其本身存在着去重的功能,但是由于我们所需要的是对用户进行计数,如果通过将所有用户的ID保存的方法来完成,当用户量大的时候就会对内存产生巨大的压力,并且效率也大大降低。
  • 为了解决这个问题,Redis在2.8.9版本添加了HyperLogLog结构。

实现原理

  • Redis HyperLogLog是用来做基数统计的算法,HyperLogLog的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。
  • 在Redis 里面,每个HyperLogLog键只需要花费12KB内存,就可以计算接近2^64个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
  • HyperLogLog使用的是概率算法,通过存储元素的hash值的第一个1的位置,来计算元素数量,所以HyperLogLog 不会存储元素本身,在数据量大的时候也可能会存在一定的误差。但是在基数统计这一方面,它的效果是其他结构无法比拟的。

使用

PFADD key value 添加指定的值到Hyperloglog中
PFCONUT key 返回给定Hyperloglog的基数估算值
PFMERGE destkey sourcekey 将目标Hyperloglog合并到源Hyperloglog中

127.0.0.1:6379> PFADD NUMS1 1 2	3 4	#向NUMS1插入1-4
(integer) 1
127.0.0.1:6379> PFADD NUMS1 1		#数据已存在,不再插入
(integer) 0
127.0.0.1:6379> PFCOUNT NUMS1		#查看当前基数数量
(integer) 4

127.0.0.1:6379> PFADD NUMS2 3 4 5 6	#向NUMS2插入3-6
(integer) 1
127.0.0.1:6379> PFMERGE NUMS1 NUMS2	#将NUMS2合并到NUMS1中
OK
127.0.0.1:6379> PFCOUNT NUMS1		#此时NUMS1中记录了1-6,六个元素
(integer) 6									

Bitmap(位图)

  • 位图其实就是哈希的变形,他通过哈希映射来处理数据,位图本身并不存储数据,而是存储标记。通过一个比特位,即0/1来标记一个数据的两种状态
  • 位图通常情况下用在数据量庞大,且数据不重复的情景下标记某个数据的两种状态。 我们可以使用位图来记录当前用户的登陆情况、或者实现打卡、签到等功能

使用

GETBIT key offset value(0/1) 设置Bitmap中偏移量为offset的位置的值
SETBIT key offset value 返回Bitmap中偏移量为offset的位置的值
BITCOUNT key 计算位图中有多少个1

127.0.0.1:6379> SETBIT TEST 1 1	#将位图中第135位设置为1
(integer) 0
127.0.0.1:6379> SETBIT TEST 3 1
(integer) 0
127.0.0.1:6379> SETBIT TEST 5 1
(integer) 0

127.0.0.1:6379> GETBIT TEST 1 	#查看位图中123位的值
(integer) 1
127.0.0.1:6379> GETBIT TEST 2
(integer) 0
127.0.0.1:6379> GETBIT TEST 3
(integer) 1

127.0.0.1:6379> BITCOUNT TET	#统计位图中1的数量,由于我们只设置了135位,因此为3
(integer) 3

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值