原文地址: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发布 地理位置功能增强了什么?的更多相关文章

  1. WijmoJS V2019.0 Update2发布:再度增强 React 和 Vue 框架的组件功能

    前端开发工具包 WijmoJS 在2019年的第二个主要版本 V2019.0 Update2 已经发布,本次发布涵盖了React 和 Vue 框架下 WijmoJS 前端组件的功能增强,并加入更为易用 ...

  2. DevExpress WPF v19.2图表图形控件功能增强?速速种草

    通过DevExpress WPF Controls,你能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案. 无论是Office办公软件的衍 ...

  3. DevExpress WPF v19.1:Data Grid/Tree List等控件功能增强

    行业领先的.NET界面控件DevExpress 日前正式发布v19.1版本,本站将以连载的形式介绍各版本新增内容.在本系列文章中将为大家介绍DevExpress WPF v19.1中新增的一些控件及部 ...

  4. DevExpress WinForms v19.1新版亮点:Spreadsheet/Sunburst控件功能增强

    行业领先的.NET界面控件DevExpress v19.1终于正式发布,本站将以连载的形式介绍各版本新增内容.在本系列文章中将为大家介绍DevExpress WinForms v19.1中新增的一些控 ...

  5. Tapdata Cloud 版本上新!新增TiDB等数据源支持,连接和任务功能增强,体验更优

    Tapdata Cloud cloud.tapdata.net Tapdata Cloud 是国内首家异构数据库实时同步云平台,目前支持Oracle.MySQL.PG.SQL Server.Mongo ...

  6. C#开发微信门户及应用(15)-微信菜单增加扫一扫、发图片、发地理位置功能

    前面介绍了很多篇关于使用C#开发微信门户及应用的文章,基本上把当时微信能做的接口都封装差不多了,微信框架也积累了不少模块和用户,最近发现微信公众平台增加了不少内容,特别是在自定义菜单里面增加了扫一扫. ...

  7. MWeb 1.4 新功能介绍二:静态博客功能增强

    MWeb 比较有特色的是一键生成静态博客功能,然后从 MWeb 最开始规划要做静态博客生成功能时,我就希望 MWeb 的静态博客生成功能在易用的同时,还要有很强大的扩展性. 比如说能自己增加网站公告, ...

  8. VMare中安装“功能增强工具”,实现CentOS5.5与win7host共享文件夹的创建

    读者如要转载,请标明出处和作者名,谢谢. 地址01:http://space.itpub.net/25851087 地址02:http://www.cnblogs.com/zjrodger/ 地址03 ...

  9. Jedis实现发布订阅功能

    Redis为我们提供了publish/subscribe(发布/订阅)功能.我们可以对某个channel(频道)进行subscribe(订阅),当有人在这个channel上publish(发布)消息时 ...

随机推荐

  1. Shell系列(6)- 管道符

    多命令顺序执行 多命令执行符 格式 作用 ; 命令1 ; 命令2 连接命令:多个命令顺序执行,命令之间没有任何逻辑联系:前面命令报错,后面命令照常执行 && 命令1 && ...

  2. Elasticsearch -head 查询报 406错误码

    问题:利用Elasticsearch -head插件不能查看数据或者在Elasticsearch -linux的curl命令操作时总是提示: {"error":"Cont ...

  3. 腾讯云centos7.5安装jdk1.8

    手动解压安装包方法 在user目录下新建java文件夹 cd /usr/ mkdir java 把jdk安装包移动到java目录下 我已经提前下载jdk的tar包 mv jdk-8u251-linux ...

  4. 微信小程序 创建自己的第一个小程序

    * 成为微信公众平台的开发者 注册 https://mp.weixin.qq.com * 登录 https://open.weixin.qq.com/ * 开发者工具下载 https://develo ...

  5. SQL-关联查询【转】

    T_A A表 T_B B标,id为表与表相关联的字段`创建相关表结构 CREATE TABLE Table_B( id INT(2), serNum VARCHAR(10) ); CREATE TAB ...

  6. 几分钟就能学会的Python虚拟环境教程

    什么是虚拟环境 我们在使用Python的时候,通常用pip来进行包管理.比如我们要安装一个叫requests的库,那么我们就会采用以下命令去安装: pip install requests 那你知道, ...

  7. springweb项目自定义拦截器修改请求报文头

    面向切面,法力无边,任何脏活累活,都可以从干干净净整齐划一的业务代码中抽出来,无非就是加一层,项目里两个步骤间可以被分层的设计渗透成筛子. 举个例子: 最近我们对接某银行接口,我们的web服务都是标准 ...

  8. caffe运行错误 target_blobs.blobs_size()与 source_layer.blobs_size() 不一致

    解决方法参考:http://blog.csdn.net/zhangla1220/article/details/50697352 感谢博主!!! 最新下载的caffe代码,运行mnist,训练时可以正 ...

  9. ArcPy获取栅格属性

    获取栅格属性 (数据管理) 描述 从元数据和栅格数据集的相关描述性统计数据中检索信息. 使用方法 返回的属性将显示在结果窗口中. 此工具的 Python 结果是地理处理结果对象.要获取字符串值,请使用 ...

  10. VS Code Just My Code Debugging

    VS Code Just My Code Debugging VS Code for C++ doesn't support Just My Code Refer here: Add support ...