美文网首页PHP
Redis应用-Geo

Redis应用-Geo

作者: Gundy_ | 来源:发表于2019-07-05 16:14 被阅读4次

系列文章

移动互联网时代LBS应用越来越多,交友软件中附近的小姐姐、外卖软件中附近的美食店铺、打车软件附近的车辆等等,那这种附近各种形形色色的XX是如何实现的呢,

我么你都知道地球上的地理位置是使用二维的经纬度表示,经度范围 (-180, 180],纬度范围 (-90, 90],只要我们确定一个点的经纬度就可以名曲他在地球的位置

例如打车,最直观的操作就是实时记录更新各个车的位置,然后去我们要找车时,在数据库中查找距离我们(坐标x0,y0)附近r公里的车辆,使用如下SQL即可:

select cart from position where x0-r < x < x0+r and y0-r < y < y0+r

但是这样会有什么问题呢?
1是查询性能问题,如果并发高,数据量大这种查询是要搞垮数据库的
2是这个查询的是一个矩形访问,而不是以我为中心r公里为半径的圆形访问。
3是精准度的问题,我们知道地球不是平面坐标系,而是一个圆球,这种矩形计算在长距离计算时会有很大误差

今天我们讲的是使用Redis来解决附近的问题,下面我们先看看Redis的解决办法

Redis 地理位置

命令

Redis在3.2版本以后增加了地理位置的处理,其提供了6个地理位置相关的命令

  • GEOADD 将给定的空间元素(纬度、经度、名字)添加到指定的键里面
  • GEOPOS 从键里面返回所有给定位置元素的位置(经度和纬度)
  • GEODIST 返回两个给定位置之间的距离。
  • GEORADIUS 以给定的经纬度为中心, 返回与中心的距离不超过给定最大距离的所有位置元素。
  • GEORADIUSBYMEMBER 跟GEORADIUS类似
  • GEOHASH 返回一个或多个位置元素的 Geohash 表示。

使用

添加地理位置
geo add key longitude latitude member [longitude latitude member ...]
如添加杭州北京上海的地理位置
127.0.0.1:6379> geoadd city 120.20000 30.26667 hangzhou  116.41667 39.91667 beijing 121.47 31.23 shanghai
获取地理位置信息

geopos 指令可以获取集合中任意元素的经纬度坐标,可以一次获取多个。

127.0.0.1:6379> geopos city hangzhou  beijing shanghai
1) 1) "120.15000075101852417"
   2) "30.2800007575645509"
2) 1) "116.39999896287918091"
   2) "39.90000009167092543"
3) 1) "121.47000163793563843"
   2) "31.22999903975783553"
127.0.0.1:6379> geopos city hangzhou
1) 1) "120.15000075101852417"
   2) "30.2800007575645509"
计算距离

距离单位可以是 m、km、ml、ft,分别代表米、千米、英里和尺。

127.0.0.1:6379> geodist city shanghai hangzhou  km
"164.5694"
127.0.0.1:6379> geodist city beijing  hangzhou  km
"1122.7998"
获取指定元素范围的地理信息位置集合

使用GEORADIUSBYMEMBER命令即可查询附近的位置

GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]

例如查找距离杭州300km以内的城市的10个城市按距离排序

127.0.0.1:6379> GEORADIUSBYMEMBER city hangzhou 300 km WITHCOORD WITHDIST WITHHASH  ASC COUNT 10
1) 1) "hangzhou"
   2) "0.0000"
   3) (integer) 4054134257390783
   4) 1) "120.15000075101852417"
      2) "30.2800007575645509"
2) 1) "shanghai"
   2) "164.5694"
   3) (integer) 4054803462927619
   4) 1) "121.47000163793563843"
      2) "31.22999903975783553"

在给定以下可选项时, 命令会返回额外的信息:

  • WITHDIST : 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
  • WITHCOORD : 将位置元素的经度和维度也一并返回。
  • WITHHASH : 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。
  • ASC : 根据中心的位置, 按照从近到远的方式返回位置元素。DESC : 根据中心的位置, 按照从远到近的方式返回位置元素。
获取元素的 hash 值

可能你还注意到有一个命令GEOHASH,那他是做什么的呢

127.0.0.1:6379> geohash city hangzhou
1) "wtmkq069cc0"
127.0.0.1:6379> geohash city beijing
1) "wx4fbxxfke0"

返回的其实是元素的经纬度经过goehash计算后的base32编码字符串。可以通过连接 http://geohash.org/${hash}中进行直接定位,它是 geohash 的标准编码值。

RedisGeo的原理

RedisGeo的存储结构

其存储结构主要使用的是Redis的有序结构,其score是GeoHash的52位整数值

127.0.0.1:6379> ZRANGE city 0 -1 WITHSCORES
1) "hangzhou"
2) "4054134257390783"
3) "shanghai"
4) "4054803462927619"
5) "beijing"
6) "4069885360207904"

Geohash原理

其原理比较容易理解,核心思想就是将球体转换为球面,区块转换为一点

image

主要分为三步

  • 将三维的地球变为二维的坐标
  • 在将二维的坐标转换为一维的点块
  • 最后将一维的点块转换为二进制在通过base32编码

详细原理解析可以参考这边文章GeoHash核心原理解析

其他Geo处理

目前很多数据存储引擎都支持Geo的处理,如MongoDB、MySql、PgSql、Elasticsearch等。感兴趣的读者可以去研究一下。

参考文章

Redis 命令参考
GeoHash核心原理解析

本文亦在微信公众号【小道资讯】发布,欢迎扫码关注!


image

相关文章

  • Redis应用-Geo

    系列文章Redis应用-分布式锁Redis应用-异步消息队列与延时队列Redis应用-位图Redis应用-Hype...

  • 项目中Redis应用场景

    一、Redis GEO-实现附近的人 1.1 Redis GEO介绍 Redis GEO主要用于存储地理位置信息,...

  • redis-geo

    redis-geo 介绍 算法看geo那个 内部实现就是zset(skiplist) 实例

  • Redis实现地理信息计算

    1 Redis的GEO Redis 在 3.2 版本以后增加了地理位置 GEO 模块,意味着我们可以使用 Redi...

  • Redis源码剖析之GEO——Redis是如何高效检索地理位置的

    Redis GEO 用做存储地理位置信息,并对存储的信息进行操作。通过geo相关的命令,可以很容易在redis中存...

  • redis命令大全

    1、Redis 地理位置(geo) 命令 2、 Redis 键(key) 命令 3、Redis 字符串(Strin...

  • redis GEO

    CEO(地理信息定位): 存储经纬度,计算两地距离,范围计算等API geoaddgeo key logitude...

  • redis geo地理位置的应用

    GEO功能在Redis3.2版本提供,支持存储地理位置信息用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能...

  • redis 学习(15)-- GEO

    GEO GEO 简介 Redis 3.2添加新特性 功能:存储经纬度、计算两地距离、范围计算等 基于ZSet实现 ...

  • Redis geo之我想找最近的美食

    又是Redis这个家伙,到底还有什么是Redis不能做的。没错,就是它,今天小马来聊聊Redis geo这个数据结...

网友评论

    本文标题:Redis应用-Geo

    本文链接:https://www.haomeiwen.com/subject/afpehctx.html