【Redis 其他数据类型】

1. Redis Streams

Redis Streams是一种数据结构,它的行为类似于仅追加日志,但也实现了一些操作来克服典型的仅追加日志的一些限制。其中包括O(1)时间内的随机访问和复杂的消费策略,例如消费者群体。
Redis为每个流条目生成一个唯一的ID。可以使用这些id稍后检索与它们相关的条目,或者读取和处理流中的所有后续条目。请注意,因为这些id与时间有关,这里显示的id可能会有所不同,并且与您在自己的Redis实例中看到的id不同。

注意redis Stream在5.0以上版本支持

使用方法

  • xadds - key id file value [file value] - 创建流并添加消息,其中id为流的唯一标识,可以通过将其设置为*让系统自动生成
  • xread - [COUNT count] [BLOCK milliseconds] STREAMS key [key…] id [ids…] - 从流中读取指定大小的内容,可以设置阻塞时间
  • xrange key start end [count count] - 按照消息id范围从小到大读取指定长度消息
  • xrevrange key start end [count count] - 按照消息id范围从大到小读取指定长度消息
  • xdel key id [ids] - 命令删除指定流中的指定消息
  • xgroup create key groupname id - 创建消费者组,例如:XGROUP CREATE mystream mygroup 0 MKSTREAM,在 mystream 流上创建名为 mygroup 的消费者组,从 ID 为 0 开始,如果流不存在则创建(MKSTREAM 选项)
  • xreadgroup GROUP group consumer [COUNT count] [BLOCK milliseconds] STREAMS key [key…] ID [ID…] - 例如:XREADGROUP GROUP mygroup consumer1 STREAMS mystream >,> 表示从消费者组中尚未被消费的消息开始读取,mygroup 是消费者组,consumer1 是消费者。
  • xack key group ID [ID…] - 例如:XACK mystream mygroup 1234567890-0,确认消费者组 mygroup 中消息 1234567890-0 已被处理
  • xlen key - 返回流中的元素个数

特点

  • 通常redis stream 在写入到一个流中的时间开销是o(1),读取任意一个消息是o(n)
  • 在stream 中自动生成的id由两个部分组成 - 前面一个是本地redis服务器生成的毫秒时间戳,第二个是元素在流中的序号
  • stream自动生成的id一般都是单调递增的,并且其中的时间戳部分如果存在新的时间戳小于前一条条目则会使用前一条目的时间戳,这样即使发生的时间往前跳,id依旧是单调增的
  • 在7.0以上版本可以对id实现部分自动生成,例如:XADD race:usa 0-* racer Prickett
  • 查询时可以使用- + 表示id的最小和最大值XRANGE race:france - +
  • 在查询时可以通过id的时间戳部分进行查询,例如:XRANGE race:france 1692632086369 1692632086371

2. Redis geospatial 位置坐标

Redis地理空间索引允许您存储坐标并搜索它们。这种数据结构对于在给定半径或边界框内查找附近的点非常有用。

使用方法

  • geoadd key longitude latitude member [longitude latitude member …] - 用于将一个或多个地理位置(经度、纬度和名称等信息)添加到指定的键中。- 添加一些城市的地理位置信息到名为cities的键中。假设北京的经度是 116.4074,纬度是 39.9042,那么命令可以是GEOADD cities 116.4074 39.9042 Beijing。如果要添加多个城市,例如再添加上海(经度 121.4737,纬度 31.2304),可以使用GEOADD cities 121.4737 31.2304 Shanghai。
  • geosearch - 计算两个成员之间的距离。- 其中unit可以是m(米)、km(千米)、mi(英里)、ft(英尺)等。
  • geopos - key member [member …] - 获取一个或多个成员的地理位置(经度和纬度)信息。
  • geodist - key member1 member2 [unit]
  • georadius key longitude latitude radius unit [WITHSCORES] [COUNT count] - 以给定的经纬度为中心,查找指定半径内的成员。 -其中WITHSCORES表示是否返回距离分数,COUNT count限制返回的成员数量,ASC|DESC表示按照距离升序或降序排列。
  • georadiusbybox key min - longitude min - latitude max - longitude max - latitude [WITHSCORES] [COUNT count] - 通过一个矩形区域(由两个对角点的经纬度定义)查找成员。- 定义一个矩形区域,左下角经度为 110,纬度为 30,右上角经度为 120,纬度为 40,查找这个区域内的城市可以使用GEORADIUSBYBOX cities 110 30 120 40。

3. Redis bitmaps 位图

位图不是一种实际的数据类型,而是在String类型上定义的一组面向位的操作,它被视为位向量。由于字符串是二进制安全的blob,其最大长度为512 MB,因此它们适合设置最多2^32个不同的位。

使用方法

  • setbit key offset value - 用于设置位图中指定偏移量(offset)处的位值(0 或 1)
  • getbit key offset - 用于获取位图中指定偏移量处的位值。
  • bitcount key [start end] - 用于计算位图中值为 1 的位的数量。
  • bitop operation destkey key1 [key2 …],其中operation可以是AND(与操作)、OR(或操作)、XOR(异或操作)、NOT(非操作,只能用于一个键 - 用于对一个或多个位图进行位操作(如与、或、异或、非等操作),并将结果存储到一个新的位图中

4. Redis bitfields 二进制位域

Redis 的 Bitfields 命令是一种强大的操作,可以在一个 Redis 字符串值内对位域(bit fields)进行操作。它允许在单个操作中对多个位域进行读写操作,这些位域可以是有符号整数(signed integers)或无符号整数(unsigned integers)。这在处理紧凑的二进制数据结构(如存储多个小整数、标志位等)时非常有用。

使用方法

  • bitfileds key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW behavior]
    其中:
    key:要操作的 Redis 键,该键存储的值将被视为位序列。
    GET type offset:用于从指定的偏移量(offset)处获取一个位域的值,type指定了要获取的位域类型(如u8表示无符号 8 位整数、i16表示有符号 16 位整数等)。
    SET type offset value:用于在指定的偏移量(offset)处设置一个位域的值为value,同样type指定了位域类型。
    INCRBY type offset increment:用于将指定偏移量(offset)处的位域值按照increment进行递增或递减(如果increment为负),type为位域类型。
    OVERFLOW behavior:用于指定溢出行为,可选的值有WRAP(环绕,即溢出时从最小值或最大值重新开始)、SAT(饱和,即溢出时保持在最小值或最大值)、FAIL(溢出时操作失败)。

  • 示例

  • 设置位域值 假设我们有一个名为mykey的 Redis 键,初始为空字符串。如果我们想要在这个键对应的位序列中设置一个无符号 8 位整数(u8)在位偏移量为 0 的位置,值为 10,可以使用:

BITFIELDS mykey SET u8 0 10

  • 获取位域值
    要获取刚刚设置的位域值,可以使用:

BITFIELDS mykey GET u8 0
这将返回一个包含一个元素的数组,例如[10]。

  • 递增位域值
    如果要将这个无符号 8 位整数位域的值递增 5(假设之前的值为 10),可以使用:

BITFIELDS mykey INCRBY u8 0 5
再次获取这个位域的值将会得到[15]。

  • 溢出处理示例
    对于无符号 8 位整数,最大值为 255。如果当前值为 250 并且我们执行:

BITFIELDS mykey INCRBY u8 0 10
如果使用OVERFLOW WRAP(默认行为),结果将会是 4(因为 250 + 10 = 260,260 % 256 = 4)。
如果使用OVERFLOW SAT,结果将会是 255(因为超过最大值后保持在最大值)。
如果使用OVERFLOW FAIL,操作将会失败并且返回一个错误。

5. Probabilistic 概率数据

在 Redis 中,有一些概率性数据结构,如 Bloom filter(布隆过滤器)。

Bloom filter 工作原理

Bloom filter 是一种空间效率极高的概率型数据结构,用于判断一个元素是否在一个集合中。它基于位数组和多个哈希函数实现。
当向 Bloom filter 中添加一个元素时,会使用多个哈希函数对该元素进行哈希运算,得到多个哈希值,然后将位数组中这些哈希值对应的位置设置为 1。

当检查一个元素是否在集合中时,同样使用这些哈希函数对元素进行哈希运算,如果得到的所有哈希值对应的位数组位置都为 1,则认为该元素可能在集合中(存在一定的误判率,即可能实际上元素不在集合中,但被判断为在集合中,不过不会将存在的元素判断为不存在)。

Redis 中的 Bloom filter 相关命令(如果 Redis 开启了相关模块)

  • BF.ADD:用于向 Bloom filter 中添加元素。
    例如,如果有一个名为mybf的 Bloom filter,要添加元素"element1",可以使用命令BF.ADD mybf “element1”。
  • BF.EXISTS:用于判断一个元素是否可能存在于 Bloom filter 中。
    例如,要检查"element1"是否在mybf中,可以使用命令BF.EXISTS mybf “element1”,如果返回 1,则表示该元素可能存在;如果返回 0,则表示该元素肯定不存在。
  • BF.MADD(批量添加)和 BF.MEXISTS(批量检查):这两个命令分别用于批量添加元素和批量检查元素是否存在。
    例如,要批量添加"element1"、“element2”、"element3"到mybf中,可以使用命令BF.MADD mybf “element1” “element2” “element3”。要批量检查这些元素是否存在,可以使用命令BF.MEXISTS mybf “element1” “element2” “element3”。

应用中的优势

  • 节省内存空间:对于大规模数据集,尤其是在处理如缓存穿透问题(大量不存在于缓存中的请求穿透到后端数据库)时,使用 Bloom filter 可以用非常小的内存空间快速判断元素是否可能存在,避免不必要的查询。
  • 高效查询:查询速度非常快,因为只需要进行简单的哈希运算和位检查,不需要遍历整个数据集。

还有其他数据结构详细可以查看官方文档 Redis Probabilitic

6. Time series 时间序列

Redis 的时间序列数据类型是一种专门用于存储和处理按时间顺序排列的数据结构。它适用于许多场景,如监控系统(存储 CPU 使用率、内存使用率等指标随时间的变化)、金融数据(股票价格随时间的波动)、物联网(传感器数据采集随时间的记录)等。

使用方法

  • ts.create key [RETENTION retentionTime] [ENCODING encoding] [CHUNK_SIZE chunkSize] [LABELS label value…] -

其中:
key:是时间序列的键名。
RETENTION retentionTime:可选参数,用于指定数据的保留时间,超过这个时间的数据将被自动删除。例如,RETENTION 3600表示保留 1 小时(3600 秒)的数据。
ENCODING encoding:可选参数,用于指定数据的编码方式,不同的编码方式在存储效率和查询性能上有所不同。
CHUNK_SIZE chunkSize:可选参数,定义了数据块的大小,影响数据的存储和查询效率。
LABELS label value…:可以为时间序列添加标签,用于分类和查询,例如LABELS metric cpu_usage表示这个时间序列是关于 CPU 使用率的指标。

  • ts.add key timestamp value [LABELS label value…] - 假设要记录某个服务器在特定时间的 CPU 使用率。如果当前时间戳是 1609459200(对应某个具体时刻),CPU 使用率为 0.8,可以使用TS.ADD cpu_usage 1609459200 0.8。如果还想添加标签,例如服务器名称,可以使用TS.ADD cpu_usage 1609459200 0.8 LABELS server server1。

  • ts.range key fromTimestamp toTimestamp [FILTER filter] [COUNT count] [AGGREGATION aggregationType bucketDurationSeconds] - 要查询cpu_usage时间序列从时间戳 1609459200 到 1609462800 之间的数据,可以使用TS.RANGE cpu_usage 1609459200 1609462800。如果想要按照每 60 秒进行聚合(例如求平均值),并且只返回 10 个数据点,可以使用TS.RANGE cpu_usage 1609459200 1609462800 AGGREGATION avg 60 COUNT 10

  • ts.mrange fromTimestamp toTimestamp [FILTER filter] [COUNT count] [AGGREGATION aggregationType bucketDurationSeconds] [WITHOUT_DATA] keys… - 与TS.RANGE不同的是,TS.MRANGE可以同时查询多个时间序列。例如,要查询cpu_usage和memory_usage这两个时间序列在特定时间段的数据,可以使用TS.MRANGE 1609459200 1609462800 keys cpu_usage memory_usage。

  • ts.into - 用于获取时间序列的信息,如数据点数量、保留时间、编码方式等。例如,TS.INFO cpu_usage将返回关于cpu_usage时间序列的各种信息。

  • ts.deleterules - 用于删除时间序列的规则(如数据保留规则等)。

  • ts.get - 用于获取时间序列中特定时间戳的数据点的值。例如,TS.GET cpu_usage 1609459200将返回在时间戳 1609459200 时cpu_usage时间序列的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值