Redis入门(九)

Redis地理空间(GEO)

简介

从版本 3.2 开始,Redis 引入了地理空间支持,允许用户在 Redis 中存储地理位置信息,并执行一些与地理位置相关的操作。

原理

将球体转换为平面,区块转换为一点

基本命令

1.GEOADD - 将一个或多个地理位置元素添加到指定的键中。每个位置由经度、纬度和成员名称组成。

  • 用途:将一个或多个地理位置元素添加到指定的键中。

  • 语法:GEOADD key longitude latitude member [longitude latitude member ...]

  • 示例

    GEOADD places 116.404 39.915 "Beijing"
    (integer) 1
    GEOADD places -73.993 40.750 "New York"
    (integer) 1

2.GEODIST - 计算两个给定成员之间的距离。可以使用不同的单位来返回结果(例如米、千米、英里等)。

  • 用途:计算两个给定成员之间的距离。

  • 语法GEODIST key member1 member2 [unit]

  • 单位m(米)、km(千米)、mi(英里)、ft(英尺)

  • 示例

    GEODIST places Beijing New York km
    "10684.4115"

3.GEOPOS - 获取一个或多个成员的位置(即经度和纬度)。

  • 用途:获取一个或多个成员的位置(即经度和纬度)。

  • 语法GEOPOS key member [member ...]

  • 示例:

    GEOPOS places Beijing

      1. "116.40400000000000178698"
    2) "39.91499999999999943155"
    

4.GEORADIUS - 在给定的地理位置周围查找所有成员,这些成员位于指定半径内。可以以米或千米为单位指定半径。

  • 用途:在给定的地理位置周围查找所有成员,这些成员位于指定半径内。

  • 语法GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]

  • 示例

    GEORADIUS places 116.404 39.915 100 km WITHDIST

      1. "Beijing"
      2. "0.0000"

5.GEORADIUSBYMEMBER - 类似于 GEORADIUS,但是是以另一个成员的位置为中心来查找附近的其他成员。

  • 用途:类似于 GEORADIUS,但以另一个成员的位置为中心来查找附近的其他成员。

  • 语法:GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]

  • 示例

    GEORADIUSBYMEMBER places Beijing 100 km WITHDIST

      1. "Beijing"
      2. "0.0000"
  • 参数说明

WITHCOORD:返回每个成员的经度和纬度。

WITHDIST:返回每个成员与中心点的距离。

WITHHASH:返回每个成员的 Geohash 整数值。

COUNT count:限制返回的结果数量。

ASC/DESC:按距离升序或降序排列结果。

STORE key:将结果存储到指定的键中。

STOREDIST key:将结果的距离存储到指定的键中。

6.GEOHASH- 返回一个或多个位置元素的Geohash表示。

  • 用途:用来表示一个地理位置的大致范围。

  • 语法:GEOHASH key member [member ...]

  • 示例

    查找距离北京 100 公里内的所有地点

    GEORADIUS places 116.404 39.915 100 km WITHDIST

      1. "Beijing"
      2. "0.0000"

数据存储

地理空间数据在 Redis 中是作为**有序集合(sorted set)**存储的。每个地理位置都有一个唯一的分数,这个分数是由地理位置的经度和纬度计算得出的。因此,Redis 能够高效地处理地理位置的查询。

应用场景

附近的人/地点搜索 : 可以快速找到某个地理位置周围的用户或兴趣点。
路径规划 : 虽然 Redis 不直接支持复杂的路径规划算法,但它可以用来辅助计算两点之间的直线距离。
地理围栏 : 当用户进入或离开特定区域时触发事件。

Redis 流(Stream)

简介

Redis 流(Stream)是从 Redis 5.0 版本开始引入的一种新的数据类型,用于处理实时 数据流。流(Stream)数据类型非常适合用于构建消息队列日志记录系统事件溯源等应用场景。

主要特性

持久化 :流中的数据会被持久化存储,即使 Redis 重启后数据也不会丢失。
追加只读 :流是一个追加只读的数据结构,只能在尾部添加新数据,不能修改已有的数据。
多消费者组 :支持多个消费者组(Consumer Groups),每个组可以有多个消费者(Consumers),实现消息的分布式消费。
消息确认 :消费者可以确认已经处理的消息,未确认的消息可以被重新消费。
历史消息保留:可以根据需要配置保留一定数量的历史消息,超出的部分会被自动删除。

底层结构

一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的 ID 和对应的内容。

|---|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 | Message Content | 消息内容 |
| 2 | Consumer group | 消费组,通过XGROUP CREATE 命令创建,同一个消费组可以有多个消费者 |
| 3 | Last_delivered_id | 游标,每个消费组会有个游标 last_delivered_id,任意一个消费者读取了消息都会使游标 last_delivered_id 往前移动。 |
| 4 | Consumer | 消费者,消费组中的消费者 |
| 5 | Pending_ids | 消费者会有一个状态变量,用于记录被当前消费已读取但未ack的消息Id,如果客户端没有ack,这个变量里面的消息ID会越来越多,一旦某个消息被ack它就开始减少。这个pending_ids变量在Redis官方被称之为 PEL(Pending Entries List),记录了当前已经被客户端读取的消息,但是还没有 ack (Acknowledge character:确认字符),它用来确保客户端至少消费了消息一次,而不会在网络传输的中途丢失了没处理 |

常用命令

队列相关指令

1. XADD
  • 用途:向流中添加一条消息。如果指定的Stream 队列不存在,则该命令执行时会新建一个Stream 队列.

  • 语法:XADD key [MAXLEN/LIMIT] count message

  • 示例:

    XADD mystream * sensor-id 1234 temperature 19.8
    1626893541302-0

* 表示让 Redis 自动生成一个唯一的消息 ID。类似mysql里面主键auto_increment,后面顺序跟着一堆业务key/value。

sensor-id 1234 temperature 19.8 是消息的内容,键值对形式。

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 信息条目指的是序列号,在相同的毫秒下序列号从0开始递增,序列号是64位长度,理论上在同一毫秒内生成的数据量无法到达这个级别,因此不用担心序列号会不够用。millisecondsTime指的是Redis节点服务器的本地时间,如果存在当前的毫秒时间戳比以前已经存在的数据的时间戳小的话(本地时间钟后跳),那么系统将会采用以前相同的毫秒创建新的ID,也即redis 在增加信息条目时会检查当前 id 与上一条目的 id, 自动纠正错误的情况,一定要保证后面的 id 比前面大,一个流中信息条目的ID必须是单调增的,这是流的基础。 |
| 客户端显示传入规则: Redis对于ID有强制要求,格式必须是 时间戳-自增Id这样的方式,且后续ID不能小于前一个ID |
| Stream的消息内容,也就是图中的Message Content它的结构类似Hash结构,以key-value的形式存在。 |

2. XREAD
  • 用途:从一个或多个流中读取消息。只会返回大于指定ID的消息。

  • 语法:XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]

  • 示例:

    XREAD COUNT 2 STREAMS mystream 0

      1. "mystream"
          1. "1626893541302-0"
          1. "sensor-id"
          2. "1234"
          3. "temperature"
          4. "19.8"
          1. "1626893541303-0"
          1. "sensor-id"
          2. "1234"
          3. "temperature"
          4. "20.1"

count表示最多可以读取多少条消息

BLOCK表示是否以阻塞的方式读取消息,默认不阻塞,如果 milliseconds设置为0,表示 永远阻塞。

|-----------------------------------------------------------------------------------|
| $代表特殊ID,表示以当前Stream已经存储的最大的ID作为最后一个ID,当前Stream中不存在大于当前最大ID的消息,因此此时返回nil |
| 0-0代表从最小的ID开始获取Stream中的消息,当不指定count,将会返回Stream中的所有消息,注意也可以使用0(00/000也都是可以的......) |

Stream的基础方法,使用xadd存入消息和xread循环阻塞读取消息的方式可以实现简易版的消息队列,交互流程如下:

3. XRANGE
  • 用途:按时间顺序返回流中的消息。

  • 语法:XRANGE key start end [COUNT count]

  • 示例:

    XRANGE mystream - +

      1. "1626893541302-0"
        1. "sensor-id"
        2. "1234"
        3. "temperature"
        4. "19.8"
      1. "1626893541303-0"
        1. "sensor-id"
        2. "1234"
        3. "temperature"
        4. "20.1"
  • 表示从最早的 ID 开始。
  • 表示到最新的 ID 结束。
4. XREVRANGE
  • 用途:按逆时间顺序返回流中的消息。

  • 语法:XREVRANGE key end start [COUNT count]

  • 示例:

    XREVRANGE mystream + -

      1. "1626893541303-0"
        1. "sensor-id"
        2. "1234"
        3. "temperature"
        4. "20.1"
      1. "1626893541302-0"
        1. "sensor-id"
        2. "1234"
        3. "temperature"
        4. "19.8"
5.XDEL
  • 用途:删除流中的一个或多个消息。

  • 语法:XDEL key id [id ...]

  • 示例:

    XDEL mystream 1626893541302-0
    (integer) 1

6.XLEN
  • 用途:获取流中的消息数量。

  • 语法:XLEN key

  • 示例:

    XLEN mystream
    (integer) 3

如果尝试获取一个不存在的流的消息数量,XLEN 将返回 0。

消费组相关指令

1. XGROUP CREATE
  • 用途:创建一个新的消费者组。

  • 语法:XGROUP CREATE key groupname id-or-$

  • 示例:

    XGROUP CREATE mystream group1 0
    OK

group1 是消费者组的名称。

0 表示从最早的未确认消息开始消费。

$表示从Stream尾部开始消费

0表示从Stream头部开始消费

创建消费者组的时候必须指定 ID, ID 为 0 表示从头开始消费,为 $ 表示只消费新的消息,队尾新来

2. XREADGROUP
  • 用途:从流中读取消息,支持消费者组。

  • 语法:XREADGROUP GROUP groupname consumername [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]

  • 示例:

    XREADGROUP GROUP group1 consumer1 COUNT 2 STREAMS mystream >

      1. "mystream"
          1. "1626893541302-0"
          1. "sensor-id"
          2. "1234"
          3. "temperature"
          4. "19.8"
          1. "1626893541303-0"
          1. "sensor-id"
          2. "1234"
          3. "temperature"
          4. "20.1"

GROUP group1 consumer1 表示从 group1 消费者组中读取,consumer1 是消费者名称。

> 表示从最新的未确认消息开始消费。

stream中的消息一旦被消费组中的一个消费者读取,就不能被该消费组内的其他成员读取了,即同一个消费组 里的消费者不能 消费同一条消息,不同消费组 的消费者可以消费同一条消息。

让组内的多个消费者共同分担读取消息,我们通常会让每个消费者读取部分消息,从而实现消息读取负载在多个消费者间是均衡分布的。

3. XACK
  • 用途:确认消息已被成功处理。

  • 语法:XACK key groupname id [id ...]

  • 示例:

    XACK mystream group1 1626893541302-0
    (integer) 1

4. XINFO
  • 用途:获取流的各种信息。

  • 语法:XINFO subcommand key [extra arguments]

  • 示例:

    XINFO STREAM mystream

    1. length
    2. (integer) 2
    3. first-entry
      1. "1626893541302-0"
        1. "sensor-id"
        2. "1234"
        3. "temperature"
        4. "19.8"
    4. last-entry
      1. "1626893541303-0"
        1. "sensor-id"
        2. "1234"
        3. "temperature"
        4. "20.1"
5.XPENDING
  • 用途:查询每个消费组内所有消费者[已读取,但尚未确认]的消息,或查看某个消费者具体读取了哪些数据。

  • 语法:XPENDING key groupname [start end count] [consumer]

  • 示例:

    XPENDING mystream group1 - + 10 consumer1

      1. "1626893541302-0"
      2. "consumer1"
      3. (integer) 1000
      4. (integer) 1

这表明 consumer1 有 1 条待处理消息。

应用场景

消息队列 :使用 Redis 流可以构建高性能的消息队列系统,支持多消费者组和消息确认机制。
日志记录 :流可以用于记录应用程序的日志,支持按时间顺序读取和归档。
事件溯源:流可以用于记录系统的状态变化,支持历史数据的查询和分析。

相关推荐
m0_748230218 分钟前
mysql约束和高级sql
数据库·sql·mysql
刘艳兵的学习博客14 分钟前
刘艳兵-DBA046-ASSM表空间的全表扫描范围由哪些因素综合确定?
数据库·sql·oracle·刘艳兵
2401_8576363917 分钟前
实验室管理技术革新:Spring Boot系统
数据库·spring boot·后端
生活很暖很治愈1 小时前
C51数字时钟/日历---LCD1602液晶显示屏
数据库·单片机·mongodb
YONG823_API1 小时前
1688商品数据采集API的测试对接步骤分享(提供免费测试key)
开发语言·数据库·爬虫·python·数据挖掘
码上一元1 小时前
掌握 Spring 事务管理:深入理解 @Transactional 注解
数据库·spring
程序猿毕设源码分享网1 小时前
基于springboot停车场管理系统源码和论文
数据库·spring boot·后端
YiSLWLL2 小时前
Django+Nginx+uwsgi网站使用Channels+redis+daphne实现简单的多人在线聊天及消息存储功能
服务器·数据库·redis·python·nginx·django
.生产的驴2 小时前
Docker Seata分布式事务保护搭建 DB数据源版搭建 结合Nacos服务注册
数据库·分布式·后端·spring cloud·docker·容器·负载均衡
盖盖衍上2 小时前
4.4 MySQL 触发器(Trigger)
数据库·mysql