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(发布)消息时 ...
随机推荐
- Jmeter系列(36)- Access Log Sampler
简介 Access Log Sampler 是个非常有用的工具,可以收集和分析真实用户操作的数据,并可用于流量分析.常见的就是我们的nginx的access.log 日志 使用 access.log ...
- django 各项配置基本设置
setting中一些设置例子 mysql数据库连接设置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': ...
- 踩坑系列《六》Spring增加事务处理遇到异常解决办法
当在对数据进行增删改操作时,需要用到事务的处理,所以在业务层中加入@Transactional注解,但是在执行业务操作的前面遇到异常,因此对异常进行抛出,但是数据又诡异地成功保存到数据库了. 解决方法 ...
- Spring源码之AOP的使用
Spring往期精彩文章 Spring源码搭建 Spring源码阅读一 前言 我们都知道Java是一门面向对象(OOP)的语言,所谓万物皆对象.但是它也存在着一些个弊端:当你需要给多个不具有继承关系的 ...
- java 从零开始手写 RPC (05) reflect 反射实现通用调用之服务端
通用调用 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 java 从零开始手写 RPC (03) 如何 ...
- noip模拟78
考试过程:先读题,然后觉得开题顺序1 4 2 3. 首先是T1,要是不考虑重复这题很简单,但是考虑重复就比较复杂了,我打完,对拍完差不多用了两个小时,然后就是忘了算内存,结果内存爆了,\(100pts ...
- pycharm中设置自己的文件模板
File>>Settings>>Editor>>File and Code Templates 选择文件类型Python Scripts,输入文件模板类型 #!/u ...
- 2020.12.3--vj个人赛补题
A Vasya studies music.He has learned lots of interesting stuff. For example, he knows that there are ...
- PAT (Basic Level) Practice (中文)1014 福尔摩斯的约会 (20分)
1014 福尔摩斯的约会 (20分) 带侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hys ...
- IEEE 754 浮点数加减运算
电子科技大学 - 计算机组成原理 小数的十进制和二进制转换 移码 定义:[X]移 = X + 2n ( -2n ≤ X < 2n ) X为真值,n为整数的位数 数值位和X的补码相同,符号位与补码 ...