
Redis 三种特殊类型
HyperLogLogs(基数统计)
用于统计一些准确度要求不高的数据;
- 允许容错,可以接受一定误差;
- 基数,指内容不可重复;A={1,2,3,4,5},B={3,5,6,7,9},基数=1,2,4,6,7,9;
用来做什么
可以用来统计各种计数,如注册IP数,每日访问IP数,在线用户数,共同好友数等;
优势
可以使用少量固定的内存去存储并识别集合中的唯一元素,估算的基数不一定准确,有0.81%标准错误近似值;
如:
一个IP消耗15个字节,100W个IP就是15M,HyperLogLog在Redis中每个键占用内容都是12K,理论存储近似接近2^64个值;不论存储的内容是什么,它有一个基于基数估算的算法,只能比较准确地估算出基数,可以使用少量固定的内存去存储并识别集合的唯一元素;
使用
1 | 127.0.0.1:6379> pfadd k1 a b c d e f g h i # k1 ={a,b,c,d,e,f,g,h,i} |
Bitmap(位存储)
位图数据结构,通过操作二进制数来进行记录,只有0和1两个状态;
用来做什么
比如用户每天的打卡情况;
设置打卡情况
1 | 127.0.0.1:6379> setbit sign:year 0 1 # 用户第0天打卡了 |
获取打卡情况
1 | 127.0.0.1:6379> getbit sign:year 4 # 用户第4天没打卡 |
获取所有的打卡情况
1 | 127.0.0.1:6379> bitcount sign:year |
Geospatial(地理位置)
geospatial可以存放一个坐标,地理位置,基于经纬度;
底层实现原理
Geo的底层实现就是SortedSet,可以通过SortedSet命令控制geo;
原理
Redis Geo使用Geohash实现位置的存储;
Geohash将经纬度编码成为一个52bit的整型,而此时有序集合的score就可以存储52bit的整型且不失精度;
一些命令
geoadd 添加地理位置
介绍
GEOADD key [NX | XX] [CH] longitude latitude member [longitude latitude member ...]
添加指定的位置信息到key中;
数据存储为一个有序集合;
可以通过GEOSEARCH命令获取这些信息;
参数
longitude 经度 latitude 纬度
命令支持标准的x,y坐标,经度必须放置在纬度的前面;
极其接近极点的坐标无法被索引:
- 有效经度范围:-180到180;
- 有效纬度范围:-85.05112878到85.05112878
若使用范围之外的经纬度会返回错误;
XX
仅更新已有元素,不添加新元素;
NX
不更新已有元素,只添加新元素;
CH
GEOADD默认返回值为新添加的元素的数量,使用CH之后将返回值改为改变的元素的数量,不计入原值和输入值相同的情况。一个双score有序集合可以存储一个52bit的整数且不失精度;
注意:XX与NX不可一起使用
geopos 获取指定成员经纬度
GEOPOS key member [member ...]
返回所有指定成员的经度和纬度;
通过key使用有序集合进行索引;
由于存储数据时采用geohash方法,获取到的数据可能会出现一些误差;
若元素不存在则返回一个由null组成的数组;
1 | 127.0.0.1:6379> geoadd g1 116 40 "BeiJing" 112 37 "TaiYuan" # 添加TaiYuan和BeiJing的经纬度 |
geodist 两个成员的距离
GEODIST key member1 member2 [M | KM | FT | MI]
返回两个成员之间的距离;
如果有一个或两个成员不存在,则返回null;
最后的参数为单位,默认为米:
- m 米;
- km 千米;
- mi 英里;
- ft 尺
步数
距离的计算基于假定地球是一个完美的球体,所以计算结果会有0.5%的误差;
1 | 127.0.0.1:6379> GEOPOS g1 BeiJing TaiYuan |
geohash
GEOHASH key member [memebr …]
返回geohash字符串
(geohash是一个可以将纬度和精度编码为一个52bit的散列函数)
1 | 127.0.0.1:6379> GEOHASH g1 BeiJing TaiYuan |
geosearch
1 | GEOSEARCH key |
介绍
返回给定形状范围内的member列表;
支持搜索圆形区域和方形取悦;
命令代替了GEORADIUS和GEORADIUSBYMEMBER;
参数
形状的中心
FROMMEMBER:以成员为形状的原点;
FROMLONLAT:以指定经纬度为形状的原点;
形状的参数
BYRADIUS:形状为圆形,根据给定radius参数为圆形的半径
BYBOX:形状为矩形,根据给定的width和height为形状的长宽;
需要返回对象的其他参数
WITHDIST:返回原点到各个成员的距离;
WITHCOORD:返回成员的经纬度;
WITHHASH:返回成员的GEOHASH值。
是否排序
若未指定以下两个参数,则默认不排序;
ASC:排序顺序为距离原点,最近的元素到最远的元素;
DESC:距离原点,最远的元素到最近的元素;
返回数量
COUNT <count> [ANY]
默认返回所有的元素;
通过COUNT <count>
参数可以限制返回的数量;
若提供ANY,Redis查询过程会在查到指定数量的结果后直接返回不排序,且不考虑远近问题;
若不提供ANY,Redis会返回排序后的所有结果。不提供ANY时,命令执行的速度会相对慢一点;
1 | 127.0.0.1:6379> GEODIST g1 BeiJing TaiYuan m # 查询得知,TaiYuan到BeiJing的距离为482157m,换算48.22km |
geosearchstore
1 | GEOSEARCHSTORE destination source |
与GEOSEARCH类似;
不同的是,GEOSEARCHSTORE会将获得的结果存放到destination中;
默认将获得的对象以及其GEOHASH以SortedSet方式存放;
使用STOREDIST参数后,存放内容为获得的对象和距离原点的距离。
STOREDIST,
1 | 127.0.0.1:6379> GEOSEARCHSTORE ss1 g1 FROMMEMBER BeiJing BYRADIUS 500 KM ASC COUNT 2 ANY |
georadius 通过半径获取附近的人的地址(弃用)
GEORADIUS key longitud latitude raduis <M | KM | FI | MI> [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC | DESC] [STORE key] [STOREDIST key]
georadiusbymember 通过半径获取成员附近的地址(弃用)
1 | GEORADIUSBYMEMBER key member radius <M | KM | FT | MI> [WITHCOORD] |