Redis缓存(笔记三:Redis6新数据类型)

目录

[1. 介绍](#1. 介绍)

[2. Bitmaps(可以称为字符串,专门进行位操作的字符串)](#2. Bitmaps(可以称为字符串,专门进行位操作的字符串))

[2.1 概念](#2.1 概念)

[2.2 setbit(设置Bitmaps中某个偏移量的值)](#2.2 setbit(设置Bitmaps中某个偏移量的值))

[2.3 getbit(获取Bitmaps中某个偏移量的值)](#2.3 getbit(获取Bitmaps中某个偏移量的值))

[2.4 bitcount(统计字符串被设置为1的bit数,访问过的用户为1,没有访问过的为0)](#2.4 bitcount(统计字符串被设置为1的bit数,访问过的用户为1,没有访问过的为0))

[2.5 bitop(复合操作,将多种情况的操作结果保存在destkey中)](#2.5 bitop(复合操作,将多种情况的操作结果保存在destkey中))

[3. HyperLogLog(做基数处理,去重等..)](#3. HyperLogLog(做基数处理,去重等..))

[3.1 概念](#3.1 概念)

[3.2 pfadd(添加指定元素到HyperLogLog中)](#3.2 pfadd(添加指定元素到HyperLogLog中))

[3.3 pfcount(计算HLL的近似基数)](#3.3 pfcount(计算HLL的近似基数))

[3.4 pfmerge(合并其它的key,进行计算等)](#3.4 pfmerge(合并其它的key,进行计算等))

[4. Geospatial(对经纬度,地理信息等操作)](#4. Geospatial(对经纬度,地理信息等操作))

[4.1 概念](#4.1 概念)

[4.2 geadd(添加地理位置)](#4.2 geadd(添加地理位置))

[4.3 geopos(获取指定地区的坐标值)](#4.3 geopos(获取指定地区的坐标值))

[4.4 geodist(获取两个位置之间的直线距离)](#4.4 geodist(获取两个位置之间的直线距离))

[4.5 georadius(以给定的经纬度为中心,找出某一半径内的元素)](#4.5 georadius(以给定的经纬度为中心,找出某一半径内的元素))


1. 介绍

在Redis 6中,有几种比较特殊且功能强大的数据结构:Bitmaps(位图)、HyperLogLog(超级对数日志)、Geospatial(地理空间)

  1. Bitmaps(位图):
  • 作用:Bitmaps 是 Redis 中的一种非常紧凑和高效的数据结构,用来处理位操作相关的需求。
  • 用途:主要用于记录某些状态或者事件是否发生过,例如用户是否点击过某个按钮、某天是否有用户访问网站等。因为它可以节省大量内存,特别适合于需要高效率地记录大量布尔型状态的场景。
  1. HyperLogLog(超级对数日志):
  • 作用:HyperLogLog 是一种概率性数据结构,用于统计元素的基数(唯一元素的数量),占用固定大小的内存空间。
  • 用途:适合于需要快速估计大数据集合中的唯一元素数量,例如统计网站的独立访客数、统计一周内不同IP地址访问网站的数量等。
  1. Geospatial(地理空间):
  • 作用:Geospatial 是 Redis 提供的一种处理地理位置和坐标的数据结构,可以存储地理位置的经度和纬度,并支持相关的地理位置查询操作。
  • 用途:适合于需要存储和查询地理位置信息的应用场景,如附近的商家搜索、地点推荐等。

2. Bitmaps(可以称为字符串,专门进行位操作的字符串)

2.1 概念
  • Bitmaps本身不是数据类型,他只是字符串,专门进行位操作的字符串;

Bitmaps与set的区别:

提高了空间利用率,提高了cpu内存的利用率;

对比 setBitmaps 在存储独立用户空间方面的差异:

  • setBitmaps 存储独立用户空间对比
数据类型 一天 一个月 一年
set 400MB 12GB 144GB
Bitmaps 12.5MB 375MB 4.5GB
  • 备注
    • Bitmaps 并不是万能的。如果网站每天的独立访问用户很少(例如只有 10 万,大量的僵尸用户),则对比情况如下。
    • Bitmaps 在用户数量少的情况下不太适合,因为这时候大部分位都是 0,使其不太高效。
2.2 setbit(设置Bitmaps中某个偏移量的值)
  • SETBIT 命令用于设置 Bitmaps 中某个偏移量的值,可以将指定位置的位设置为 0 或 1;
    • <key>: Bitmaps 的键
    • <offset>: 偏移量,从 0 开始
    • <value>: 设置的值,只能是 0 或 1
ruby 复制代码
SETBIT <key> <offset> <value>
ruby 复制代码
# 设置键 `userbitmap` 在偏移量 5 处的位值为 1
127.0.0.1:6379> SETBIT userbitmap 5 1
(integer) 0

# 设置键 `userbitmap` 在偏移量 10 处的位值为 1
127.0.0.1:6379> SETBIT userbitmap 10 1
(integer) 0

# 设置键 `userbitmap` 在偏移量 5 处的位值为 0
127.0.0.1:6379> SETBIT userbitmap 5 0
(integer) 1
2.3 getbit(获取Bitmaps中某个偏移量的值)
  • GETBIT 命令用于获取 Bitmaps 中某个偏移量的值,返回该位的值(0 或 1);
    • <key>: Bitmaps 的键
    • <offset>: 偏移量,从 0 开始
ruby 复制代码
GETBIT <key> <offset>
ruby 复制代码
# 获取键 `userbitmap` 在偏移量 5 处的位值
127.0.0.1:6379> GETBIT userbitmap 5
(integer) 0

# 获取键 `userbitmap` 在偏移量 10 处的位值
127.0.0.1:6379> GETBIT userbitmap 10
(integer) 1

# 获取键 `userbitmap` 在偏移量 15 处的位值
127.0.0.1:6379> GETBIT userbitmap 15
(integer) 0
2.4 bitcount(统计字符串被设置为1的bit数,访问过的用户为1,没有访问过的为0)
  • BITCOUNT 命令用于统计 Bitmaps 中被设置为 1 的位的数量。该命令可以统计整个 Bitmaps 的 1 位数,也可以通过指定 startend 参数来统计特定范围内的 1 位数;
    • <key>: Bitmaps 的键
    • [start] (可选): 开始的字节下标,负数表示从末尾开始计算
    • [end] (可选): 结束的字节下标,负数表示从末尾开始计算
ruby 复制代码
BITCOUNT <key> [start end]
ruby 复制代码
# 统计键 `userbitmap` 中所有被设置为 1 的位的数量
127.0.0.1:6379> BITCOUNT userbitmap
(integer) 2
ruby 复制代码
# 统计键 `userbitmap` 在字节 0 到字节 1 范围内被设置为 1 的位的数量
127.0.0.1:6379> BITCOUNT userbitmap 0 1
(integer) 1

# 统计键 `userbitmap` 在最后 2 个字节范围内被设置为 1 的位的数量
127.0.0.1:6379> BITCOUNT userbitmap -2 -1
(integer) 1
2.5 bitop(复合操作,将多种情况的操作结果保存在destkey中)
  • BITOP 命令用于对多个 Bitmaps 进行位运算,包括 AND (交集)、OR (并集)、NOT (非)、XOR (异或)操作,并将结果存储在 destkey 中;
    • <operation>: 运算类型,可以是 ANDORNOTXOR
    • <destkey>: 结果存储的目标键
    • <key>: 输入的源键,可以有一个或多个
ruby 复制代码
BITOP <operation> <destkey> <key> [key...]
  • 操作类型:
    • AND: 交集(所有键中对应位都为 1,则结果位为 1)
    • OR: 并集(至少一个键中对应位为 1,则结果位为 1)
    • NOT: 非(键中对应位取反,NOT 只能有一个源键)
    • XOR: 异或(键中对应位不同则结果位为 1)
ruby 复制代码
# 计算键 `bitmap1` 和 `bitmap2` 的位交集,结果存储在 `result`
127.0.0.1:6379> BITOP AND result bitmap1 bitmap2
(integer) <result-length>
ruby 复制代码
# 计算键 `bitmap1` 和 `bitmap2` 的位并集,结果存储在 `result`
127.0.0.1:6379> BITOP OR result bitmap1 bitmap2
(integer) <result-length>
ruby 复制代码
# 计算键 `bitmap1` 的位取反,结果存储在 `result`
127.0.0.1:6379> BITOP NOT result bitmap1
(integer) <result-length>
ruby 复制代码
# 计算键 `bitmap1` 和 `bitmap2` 的位异或,结果存储在 `result`
127.0.0.1:6379> BITOP XOR result bitmap1 bitmap2
(integer) <result-length>

3. HyperLogLog(做基数处理,去重等..)

  • Redis 提供了三种主要的 HyperLogLog 操作命令:PFADDPFCOUNTPFMERGE。这些命令允许我们高效地执行基数估计、添加元素、统计唯一元素数量、以及合并多个 HyperLogLog;
3.1 概念
  • 在现代应用中,统计数据的基数(Unique Visitors,独立 IP 数,等)是常见需求。传统方法精确但耗费内存大,而 Redis 提供的 HyperLogLog 可以在较低的空间占用下高效估计集合的基数;
  • 基数是集合中不重复元素的个数:数据集 {1, 3, 5, 7, 5, 7, 8},其基数集为 {1, 3, 5, 7, 8},基数为 5;
  • 空间效率: 固定使用约 12 KB 内存;
  • 适用场景: 处理大规模数据集,允许少量误差;
  • 特点
    • 不存储实际元素,仅用于基数估计;
    • 可处理多达 2642^{64}264 个不同元素;
3.2 pfadd(添加指定元素到HyperLogLog中)
  • PFADD 命令用于向 HyperLogLog 中添加元素。如果这些元素是新出现的(即之前没有添加过),HyperLogLog 的估计基数将增加;
    • <key>: HyperLogLog 的键
    • <element>: 要添加的元素,可以是一个或多个
ruby 复制代码
PFADD <key> <element> [element ...]
  • 如果 HyperLogLog visitors 中没有这些元素,它会更新并增加基数估计:
ruby 复制代码
# 添加用户 user1, user2, user3 到 HyperLogLog `visitors`
127.0.0.1:6379> PFADD visitors user1 user2 user3
(integer) 1  # 1 表示基数发生了变化
3.3 pfcount(计算HLL的近似基数)
  • PFCOUNT 命令返回 HyperLogLog 中估计的唯一元素数量。可以对单个或多个 HyperLogLog 进行基数估计;
    • <key>: HyperLogLog 的键,可以是一个或多个;
ruby 复制代码
PFCOUNT <key> [key ...]
  • (integer) 表示估计的唯一元素数量:
ruby 复制代码
# 统计 HyperLogLog `visitors` 中的唯一元素数量
127.0.0.1:6379> PFCOUNT visitors
(integer) 3  # 估计的唯一元素数

# 统计多个 HyperLogLog `visitors1`, `visitors2` 的合并基数
127.0.0.1:6379> PFCOUNT visitors1 visitors2
(integer) 5  # 合并估计的唯一元素数
3.4 pfmerge(合并其它的key,进行计算等)
  • PFMERGE 命令将多个 HyperLogLog 合并为一个目标 HyperLogLog。合并后的结果保存在指定的目标键中;
    • <destkey>: 目标 HyperLogLog 的键
    • <sourcekey>: 源 HyperLogLog 的键,可以是一个或多个
ruby 复制代码
PFMERGE <destkey> <sourcekey> [sourcekey ...]
  • 合并后的 total_visitors 将包含 visitors1visitors2 的所有元素,并估计其总的唯一元素数量;
    • 返回值: OK 表示操作成功
ruby 复制代码
# 合并 HyperLogLog `visitors1`, `visitors2` 到 `total_visitors`
127.0.0.1:6379> PFMERGE total_visitors visitors1 visitors2
OK

4. Geospatial(对经纬度,地理信息等操作)

4.1 概念
  • Redis 3.2 中增加了对 GE0 类型的支持。GE0,Geographic,地理信息的缩写。该类型,就是元素的 2维坐标,在地图上就是经纬度。redis 基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度 Hash 等常见操作;
  • 地理空间数据存储方式
    • Redis 使用有序集合(Sorted Set)来存储地理空间数据。
    • 每个成员(member)都有一个关联的分数(score),这个分数用来排序,通常用来表示成员的位置。
  • 地理位置表示
    • 每个地理位置通过经度(longitude)和纬度(latitude)来表示。
    • Redis 使用二维平面坐标系来存储这些位置信息。
  • 地理位置的索引
    • 有序集合中的每个成员是一个地理位置的标识符,可以是任意字符串。
    • 每个成员都有一个对应的地理坐标(经纬度),以及用来排序的分数。
4.2 geadd(添加地理位置)
  • GEADD 是一个用于向地理空间索引(Geo Index)添加成员的命令,它可以将带有经度和纬度信息的成员添加到指定的地理位置集合(GeoSet)中;
    • <key>: 地理位置集合(GeoSet)的键名。
    • <longitude>: 成员的经度。
    • <latitude>: 成员的纬度。
    • <member>: 要添加的成员名称。
ruby 复制代码
GEADD <key> <longitude> <latitude> <member> [longitude latitude member...]
  • 添加单个成员:
ruby 复制代码
GEADD cities 13.361389 38.115556 "Palermo"
  • 添加多个成员:
ruby 复制代码
GEADD cities 15.087269 37.502669 "Catania" 13.361389 38.115556 "Palermo"
  • 注意事项:
    • GEADD 命令会创建地理位置集合(如果它不存在),并将指定的成员添加到集合中。
    • 成员的经度和纬度需要是有效的浮点数值。
    • 成员名称可以是任何字符串,但必须唯一标识该成员。
4.3 geopos(获取指定地区的坐标值)
  • GEOPOS 是用于获取地理位置集合(GeoSet)中成员的经度和纬度信息的命令。它可以用来查询指定成员在地理位置集合中的坐标信息;
    • <key>: 地理位置集合(GeoSet)的键名。
    • <member>: 要查询坐标信息的成员名称。
ruby 复制代码
GEOPOS <key> <member> [member...]
  • 返回值:

    如果指定的成员存在于地理位置集合中,GEOPOS 返回一个数组,每个成员的坐标用一个两元素的数组表示 [longitude, latitude]。如果成员不存在于集合中,返回 nil

  • 查询单个成员的坐标:

ruby 复制代码
GEOPOS cities "Palermo"
ruby 复制代码
假设 "Palermo" 的坐标是 `[13.361389, 38.115556]`,则命令返回:
ruby 复制代码
1) 1) "13.361389"
   2) "38.115556"
  • 查询多个成员的坐标:
ruby 复制代码
GEOPOS cities "Palermo" "Catania"
ruby 复制代码
假设 "Palermo" 的坐标是 `[13.361389, 38.115556]`,"Catania" 的坐标是 `[15.087269, 37.502669]`,则命令返回:
ruby 复制代码
1) 1) "13.361389"
   2) "38.115556"
2) 1) "15.087269"
   2) "37.502669"
  • 注意事项:
    • GEOPOS 返回的坐标是以字符串形式表示的浮点数,分别代表经度和纬度。
    • 如果查询的成员不存在于地理位置集合中,返回 nil
    • GEOPOS 命令可以用于单个成员或多个成员的查询,允许一次性获取多个成员的坐标信息。
4.4 geodist(获取两个位置之间的直线距离)
  • GEODIST 是用于计算地理位置集合(GeoSet)中两个成员之间距离的命令。它能够返回成员之间的距离,单位默认为米(meters),或者可以通过选项指定为其他单位(如千米、英里等);
    • <key>: 地理位置集合(GeoSet)的键名。
    • <member1>: 第一个成员的名称。
    • <member2>: 第二个成员的名称。
    • [unit]: (可选)距离的单位,可选项包括:
      • m: 米(默认)
      • km: 千米
      • mi: 英里
      • ft: 英尺
ruby 复制代码
GEODIST <key> <member1> <member2> [unit]
  • 返回值:

    如果两个成员都存在于地理位置集合中,GEODIST 返回这两个成员之间的距离。如果其中一个或两个成员不存在于集合中,返回 nil

  • 假设有以下数据:

    • 商店 A 的经纬度为 (13.361389, 38.115556)
    • 商店 B 的经纬度为 (15.087269, 37.502669)
ruby 复制代码
GEODIST stores "storeA" "storeB" km
这表示商店 A 和商店 B 之间的距离是 163.8964 千米:
ruby 复制代码
127.0.0.1:6379> GEODIST stores "storeA" "storeB" km
"163.8964"
4.5 georadius(以给定的经纬度为中心,找出某一半径内的元素)
  • GEORADIUS 是 Redis 中用于根据给定的经纬度和半径查找地理位置元素的命令;
ruby 复制代码
GEORADIUS key longitude latitude radius unit [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
ruby 复制代码
- `key`: Redis 中存储地理位置数据的键名。
- `longitude` 和 `latitude`: 给定的中心点经纬度,用于确定搜索的中心。
- `radius`: 搜索半径,可以是以 `m` (米), `km` (千米), `ft` (英尺), `mi` (英里) 为单位的浮点数。
- `unit`: 单位参数,指定 `radius` 的单位,可以是 `m` (米), `km` (千米), `ft` (英尺), `mi` (英里)。
- `WITHCOORD`: 返回每个位置元素的经纬度。
- `WITHDIST`: 返回每个位置元素与中心点的距离。
- `WITHHASH`: 返回每个位置元素的 geohash 值。
- `COUNT count`: 指定返回的最大元素数量。
- `ASC|DESC`: 结果的排序方式,按距离升序或降序排列。
- `STORE key`: 将结果存储到指定键名的有序集合中。
- `STOREDIST key`: 将结果存储到指定键名的有序集合中,并且同时存储每个位置元素与中心点的距离。
  • 假设我们有一个名为 stores 的 Redis 地理位置集合,其中存储了不同商店的经纬度信息。我们可以使用 GEORADIUS 命令来查找以某一经纬度为中心,半径内的商店。
    • 例如,假设要查找以经度 13.361389 和纬度 38.115556 为中心,半径 2000 米内的商店,并返回商店的经纬度和距离:
    • 这将返回半径 2000 米内所有商店的经纬度和它们与中心点的距离。
ruby 复制代码
GEORADIUS stores 13.361389 38.115556 2000 m WITHCOORD WITHDIST
ruby 复制代码
- 返回结果:
ruby 复制代码
1) 1) "storeA"
   2) 1) "13.36138933897018433"
      2) "38.11555639549629859"
   3) "100.0"    // 与中心点的距离,单位由 WITHDIST 参数决定
2) 1) "storeB"
   2) 1) "13.35622221279144287"
      2) "38.12111264686523257"
   3) "190.0"
相关推荐
掘金-我是哪吒2 分钟前
微服务mysql,redis,elasticsearch, kibana,cassandra,mongodb, kafka
redis·mysql·mongodb·elasticsearch·微服务
密码小丑1 小时前
11月4日(内网横向移动(一))
笔记
鸭鸭梨吖2 小时前
产品经理笔记
笔记·产品经理
ketil272 小时前
Ubuntu 安装 redis
redis
齐 飞2 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
丫头,冲鸭!!!3 小时前
B树(B-Tree)和B+树(B+ Tree)
笔记·算法
王佑辉3 小时前
【redis】redis缓存和数据库保证一致性的方案
redis·面试
听忆.3 小时前
手机屏幕上进行OCR识别方案
笔记
Karoku0664 小时前
【企业级分布式系统】Zabbix监控系统与部署安装
运维·服务器·数据库·redis·mysql·zabbix
Selina K4 小时前
shell脚本知识点记录
笔记·shell