【Redis】Redis高级:GEO&BitMap&HyperLogLog

Redis高级:GEO&BitMap&HyperLogLog

GEO、BitMap、HyperLogLog是redis中三种特殊的数据结构,一般用于实现特殊的业务场景,其底层都是基于redis中的基础数据类型存储的

1 GEO

GEO就是Geolocation的简写形式,代表一个地理坐标。Redis在3.2版本中加入了对GEO的支持,允许存储地理坐标信息,帮助我们根据经纬度来检索数据。

GEO底层是按照SortedSet存储的,value是我们在添加地理空间时设置的member,score是通过经纬度计算得来的Hash值

GEO常用命令如下:

GEOADD

  • 作用:添加一个地理空间信息,包含:经度(longitude)、纬度(latitude)、值(member)

  • 语法:geoadd key [NX|XX] [CH] longitude latitude member [longitude latitude member ...]

  • 备注:经纬度必须合法

  • 案例:添加数据:北京南站(116.378248 39.865275)、北京站(116.42803 39.903738)、北京西站(116.322287 39.893729)

    在这里插入图片描述

GEODIST

  • 作用:计算指定的两个点之间的距离并返回

  • 语法:geodist key member1 member2 [m|km|ft|mi]

  • 备注:不指定单位默认为米

  • 案例:计算北京西站到北京站的距离

    在这里插入图片描述

GEOPOS

  • 作用:返回指定member的坐标

  • 语法:geopos key member [member ...]

  • 案例:查询北京西站的地理坐标

    在这里插入图片描述

GEOHASH

  • 作用:将指定member的坐标转为hash字符串形式并返回

  • 语法:geohash key member [member ...]

  • 案例:将北京西站的地理坐标转为hash字符串形式并返回

    在这里插入图片描述

GEORADIUS

  • 作用:指定圆心、半径,找到该圆内包含的所有member,并按照与圆心之间的距离排序后返回。6.2以后已废弃

  • 语法:georadius key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC|DESC] [STORE key] [STOREDIST key]

  • 备注:各参数含义如下

    参数含义
    `key longitude latitude radius mkm
    [WITHCOORD] [WITHDIST] [WITHHASH]分别对应:是否返回匹配对象的经纬坐标、是否返回匹配对象与圆心的距离、是否返回匹配对象对应的hash串
    [COUNT count [ANY]]需要查找的member的数量
    `[ASCDESC]`
    [STORE key]将查询结果存储到另一个geo中
    [STOREDIST key]将查询结果与圆心的距离的集合存储到一个SortedSet中
  • 案例:搜索天安门(116.397904 39.909005)附近 10km 内的所有火车站,显示这些火车站的经纬度以及到天安门的距离,并按照距离升序排序

    在这里插入图片描述

GEOSEARCH

  • 作用:在指定范围内搜索member,并按照与指定点之间的距离排序后返回。范围可以是圆形或矩形。6.2新功能

  • 语法:geosearch key [FROMMEMBER member] [FROMLONLAT longitude latitude] [BYRADIUS radius m|km|ft|mi] [BYBOX width height m|km|ft|mi] [ASC|DESC] [COUNT count [ANY]] [WITHCOORD] [WITHDIST] [WITHHASH]

  • 备注:各参数含义如下

    参数含义
    [FROMMEMBER member] [FROMLONLAT longitude latitude]是根据指定member查询还是指定经纬度查询
    `[BYRADIUS radius mkm
    `[ASCDESC] [COUNT count [ANY]] [WITHCOORD] [WITHDIST] [WITHHASH]`
  • 案例:搜索以天安门(116.397904 39.909005)为中心,10km 矩形范围内最近的前两个火车站(按照距离升序排序),显示这些火车站的经纬度以及到天安门的距离

    在这里插入图片描述

GEOSEARCHSTORE

  • 作用:与GEOSEARCH功能一致,不过可以把结果存储到一个指定的key, 6.2新功能

  • 语法: geosearchstore destination source [FROMMEMBER member] [FROMLONLAT longitude latitude] [BYRADIUS radius m|km|ft|mi] [BYBOX width height m|km|ft|mi] [ASC|DESC] [COUNT count [ANY]] [WITHCOORD] [WITHDIST] [WITHHASH]

  • 备注:source表示查询的geo,destination表示进行结果存储的geo,

  • 案例:搜索以天安门(116.397904 39.909005)为中心,10km 矩形范围内最近的前两个火车站(按照距离升序排序),显示这些火车站的经纬度以及到天安门的距离,并将结果存储到另一个geo中

    在这里插入图片描述


2 BitMap

BitMap 即位图数据结构,通过操作二进制位数据来记录信息,只包含0或1。

由于其占用内存空间小的特点,常用于数据量大但却只有两种情况的信息,这类信息使用mysql存储往往会占用大量磁盘资源,例如用户是否在线,用户是否登录,用户是否签到等等,像这类信息就适用于使用BitMap来存储

BitMap是基于String类型存储的,一个BitMap存储的上限取决于String大小的上限,而Redis中String大小上限是512M,转换成bit则是2^32个bit位

BitMap的常用操作命令如下:

SETBIT

  • 作用:向指定位置(offset)存入一个0或1

  • 语法:setbit key offset value

  • 案例:在bitmap的第5个位置存入1(注意索引从0开始)

    在这里插入图片描述

    执行结束后,我们可以去redis图形化界面中查看key为k3的数据

    在这里插入图片描述

    注意:BitMap是使用String类型来存储的,而String的最小单位是字节,1字节等于8bit,所以BitMap存储的数据个数必须为8的倍数,我们这里只将第5个位置的数据修改成了1,其他未被修改的位置会以0表示。

GETBIT

  • 作用:获取指定位置(offset)的bit值

  • 语法:getbit key offset

  • 演示:

    在这里插入图片描述

BITCOUNT

  • 作用:统计BitMap中值为1的bit位的数量,可以指定统计的范围

  • 语法:bitcount key [start end]

  • 演示:

    在这里插入图片描述

BITFIELD

  • 作用:操作(查询、修改、自增)BitMap中bit数组中的指定位置(offset)的值

  • 语法:bitfield key [GET type offset] [OVERFLOW WRAP|SAT|FAIL]

  • 备注:一般只会用来查询,故这里只列出查询的语法,查询的返回结果会换算成十进制

  • 演示:

    在这里插入图片描述

    get u5 0表示从第1个数字开始,截取5位数字,并将结果换算成无符号十进制整数。其中的u表示无符号,如果想要换算成有符号的十进制整数可以使用i,即get i5 0,5表示截取5位数字,0表示从第1个数字开始

    在这里插入图片描述

    这里返回结果为5,而k3中前五位数字换算成10进制的值就是5

BITFIELD_RO

  • 作用:获取BitMap中bit数组,并以十进制形式返回
  • 备注:与BITFIELD使用基本相同,只不过BITFIELD_RO只能用来查询

BITOP

  • 作用:将多个BitMap的结果做位运算(与 、或、异或)
  • 语法:bitop operation destkey key [key ...]

BITPOS

  • 作用:查找bit数组中指定范围内第一个0或1出现的位置

  • 语法:bitpos key bit [start] [end]

  • 演示:

    在这里插入图片描述


3 HyperLogLog

Hyperloglog(HLL)是从Loglog算法派生的概率算法,用于确定非常大的集合的基数,而不需要存储其所有值。相关算法原理大家可以参考:https://juejin.cn/post/6844903785744056333#heading-0

Hyperloglog适用于进行网站的UV统计

UV全称Unique Visitor,也叫独立访客量,是指通过互联网访问、浏览这个网页的自然人。1天内同一个用户多次访问该网站,只会记录1次访问。UV统计在服务端做会比较麻烦,因为要判断该用户是否已经统计过了,需要将统计过的用户信息保存。但是如果每个访问的用户都保存到Redis中,数据量会非常恐怖,这时候我们就可以通过Hyperloglog进行数量统计

Redis中的HLL是基于string结构实现的,单个HLL的内存永远小于16kb,内存占用低的令人发指!作为代价,其测量结果是概率性的,有小于0.81%的误差。不过对于UV统计来说,这完全可以忽略。

另外,Hyperloglog只能对不重复的数据进行统计,如果数据是允许重复的话,就不能使用Hyperloglog来统计了。

Hyperloglog的常用命令有以下几个:

PFADD

  • 作用:将一条或多条数据插入到HLL中
  • 语法:pfadd key element [element ...]

PFCOUNT

  • 作用:统计指定HLL中元素的个数,有小于0.81%的误差
  • 语法:pfcount key [key...]

演示:我们可以通过Java代码,向HyperLogLog添加100万条数据,看看统计结果如何:

@Autowired
private StringRedisTemplate stringRedisTemplate;

@Test
void testHyperLogLog() {
    String[] values = new String[1000];
    int j = 0;
    for (int i = 0; i < 1000000; i++) {
        j = i % 1000;
        values[j] = "user_" + i;
        if(j == 999){
            // 发送到 Redis
            stringRedisTemplate.opsForHyperLogLog().add("hl2", values);
        }
    }
    // 统计数量
    Long count = stringRedisTemplate.opsForHyperLogLog().size("hl2");
    System.out.println("count = " + count);
}

输出结果如下:

在这里插入图片描述

通过比对数据插入前后redis内存占用的变化,发现这100万条数据仅仅只占用了14KB的内存

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值