Redis6.2发布 地理位置功能增强了什么?
原文地址:https://developer.aliyun.com/article/780257
Redis社区最近刚刚发布Redis6.2 RC1版本,在本次发布中,阿里云Tair团队(阿里云云内存数据库产研团队,负责云上Redis社区版和Redis企业版Tair)为社区贡献了大量高质量代码与功能,其中关于地理位置查询能力的提升上,阿里云贡献了GEOSEARCH和GEOSEARCHSTORE两个重要而强大的API。本文通过分析这两个全新的API,对Redis在地理位置型应用进行深入剖析,并延伸介绍了阿里云Tair在地理位置上的更多强大功能与应用场景。
1. Redis 6.2 GEOSEARCH命令详解
Redis自3.2版本,增加了地理位置的相关API:
• GEOADD 将给定的空间元素(纬度、经度、名字)添加到指定的键里面。
• GEOPOS 从键里面返回所有给定位置元素的位置(经度和纬度)。
• GEODIST 返回两个给定位置之间的距离。
• GEORADIUS 以给定的经纬度为中心, 返回与中心的距离不超过给定最大距离的所有位置元素。
• GEORADIUSBYMEMBER 跟GEORADIUS类似,指定GEO集合中某个成员为中心。
• GEOHASH 返回一个或多个位置元素的 Geohash 表示。
然而随着互联网生活的本地化进程加快,诸如同城购,社区团购与买菜、电子单车围栏等基于地理位置的业务的飞速发展,过去开源Redis只能搜索圆形区域的能力并不能满足用户的搜索需求,在最新版Redis 6.2中,阿里云Tair团队将阿里云Redis企业版Tair性能增强型中包含的相关矩形搜索能力贡献给了社区。

图1. 阿里云Tair对Redis 6.2地理位置能力的贡献
新增的GEOSEARCH和GEOSEARCHSTORE命令拥有更丰富的语法,满足了搜索矩形的应用需求。

图2. 矩形搜索 vs 圆形搜索
GEOSEARCH key
[FROMMEMBER member] [FROMLONLAT long lat]
[BYRADIUS radius unit] [BYBOX width height unit]
[WITHCOORD] [WITHDIST] [WITHHASH]
[COUNT count] [ASC|DESC]
该API返回使用GEOADD填充的地理空间信息有序集合中位于给定形状所划定的区域边界内的所有成员。
其中搜索中心有两种指定方式:
• FROMMEMBER:从已经存在的key中读取经纬度。
• FROMLONLAT:从用户参数传递经纬度。
搜索条件按照下面两种:
• BYRADIUS:根据给定半径长度按照圆形搜索,命令效果等同于GEORADIUS。
• BYBOX:根据给定的width和height按照矩形搜索,矩形是轴对称矩形。
后面更多的可选参数如下:
• WITHCOORD:返回匹配的经纬度坐标。
• WITHDIST:返回距离,距离单位按照radius或者height/width单位转换。
• WITHHASH:返回GeoHash计算的值。
• COUNT count:只返回count个元素。注意,这里的count是全部搜索完成之后才过滤的,也就是不能减少搜索的CPU消耗,但是返回元素少,可以相应降低网络带宽的利用率。
• ASC|DESC:对满足条件的点按照距离排序。
GEOSEARCHSTORE与GEOSEARCH相似,只是将搜索结果存储在指定的key中。
举例如下,对于一个正方形(橙色区域)以及其内接圆(蓝色区域)的搜索,可以看到,位于正方形,但是没有在内接圆中的点edge1和edge2可以通过BYBOX指定矩形搜索的方式被搜索出来:

图3. 地理位置搜索示意图
127.0.0.1:6379> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
127.0.0.1:6379> GEOADD Sicily 12.758489 38.788135 "edge1" 17.241510 38.788135 "edge2"
(integer) 2
127.0.0.1:6379> GEOSEARCH Sicily FROMLONLAT 15 37 BYRADIUS 200 km ASC
1) "Catania"
2) "Palermo"
127.0.0.1:6379> GEOSEARCH Sicily FROMLONLAT 15 37 BYBOX 400 400 km ASC
1) "Catania"
2) "Palermo"
3) "edge2"
4) "edge1"
2. Redis GEO的不足
从实现原理上讲,Redis本身的GEO功能底层是根据GeoHash算法,将地理位置坐标转换为52bit的整形数字之后,存储在Sorted Set中。因为GeoHash的特性,地理位置距离越近则数值大小约相似,然后通过ZRANGEBYSCORE key min max WITHSCORES查询Sorted Set范围内的点并判断距离是否在搜索范围内。
目前在最新版6.2 RC1中虽然支持了圆形与矩形的搜索,但是Redis GEO仍旧有很多场景限制,例如:
• 搜索地域如果是不规则多边形怎么办?
• 如果想搜索线与面(例如外卖员的轨迹与地域关系)、面与面的关系怎么办?
要解决这些问题,需要从GIS原理重新审视。Redis目前使用的GeoHash原理本质上是对二维坐标进行了降维,将其表示为一个long数字或者base32编码,但是这种索引只适合查询点和点的关系,对于更复杂的线与面的关系,需要更复杂的索引结构RTree1来解决。RTree可以将多个不规则多边形求Minimum bounding box(最小限定矩形)之后存储在一棵RTree中用来检索。
正是由于复杂的运算和存储索引,传统关系型如PostGIS和落盘型(On-Disk Database)数据库在地理位置高并发更新和查询时效率不高。而将数据结构化在内存数据库中(In-Memory Database),结合Tair增强性能的高吞吐引擎可以使得存储查询效率得到能力的量级提升。

图4. RTree原理
3. 阿里云TairGIS介绍
TariGIS是阿里云Redis企业版性能增强型其中的一个Module,使用RTree做索引,支持GIS(Geographic Information System,地理信息系统)各种丰富的API查询2。TairGIS不仅兼容Redis GEO,并且支持线、面的查询,功能更加强大,能够更广泛地用于各类基于地理位置的应用及业务中。
主要的功能如下:
• 使用RTree索引
• 支持点、线、面的相关查询(包含,相交)
• 兼容Redis GEO
如下展示TairGIS兼容上面Redis GEO例子并增加线和面的搜索:
// 使用TairGIS可以添加 POINT(点)/LINESTRING(线)/POLYGON(面) 三种图形
127.0.0.1:7379> GIS.ADD Sicily Palermo 'POINT (13.361389 38.115556)' Catania 'POINT (15.087269 37.502669)' // 添加点
(integer) 2
127.0.0.1:7379> GIS.ADD Sicily edge1 'POINT (12.758489 38.788135)' edge2 'POINT (17.241510 38.788135)'
(integer) 2
127.0.0.1:7379> GIS.SEARCH Sicily RADIUS 15 37 200 km // 使用半径查询
1) (integer) 2
2) 1) "Palermo"
2) "POINT(13.361389 38.115556)"
3) "Catania"
4) "POINT(15.087269 37.502669)"
127.0.0.1:7379> GIS.ADD Sicily polygon 'POLYGON ((13.361389 38.115556, 15.087269 37.502669, 17.241510 38.788135))' // 添加 Palermo,Catania,edge2的三角形
(integer) 1
127.0.0.1:7379> GIS.SEARCH Sicily GEOM "POLYGON ((12.7484 35.2018, 12.7484 38.7981, 17.2515 38.7981, 17.2515 35.2018))" // 等同于 BYBOX 400 400 km,TairGIS可以指定任意形状的多边形查询,而非受限于矩形
1) (integer) 5
2) 1) "Palermo"
2) "POINT(13.361389 38.115556)"
3) "Catania"
4) "POINT(15.087269 37.502669)"
5) "edge1"
6) "POINT(12.758489 38.788135)"
7) "edge2"
8) "POINT(17.24151 38.788135)"
9) "polygon"
10) "POLYGON((13.361389 38.115556,15.087269 37.502669,17.24151 38.788135))"
127.0.0.1:7379> GIS.SEARCH Sicily GEOM "POLYGON ((12.7484 35.2018, 12.7484 38.7981, 17.2515 38.7981))" // 使用三角形查询,可以看到edge2被排除,因为polygon和三角形有重合,所以被查询出来
1) (integer) 4
2) 1) "Palermo"
2) "POINT(13.361389 38.115556)"
3) "Catania"
4) "POINT(15.087269 37.502669)"
5) "edge1"
6) "POINT(12.758489 38.788135)"
7) "polygon"
8) "POLYGON((13.361389 38.115556,15.087269 37.502669,17.24151 38.788135))"
127.0.0.1:7379>
TairGis的API如下所示,完整API及参数请参考文档。
• GIS.ADD 将点/线/面添加到key中(每key是一个RTree索引区域)。
• GIS.GET 获取添加的点/线/面。
• GIS.DEL 删除添加的某个点/线/面。
• GIS.WITHIN 给定一个范围,可以是不规则图形,搜索此范围内的点/线/面。
• GIS.CONTAINS 给定一个范围,判断包含此范围的点/线/面的集合。
• GIS.INTERSECTS 给定一个范围,判断哪些点/线/面和此范围相交的集合。
• GIS.SEARCH 可以指定圆心和半径搜索,类Redis语法的Near语义。
• GIS.GETALL 获取一个key下所有的点/线/面,通过选项控制返回格式。
通过使用TairGIS可以构建各种丰富的基于地理位置的应用,举例如下:
本地生活
在淘宝的门店服务中,使用TairGIS做商家服务范围(一个面)与消费者(一个点)之间的关系判断,从而确定消费者是否在商家的服务范围中。


图5. 构建本地生活应用
电子围栏
判断共享单车是否在禁停区内,是否已经归还到还车区(通过点和面的包含关系来判断),电子围栏用途非常广泛,还包括安全应用如儿童电子围栏,也包括无人机起飞禁飞区判定等。

图6. 构建共享单车还车区域应用
疫情防控
在疫情期间,判断用户的轨迹(一条线)是否经过疫区(一个面),即判断线与面的相交关系即可确认用户是否经过疫区。具体方案可参考:使用TairGIS实现用户轨迹监测。

图7. 构建用户轨迹判定应用
目前包含上述TairGIS强大地理位置能力的阿里云Redis企业版性能增强型限时限量特惠,新购和续费年付5折,月付7折,Redis全兼容,更强大性能,更大带宽,更大连接数,更丰富实用的数据结构,具备全球分布式多活、数据闪回等多个企业级能力,点击此处抢购使用!
Redis6.2发布 地理位置功能增强了什么?的更多相关文章
- WijmoJS V2019.0 Update2发布:再度增强 React 和 Vue 框架的组件功能
前端开发工具包 WijmoJS 在2019年的第二个主要版本 V2019.0 Update2 已经发布,本次发布涵盖了React 和 Vue 框架下 WijmoJS 前端组件的功能增强,并加入更为易用 ...
- DevExpress WPF v19.2图表图形控件功能增强?速速种草
通过DevExpress WPF Controls,你能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案. 无论是Office办公软件的衍 ...
- DevExpress WPF v19.1:Data Grid/Tree List等控件功能增强
行业领先的.NET界面控件DevExpress 日前正式发布v19.1版本,本站将以连载的形式介绍各版本新增内容.在本系列文章中将为大家介绍DevExpress WPF v19.1中新增的一些控件及部 ...
- DevExpress WinForms v19.1新版亮点:Spreadsheet/Sunburst控件功能增强
行业领先的.NET界面控件DevExpress v19.1终于正式发布,本站将以连载的形式介绍各版本新增内容.在本系列文章中将为大家介绍DevExpress WinForms v19.1中新增的一些控 ...
- Tapdata Cloud 版本上新!新增TiDB等数据源支持,连接和任务功能增强,体验更优
Tapdata Cloud cloud.tapdata.net Tapdata Cloud 是国内首家异构数据库实时同步云平台,目前支持Oracle.MySQL.PG.SQL Server.Mongo ...
- C#开发微信门户及应用(15)-微信菜单增加扫一扫、发图片、发地理位置功能
前面介绍了很多篇关于使用C#开发微信门户及应用的文章,基本上把当时微信能做的接口都封装差不多了,微信框架也积累了不少模块和用户,最近发现微信公众平台增加了不少内容,特别是在自定义菜单里面增加了扫一扫. ...
- MWeb 1.4 新功能介绍二:静态博客功能增强
MWeb 比较有特色的是一键生成静态博客功能,然后从 MWeb 最开始规划要做静态博客生成功能时,我就希望 MWeb 的静态博客生成功能在易用的同时,还要有很强大的扩展性. 比如说能自己增加网站公告, ...
- VMare中安装“功能增强工具”,实现CentOS5.5与win7host共享文件夹的创建
读者如要转载,请标明出处和作者名,谢谢. 地址01:http://space.itpub.net/25851087 地址02:http://www.cnblogs.com/zjrodger/ 地址03 ...
- Jedis实现发布订阅功能
Redis为我们提供了publish/subscribe(发布/订阅)功能.我们可以对某个channel(频道)进行subscribe(订阅),当有人在这个channel上publish(发布)消息时 ...
随机推荐
- java 小算法
//鸡兔同笼 20个头 58腿 for(int a=0;a<=20;a++) { int b = 20-a; if((2*b+4*a)==58) { System.out.println(a+& ...
- mysql8 navicat远程链接失败
原因:mysql 8加密规则问题 更改加密规则: ALTER USER 'ycc'@'%' IDENTIFIED BY 'you password' PASSWORD EXPIRE NEVER; 修改 ...
- 定要过python二级 第10套
第一部分 第一题 1. int* 字符串 =几个东西 2. 此题的最开始的疑惑 (1)01 02 03 怎么产生 for 循环 (2)<<< 这个怎么产生 (3)<这个&l ...
- 深入浅出WPF-10.Resource(资源)
资源 对象级资源:每个WPF的界面元素都有一个名为Resources的属性,这个属性继承自FrameworkElement类,其类型为ResourceDictionary,采用键值对的形式存储资源,当 ...
- Stream聚合函数
Stream班介绍 幼稚园开学的第一天,各们家长把小朋友送到了园里,各位小朋友都你看看我,我看看你.有的嚎啕大哭,有的呆若木鸡....这里时候园长安排我拿来小本本记录入园的小朋友.... 记录小朋友 ...
- Spring,AOP实现功能级别权限验证
1. 首先是问题出现的原因 对于一个我的一个个人博客网站,我希望游客可以浏览我的博客,但是评论功能是需要登录才能使用 这就需要对某个功能进行权限验证 对于过滤器,拦截器,AOP的区别日后再讨论,现在是 ...
- Filter和Interceptor
Filter的使用 拦截user下的所有请求 @WebFilter("/user/*") public class UserFilter implements Filter { @ ...
- 小记SpringMVC与SpringBoot 的controller的返回json数据的不同
近期由于项目的改动变更,在使用springmvc和springboot测试的时候发现一个有趣的现象 1.springmvc的controller使用@ResponseBody返回的仅仅是json格式的 ...
- springcloud组件之注册中心eureka学习
eureka的高可用 微服务架构中最核心的部分是服务治理,服务治理最基础的组件是注册中心.随着微服务架构的发展,出现了很多微服务架构的解决方案,其中包括我们熟知的Dubbo和Spring Cloud. ...
- 深入理解Java虚拟机之JVM内存布局篇
内存布局**** JVM内存布局规定了Java在运行过程中内存申请.分配.管理的策略,保证了JVM的稳定高效运行.不同的JVM对于内存的划分方式和管理机制存在部分差异.结合JVM虚拟机规范,一起来 ...