Redis 的 GeoHash详解_Redis

来源:脚本之家  责任编辑:小易  

windows7安装redis方法:1、下载Redis的压缩包https://github.com/dmajkic/redis/downloads 我下载的是redis-2.4.5-win32-win64.zip下载完后将其解压放在自己要放的目录下解压后的目录如果你是32位的话就进32bit的文件夹,64位就进64bit文件夹文件夹进去后会看到一下的几个文件redis-benchmark.exe: 性能测试 模拟N个客户端发送set,get请求redis-check-aof.exe:更新日志检查redis-check-dump.exe:本地数据库检查redis-server.exe:服务程序接下来就是安装了打开dos命令栏,进入到redis的目录下面,输入以下命令:redis-server.exe redis.conf安装成功然后再打开一个dos命令栏,进入到redis的目录下,输入以下命令:redis-cli.exe -h 127.0.0.1 -p 6379测试一下set key value 存值get key 取值www.zgxue.com防采集请勿采集本网。

Redis 在 3.2 版本以后增加了地理位置 GEO 模块,意味着我们可以使用 Redis 来实现摩拜单车「附近的 Mobike」、美团和饿了么「附近的餐馆」这样的功能了。

而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写

用数据库来算附近的人

Redis Smembers 命令返回集合中的所有的成员。 不存在的集合 key 被视为空集合。如果你要在代码里写,可以用jedis的方法去 调用Set<String> setValues =&

地图元素的位置数据使用二维的经纬度表示,经度范围 (-180, 180],纬度范围 (-90, 90],纬度正负以赤道为界,北正南负,经度正负以本初子午线 (英国格林尼治天文台) 为界,东正西负。比如掘金办公室在望京 SOHO,它的经纬度坐标是 (116.48105,39.996794),都是正数,因为中国位于东北半球。

另外一些人则认为Redis是一个datastructureserver,因为Redis支持复杂的数据特性,比如List,Set等。对Redis的作用的不同解读决定了你对Redis的使用方式。互联网数据目前基

当两个元素的距离不是很远时,可以直接使用勾股定理就能算得元素之间的距离。我们平时使用的「附近的人」的功能,元素距离都不是很大,勾股定理算距离足矣。不过需要注意的是,经纬度坐标的密度不一样 (经度总共 360 度,纬度总共 180 度),勾股定律计算平方差时之后再求和时,需要按一定的系数比加权求和。

首先开启redis服务:打开cmd命令窗口,将根目录切换至redis根目录; 开启redis服务:输入命令:redis-server.exe redis.conf   然后回车。 开启成功后,此窗口不要关闭,另

现在,如果要计算「附近的人」,也就是给定一个元素的坐标,然后计算这个坐标附近的其它元素,按照距离进行排序,该如何下手?

pool.destroy(); 运行上述代码,控制台输出: set指令执行结果:OK get指令执行结果:Hello, Redis! 使用连接池+分布式 在规模较大的系统中,往往会有多个Redis实例做负载均衡。

在这里插入图片描述

如果现在元素的经纬度坐标使用关系数据库 (元素 id, 经度 x, 纬度 y) 存储,你该如何计算?

redis和mysql的区别非常大。具体如下:mysql中一个中小型的网络数据库,比oracle和sqlserver小, 但是并发能力远超过acess这样的桌面数据库。redis是一个支持网络、可基于内

首先,你不可能通过遍历来计算所有的元素和目标元素的距离然后再进行排序,这个计算量太大了,性能指标肯定无法满足。一般的方法都是通过矩形区域来限定元素的数量,然后对区域内的元素进行全量距离计算再排序。这样可以明显减少计算量。如何划分矩形区域呢?可以指定一个半径 r,使用一条 SQL 就可以圈出来。当用户对筛出来的结果不满意,那就扩大半径继续筛选。

; $redis->del($redis_key); // Second case: cache exist in redis, let's display it } else if ($redis->exists($redis_key)) { $html_of_current_page = $redis->get($redis_key); ec

select id from positions where x0-r < x < x0+r and y0-r < y < y0+r

这里就不再逐个讨论了,我将会在一个实际应用程 序开发场景中介绍其中的一些。使用Redis 作为一 个缓存解决方案 我之前提到过,Redis 可轻易地用作一个缓存解决方案,碰

为了满足高性能的矩形区域算法,数据表需要在经纬度坐标加上双向复合索引 (x, y),这样可以最大优化查询性能。

是 在做项目过程中,多个客户端可能同时读写Redis数据库,set和get命令是否为原子操作,关系到命令是否需要加锁机制的必要性。网上资料或者看书都说set和get等Redis命令为原

但是数据库查询性能毕竟有限,如果「附近的人」查询请求非常多,在高并发场合,这可能并不是一个很好的方案。

利用 Redis 提供的 Set 数据结构,可以存储一些集合性的数据。比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。因为 Redis 非常

GeoHash 算法

我现在用的是redis desktop manager工具

业界比较通用的地理位置距离排序算法是 GeoHash 算法,Redis 也使用 GeoHash 算法。GeoHash 算法将二维的经纬度数据映射到一维的整数,这样所有的元素都将在挂载到一条线上,距离靠近的二维坐标映射到一维后的点之间距离也会很接近。当我们想要计算「附近的人时」,首先将目标位置映射到这条线上,然后在这个一维的线上获取附近的点就行了。

在有故障时可自动切换和数据即时恢复,并在业务增长或下降时,集群可伸缩或扩展(手动),并不影响在线业务,故调研测试这两种方案,以codis 为代理的codis server redis的集群,以

那这个映射算法具体是怎样的呢?它将整个地球看成一个二维平面,然后划分成了一系列正方形的方格,就好比围棋棋盘。所有的地图元素坐标都将放置于唯一的方格中。方格越小,坐标越精确。然后对这些方格进行整数编码,越是靠近的方格编码越是接近。那如何编码呢?一个最简单的方案就是切蛋糕法。设想一个正方形的蛋糕摆在你面前,二刀下去均分分成四块小正方形,这四个小正方形可以分别标记为 00,01,10,11 四个二进制整数。然后对每一个小正方形继续用二刀法切割一下,这时每个小小正方形就可以使用 4bit 的二进制整数予以表示。然后继续切下去,正方形就会越来越小,二进制整数也会越来越长,精确度就会越来越高。

1. Redis中,并不是所有的数据都一直存储在内存中的,这是和Memcached相比一个最大的区别。 2. Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的

上面的例子中使用的是二刀法,真实算法中还会有很多其它刀法,最终编码出来的整数数字也都不一样。

简而言之,dump.rdb是由Redis服务器自动生成的 默认情况下 每隔一段时间redis服务器程序会自动对数据库做一次遍历,把内存快照写在一个叫做“dump.rdb”的文件里,这个持

编码之后,每个地图元素的坐标都将变成一个整数,通过这个整数可以还原出元素的坐标,整数越长,还原出来的坐标值的损失程度就越小。对于「附近的人」这个功能而言,损失的一点精确度可以忽略不计。

GeoHash 算法会继续对这个整数做一次 base32 编码 (0-9,a-z 去掉 a,i,l,o 四个字母) 变成一个字符串。在 Redis 里面,经纬度使用 52 位的整数进行编码,放进了 zset 里面,zset 的 value 是元素的 key,score 是 GeoHash 的 52 位整数值。zset 的 score 虽然是浮点数,但是对于 52 位的整数值,它可以无损存储。

在使用 Redis 进行 Geo 查询时,我们要时刻想到它的内部结构实际上只是一个zset(skiplist)。通过 zset 的 score 排序就可以得到坐标附近的其它元素 (实际情况要复杂一些,不过这样理解足够了),通过将 score 还原成坐标值就可以得到元素的原始坐标。

Redis 的 Geo 指令基本使用

Redis 提供的 Geo 指令只有 6 个,读者们瞬间就可以掌握。使用时,读者务必再次想起,它只是一个普通的 zset 结构。

增加

geoadd 指令携带集合名称以及多个经纬度名称三元组,注意这里可以加入多个三元组

127.0.0.1:6379> geoadd company 116.48105 39.996794 juejin(integer) 1127.0.0.1:6379> geoadd company 116.514203 39.905409 ireader(integer) 1127.0.0.1:6379> geoadd company 116.489033 40.007669 meituan(integer) 1127.0.0.1:6379> geoadd company 116.562108 39.787602 jd 116.334255 40.027400 xiaomi(integer) 2

 

距离

geodist 指令可以用来计算两个元素之间的距离,携带集合名称、2 个名称和距离单位。

127.0.0.1:6379> geodist company juejin ireader km"10.5501"127.0.0.1:6379> geodist company juejin meituan km"1.3878"127.0.0.1:6379> geodist company juejin jd km"24.2739"127.0.0.1:6379> geodist company juejin xiaomi km"12.9606"127.0.0.1:6379> geodist company juejin juejin km"0.0000"

我们可以看到掘金离美团最近,因为它们都在望京。距离单位可以是 m、km、ml、ft,分别代表米、千米、英里和尺。

获取元素位置

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

127.0.0.1:6379> geopos company juejin1) 1) "116.48104995489120483" 2) "39.99679348858259686"127.0.0.1:6379> geopos company ireader1) 1) "116.5142020583152771" 2) "39.90540918662494363"127.0.0.1:6379> geopos company juejin ireader1) 1) "116.48104995489120483" 2) "39.99679348858259686"2) 1) "116.5142020583152771" 2) "39.90540918662494363"

我们观察到获取的经纬度坐标和 geoadd 进去的坐标有轻微的误差,原因是 geohash 对二维坐标进行的一维映射是有损的,通过映射再还原回来的值会出现较小的差别。对于「附近的人」这种功能来说,这点误差根本不是事。

获取元素的 hash 值

geohash 可以获取元素的经纬度编码字符串,上面已经提到,它是 base32 编码。 你可以使用这个编码值去 http://geohash.org/${hash}中进行直接定位,它是 geohash 的标准编码值。

127.0.0.1:6379> geohash company ireader1) "wx4g52e1ce0"127.0.0.1:6379> geohash company juejin1) "wx4gd94yjn0"

让我们打开地址 http://geohash.org/wx4g52e1ce0,观察地图指向的位置是否正确。

在这里插入图片描述

很好,就是这个位置,非常准确。

附近的公司

georadiusbymember 指令是最为关键的指令,它可以用来查询指定元素附近的其它元

素,它的参数非常复杂。

# 范围 20 公里以内最多 3 个元素按距离正排,它不会排除自身127.0.0.1:6379> georadiusbymember company ireader 20 km count 3 asc1) "ireader"2) "juejin"3) "meituan"# 范围 20 公里以内最多 3 个元素按距离倒排127.0.0.1:6379> georadiusbymember company ireader 20 km count 3 desc1) "jd"2) "meituan"3) "juejin"# 三个可选参数 withcoord withdist withhash 用来携带附加参数# withdist 很有用,它可以用来显示距离127.0.0.1:6379> georadiusbymember company ireader 20 km withcoord withdist withhash count 3 asc1) 1) "ireader" 2) "0.0000" 3) (integer) 4069886008361398 4) 1) "116.5142020583152771" 2) "39.90540918662494363"2) 1) "juejin" 2) "10.5501" 3) (integer) 4069887154388167 4) 1) "116.48104995489120483" 2) "39.99679348858259686"3) 1) "meituan" 2) "11.5748" 3) (integer) 4069887179083478 4) 1) "116.48903220891952515" 2) "40.00766997707732031"

除了 georadiusbymember 指令根据元素查询附近的元素,Redis 还提供了根据坐标值来查询附近的元素,这个指令更加有用,它可以根据用户的定位来计算「附近的车」,「附近的餐馆」等。它的参数和 georadiusbymember 基本一致,除了将目标元素改成经纬度坐标值。

127.0.0.1:6379> georadius company 116.514202 39.905409 20 km withdist count 3 asc1) 1) "ireader" 2) "0.0000"2) 1) "juejin" 2) "10.5501"3) 1) "meituan" 2) "11.5748"

小结 & 注意事项

在一个地图应用中,车的数据、餐馆的数据、人的数据可能会有百万千万条,如果使用Redis 的 Geo 数据结构,它们将全部放在一个 zset 集合中。在 Redis 的集群环境中,集合可能会从一个节点迁移到另一个节点,如果单个 key 的数据过大,会对集群的迁移工作造成较大的影响,在集群环境中单个 key 对应的数据量不宜超过 1M,否则会导致集群迁移出现卡顿现象,影响线上服务的正常运行。

所以,这里建议 Geo 的数据使用单独的 Redis 实例部署,不使用集群环境。

如果数据量过亿甚至更大,就需要对 Geo 数据进行拆分,按国家拆分、按省拆分,按市拆分,在人口特大城市甚至可以按区拆分。这样就可以显著降低单个 zset 集合的大小。

到此这篇关于Redis 的 GeoHash详解的文章就介绍到这了,更多相关Redis 的 GeoHash内容请搜索真格学网以前的文章或继续浏览下面的相关文章希望大家以后多多支持真格学网! 您可能感兴趣的文章:详解PHP使用Redis存储session时的一个Warning定位

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。Redis 是一个高性能的key-value数据库。redis的出现,很大程度补偿了memcached这类keyvalue存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。 若想在PHP中使用redis,首先要先安装redis。然后在PHP中配置扩展。 1.安装redis。 首先下载好redis安装文件,解压到D盘或其他盘。 然后通过Dos命令行进行安装。 把这个文件夹复制到其它地方,比如D:\redis 目录下。打开一个cmd窗口  使用cd命令切换目录到D:\redis  运行 redis-server.exe redis.conf  如果想方便的话,可以把redis的路径加到系统的环境变量里,这样就省得再输路径了,后面的那个redis.conf可以省略,如果省略,会启用默认的。输入之后,会显示如下界面:这时候另启一个cmd窗口,原来的不要关闭,不然就无法访问服务端了切换到redis目录下运行 redis-cli.exe -h 127.0.0.1 -p 6379 出现下图: 这时候,就已经完成配置了。 完成了配置之后,要在PHP中添加redis的扩展,之后才可以用PHP灵活的使用它。 在windows下安装php的redis扩展非常简单,下载一个.dll扩展包放到php的ext目录下,在php.ini里边添加一行配置就可以了。 php代码测试 $redis = new Redis();$redis->connect(‘127.0.0.1′,6379);$redis->set(‘test','hello world!');echo $redis->get(‘test'); 输出hello world!内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • 简介redis中的showlog功能
  • redis如何使用lua脚本实例教程
  • redis批量删除key的方法
  • centos7下redis3.2.8最新版本安装教程
  • redis集合类型_动力节点java学院整理
  • redis数据类型及应用场景知识点总结
  • 利用redis的有序集合实现排行榜功能实例代码
  • 详解redis开启远程登录连接
  • 详解利用redis + lua解决抢红包高并发的问题
  • redis教程之代理ip池设计方法详解
  • PHP中redis的用法深入解析
  • 求windows7下安装redis的方法
  • redis的setbit这个bit怎么理解,配合bitcount使用
  • c#连接Redis缓存数据库与Redis的安装与配置
  • redis的缓存数据在网站中有什么作用
  • redis中的set集合如何遍历
  • redis 的 vm是 什么意思
  • php怎么查看redis的key
  • 如何用java获取redis的info
  • redis和mysql有什么区别呢
  • 让WordPress使用Redis缓存进行加速的方案
  • java对redis的操作怎么写
  • redis的set指令具有原子性吗
  • redis的基本数据结构有哪些,都有什么应用
  • redis有没有远程的客户端管理工具
  • redis的Twemproxy迁移至Cluster可以使用redis-trib.rb导入吗
  • memcached和redis的区别
  • redis文件中的dump.rdb文件是怎么生成的
  • redis 如何重启? linux下请输入命令不要用kill 的方式
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全mssqlmysqlmariadboracledb2mssql2008mssql2005sqlitepostgresqlmongodbredisaccess数据库文摘数据库其它首页详解php使用redis存储session时的一个warning定位简介redis中的showlog功能redis如何使用lua脚本实例教程redis批量删除key的方法centos7下redis3.2.8最新版本安装教程redis集合类型_动力节点java学院整理redis数据类型及应用场景知识点总结利用redis的有序集合实现排行榜功能实例代码详解redis开启远程登录连接详解利用redis + lua解决抢红包高并发的问题redis教程之代理ip池设计方法详解超强、超详细redis数据库入门教程redis常用命令、常见错误、配置技redis操作命令总结redis中5种数据结构的使用场景介64位windows下安装redis教程redis中使用redis-dump导出、导入redis中统计各种数据大小的方法redis常用命令小结让redis在你的系统中发挥更大作用centos 6.6下redis安装配置记录redis禁用命令、危险命令及规避方法解密redis助力双11背后电商秒杀系统(推荐redis如何使用lua脚本实例教程超强、超详细redis数据库入门教程redis 解决key的乱码问题,并清理详解详谈redis优化配置和redis.conf说明(推荐jedis配置含义详解浅析redis cluster介绍与gossip协议详解redis开启远程登录连接简介lua脚本与redis数据库的结合使用
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved