博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Redis-发布订阅,GEO
阅读量:2382 次
发布时间:2019-05-10

本文共 4379 字,大约阅读时间需要 14 分钟。

1.发布订阅

Redis提供了基于“发布/订阅”模式的消息机制, 此种模式下, 消息发布者和订阅者不进行直接通信, 发布者客户端向指定的频道(channel) 发布消息, 订阅该频道的每个客户端都可以收到该消息, 如图3-16所示。 Redis提供了若干命令支持该功能, 在实际应用开发时, 能够为此类问题提供实现方法。

1 命令

Redis主要提供了发布消息、 订阅频道、 取消订阅以及按照模式订阅和取消订阅等命令。
1.发布消息
publish channel message
下面操作会向channel: sports频道发布一条消息“Tim won thechampionship”, 返回结果为订阅者个数, 因为此时没有订阅, 所以返回结果为0:

127.0.0.1:6379> publish channel:sports "Tim won the championship"(integer) 0

2.订阅消息

subscribe channel [channel ...]
订阅者可以订阅一个或多个频道, 下面操作为当前客户端订阅了channel: sports频道:

127.0.0.1:6379> subscribe channel:sportsReading messages... (press Ctrl-C to quit)1) "subscribe"2) "channel:sports"3) (integer) 1

此时另一个客户端发布一条消息:

127.0.0.1:6379> publish channel:sports "James lost the championship"(integer) 1

当前订阅者客户端会收到如下消息:

127.0.0.1:6379> subscribe channel:sportsReading messages... (press Ctrl-C to quit)...1) "message"2) "channel:sports"3) "James lost the championship"

如果有多个客户端同时订阅了channel: sports, 整个过程如图3-17所示。

有关订阅命令有两点需要注意:
·客户端在执行订阅命令之后进入了订阅状态, 只能接收subscribe、psubscribe、 unsubscribe、 punsubscribe的四个命令。
·新开启的订阅客户端, 无法收到该频道之前的消息, 因为Redis不会对发布的消息进行持久化。

                    图3-17 多个客户端同时订阅频道channel: sports

开发提示
和很多专业的消息队列系统(例如Kafka、 RocketMQ) 相比, Redis的发布订阅略显粗糙, 例如无法实现消息堆积和回溯。 但胜在足够简单, 如果当前场景可以容忍的这些缺点, 也不失为一个不错的选择。
3.取消订阅
unsubscribe [channel [channel ...]]
客户端可以通过unsubscribe命令取消对指定频道的订阅, 取消成功后,不会再收到该频道的发布消息:

127.0.0.1:6379> unsubscribe channel:sports1) "unsubscribe"2) "channel:sports"3) (integer) 0

4.按照模式订阅和取消订阅

psubscribe pattern [pattern...]
punsubscribe [pattern [pattern ...]]
5.查询订阅
(1) 查看活跃的频道
pubsub channels [pattern]

127.0.0.1:6379> pubsub channels1) "channel:sports"2) "channel:it"3) "channel:travel"127.0.0.1:6379> pubsub channels channel:*r*1) "channel:sports"2) "channel:travel"

(2) 查看频道订阅数

pubsub numsub [channel ...]
当前channel: sports频道的订阅数为2:

127.0.0.1:6379> pubsub numsub channel:sports1) "channel:sports"2) (integer) 2

(3) 查看模式订阅数

pubsub numpat

127.0.0.1:6379> pubsub numpat(integer) 1

2.GEO

Redis3.2版本提供了GEO(地理信息定位) 功能, 支持存储地理位置信息用来实现诸如附近位置、 摇一摇这类依赖于地理位置信息的功能, 对于需要实现这些功能的开发者来说是一大福音。

1.增加地理位置信息
geoadd key longitude latitude member [longitude latitude member ...]
longitude、 latitude、 member分别是该地理位置的经度、 纬度、 成员, 表3-7展示5个城市的经纬度。

127.0.0.1:6379> geoadd cities:locations 116.28 39.55 beijing(integer) 1

返回结果代表添加成功的个数, 如果cities: locations没有包含beijing,那么返回结果为1, 如果已经存在则返回0:

127.0.0.1:6379> geoadd cities:locations 116.28 39.55 beijing(integer) 0

如果需要更新地理位置信息, 仍然可以使用geoadd命令, 虽然返回结果为0。 geoadd命令可以同时添加多个地理位置信息:

127.0.0.1:6379> geoadd cities:locations 117.12 39.08 tianjin 114.29 38.02shijiazhuang 118.01 39.38 tangshan 115.29 38.51 baoding(integer) 4

2.获取地理位置信息

geopos key member [member ...]

127.0.0.1:6379> geopos cities:locations tianjin1) 1) "117.12000042200088501"2) "39.0800000535766543"

3.获取两个地理位置的距离。

geodist key member1 member2 [unit]
其中unit代表返回结果的单位, 包含以下四种:
·m(meters) 代表米。
·km(kilometers) 代表公里。
·mi(miles) 代表英里。
·ft(feet) 代表尺。
下面操作用于计算天津到北京的距离, 并以公里为单位:

127.0.0.1:6379> geodist cities:locations tianjin beijing km"89.2061"

4.获取指定位置范围内的地理信息位置集合

georadius key longitude latitude radiusm|km|ft|mi [withcoord] [withdist]
[withhash] [COUNT count] [asc|desc] [store key] [storedist key]
georadiusbymember key member radiusm|km|ft|mi [withcoord] [withdist]
[withhash] [COUNT count] [asc|desc] [store key] [storedist key]
georadius和georadiusbymember两个命令的作用是一样的, 都是以一个地理位置为中心算出指定半径内的其他地理信息位置, 不同的是georadius命令的中心位置给出了具体的经纬度,

georadiusbymember只需给出成员即可。

其中radiusm|km|ft|mi是必需参数, 指定了半径(带单位) , 这两个命令有很多可选参数, 如下所示:

·withcoord: 返回结果中包含经纬度。
·withdist: 返回结果中包含离中心节点位置的距离。
·withhash: 返回结果中包含geohash, 有关geohash后面介绍。
·COUNT count: 指定返回结果的数量。
·asc|desc: 返回结果按照离中心节点的距离做升序或者降序。
·store key: 将返回结果的地理位置信息保存到指定键。
·storedist key: 将返回结果离中心节点的距离保存到指定键。
下面操作计算五座城市中, 距离北京150公里以内的城市:

127.0.0.1:6379> georadiusbymember cities:locations beijing 150 km1) "beijing"2) "tianjin"3) "tangshan"4) "baoding"

5.获取geohash

geohash key member [member ...]
Redis使用geohash[3]将二维经纬度转换为一维字符串, 下面操作会返回beijing的geohash值。

127.0.0.1:6379> geohash cities:locations beijing1) "wx4ww02w070"

geohash有如下特点:

·GEO的数据类型为zset, Redis将所有地理位置信息的geohash存放在zset中。

127.0.0.1:6379> type cities:locationszset

字符串越长, 表示的位置更精确, 表3-8给出了字符串长度对应的精度, 例如geohash长度为9时, 精度在2米左右。

表3-8 geohash长度与精度对应关系

·两个字符串越相似, 它们之间的距离越近, Redis利用字符串前缀匹配算法实现相关的命令。

·geohash编码和经纬度是可以相互转换的。
Redis正是使用有序集合并结合geohash的特性实现了GEO的若干命令。
6.删除地理位置信息
zrem key member
GEO没有提供删除成员的命令, 但是因为GEO的底层实现是zset, 所以可以借用zrem命令实现对地理位置信息的删除。
 

备注:文章参考《Redis开发与运维》,作者:付磊,张益军

 

 

 

 

 

 

 

 

 

 

 

 

 

转载地址:http://anyab.baihongyu.com/

你可能感兴趣的文章
冒号和他的学生们(连载9)——泛型范式
查看>>
冒号和他的学生们(连载13)——范式总结
查看>>
A Proposal on Organization of Information System
查看>>
冒号和他的学生们(连载2)——首轮提问
查看>>
正则表达式与文件格式化处理
查看>>
Java EE互联网轻量级框架整合开发
查看>>
Java语言程序设计(基础篇)
查看>>
大型网站技术架构:核心原理与案例分析
查看>>
JAVA并发编程实战
查看>>
RabbitMQ实战++高效部署分布式消息队列
查看>>
微服务设计
查看>>
Spring Cloud微服务实战
查看>>
C++ static 语义
查看>>
C++ static 语义
查看>>
Linux Cgroups概述
查看>>
centos7 硬盘性能测试
查看>>
cgroup使用--cpu资源限制
查看>>
cgroup使用--memory资源限制
查看>>
Redis 单机环境搭建
查看>>
elasticsearch 单机环境搭建
查看>>