Bitmaps(位存储)

Bitmap 即位图数据结构,都是操作二进制位来进行记录,只有0 和 1 两个状态。

  • 用来解决什么问题

比如:统计用户信息,活跃,不活跃! 登录,未登录! 打卡,不打卡! 两个状态的,都可以使用 Bitmaps
如果存储一年的打卡状态需要多少内存呢? 365 天 = 365 bit 1字节 = 8bit 46 个字节左右!

就是说统计一个数只需要1位,而用其他方式存储统计,一个数可能需要n位。Bitmaps能极大的节省空间。
比如有1亿用户,日活跃5000w,用List方式存储今天活跃的人数,把他们的用户id放进入,假设每个id占8字节,64位。需要啊400MB左右。
如果用Bitmaps,每个用户占用1位,(怎么区分用户,在1000110101……中第几个用户),只需要12.5MB左右。

  1. Bitmaps本身不是一种数据类型,实际上它就是字符串(key-value),但是它可以对字符串的位进行操作
  2. Bitmaps单独提供了一套命令,所以Redis中使用Bitmaps和使用字符串的方式不太相同,可以吧Bitmaps想像成一个以位为单位的数组,数组的每个单元只能存储0和1,数组下标在Bitmaps中叫偏移量。

image.png

常用命令

命令 简述 使用
setbit 在键为key的Bitmaps中设置偏移量offset的值为0或者1 setbit
getbit 获取键为key的Bitmaps里面某个偏移量的值 getbit
bitcount 统计字符串被设置为1的bit数量,一般情况下给定的整个字符串都会被进行计数,通过指定额外的start或者end参数,可以让计数只在特定的位上进行。start和end参数的设置,都可以使用负数值,比如-1表示最后一位,而-2表示倒数第二个位,start和end是指下标,二者皆包含 bitcount [start end]
bitop and/or/not/xor bitop是一个复合操作,它可以做多个Bitmaps的 and(交集),or(并集),not(非),xor(异或)操作,并将结果保存在destkey中 bitop and/or/not/xor [key…]

HyperLogLog(基数统计)

  • 什么是基数?

举个例子,A = {1, 2, 3, 4, 5}, B = {3, 5, 6, 7, 9};那么基数(不重复的元素)= 1, 2, 4, 6, 7, 9; (允许容错,即可以接受一定误差)

  • HyperLogLog 基数统计用来解决什么问题

这个结构可以非常省内存的去统计各种计数,比如注册 IP 数、每日访问 IP 数、页面实时UV、在线用户数,共同好友数等。

  • 它的优势体现在哪

一个大型的网站,每天 IP 比如有 100 万,粗算一个 IP 消耗 15 字节,那么 100 万个 IP 就是 15M。而 HyperLogLog 在 Redis 中每个键占用的内容都是 12K,理论存储近似接近 2^64 个值,不管存储的内容是什么,它一个基于基数估算的算法,只能比较准确的估算出基数,可以使用少量固定的内存去存储并识别集合中的唯一元素。而且这个估算的基数并不一定准确,是一个带有 0.81% 标准错误的近似值(对于可以接受一定容错的业务场景,比如IP数统计,UV等,是可以忽略不计的)。

常用命令

命令 简述 使用
pfadd 添加指定元素到HyperLogLogs中,如果执行命令后,HLL估计的近似基数发生变化,返回1,否则返回0 pfadd [element……]
pfcount 计算HLL的近似基数,可以计算多个HLL pfcount [key ……]
pfmerge 将一个或多个HLL(sourcekey)合并后的结果存储在另一个HLL(destkey)中 pfmerge [sourcelkey ……]

geospatial (地理位置)

Redis 3.2中增加了对GEO类型的支持。GEO ,Geographic,地理信息的缩写。
该类型,就是元素的2维坐标,在地图上就是经纬度。redis基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度Hash 等常见操作。

这个网站可以查询城市经纬度数据:http://www.jsons.cn/lngcode

常用命令

命令 简述 使用
geoadd 添加地理位置
- 有效的经度从-180度到180度。
- 有效的纬度从-85.05112878度到85.05112878度。
geoadd <经度> <纬度> [<经度> <纬度> …… ]
geopos 获取指定地方的经纬度坐标 geopos [ …… ]
geodist 获取两个位置之间的直线距离
- m单位米,默认值
- km千米
- mi英里
- ft英尺
geodist [m|km|ft|mi]
georadius 以给定的经纬度为中心,找出某一半径内的元素 georadius <经度> <纬度> <半径> m|km|ft|mi
georadiusbymember 显示与指定成员一定半径范围内的其他成员 georadiusbymember <半径> m|km|ft|mi