原文地址: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. Java面向对象系列(1)- 什么是面向对象

    面向过程 & 面向对象 面向过程思想 步骤清晰清楚,第一步做什么,第二步做什么-- 面对过程适合处理一些较为简单的问题 面向对象思想 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分 ...

  2. Docker系类(25)- 发布镜像到DockerHub

    # step-1 注册账号 https://hub.docker.com/# step-2 在服务器尚提交我们的镜像[root@localhost WEB-INF]# docker login --h ...

  3. LateX出坑

    1 公式是用$ 包围着的  $ 2 \begin{equation} 里面的公式自动编号   \end{equation} 要达成这样的效果,暂时想到如下方法: 1 \begin{equation} ...

  4. P7444-「EZEC-7」猜排列【dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P7444 题目大意 一个长度为\(n\)的排列,已知每个\(c_i\)表示那个排列中\(mex\)为\(i\)的区间 ...

  5. 【月光宝盒get√】用时间置换空间,聊聊稀疏数组的那些事儿

    背景 数据结构是指带有结构特性的数据元素的集合.在数据结构中,数据之间通过一定的组织结构关联在一起,便于计算机存储和使用.从大类划分,数据结构可以分为线性结构和非线性结构,适用于不同的应用场景. 线性 ...

  6. 在Anaconda环境下安装Tensorflow

    安装Anaconda 下载Anaconda 个人版Individual Edition.如果下载速度慢,可以复制下载链接到迅雷或者在清华大学开源镜像站TUNA中找合适的版本. 注意在安装过程中的&qu ...

  7. 4.自定义类加载器实现及在tomcat中的应用

    了解了类加载器的双亲委派机制, 也知道了双亲委派机制的原理,接下来就是检验我们学习是否扎实了,来自定义一个类加载器 一. 回顾类加载器的原理 还是这张图,类加载器的入口是c++调用java代码创建了J ...

  8. sql提示1055 不让你group by

    是不是突然写好的sql语句 部署上去就 Expression #2 of SELECT list is not in GROUP BY clause and containsnonaggregated ...

  9. 题解 「BZOJ2178」圆的面积并

    题目传送门 题目大意 给出 \(n\) 个圆,求它们并的面积大小. \(n\le 10^3\) 思路 如果您不会自适应辛普森法,请戳这里学习 其实我们发现,如果我们设 \(f(x)\) 表示 \(x= ...

  10. 洛谷3195 [HNOI2008]玩具装箱TOY(斜率优化+dp)

    qwq斜率优化好题 第一步还是考虑最朴素的\(dp\) \[dp=dp[j]+(i-j-1+sum[i]-sum[j])^2 \] 设\(f[i]=sum[i]+i\) 那么考虑将上述柿子变成$$dp ...