本文共 4379 字,大约阅读时间需要 14 分钟。
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 numpat127.0.0.1:6379> pubsub numpat(integer) 1
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/