当前位置: 首页 > ops >正文

Redis-基数统计、位图、位域、流

Redis-基数统计、位图、位域、流

  • 一、基数统计 HyperLogLog
  • 二、位图 Bitmap
  • 三、位域 Bitfild
  • 四、流 Stream


一、基数统计 HyperLogLog

基数统计:是用来做基数(不重复的数)统计的算法
统计不重复出现的数据的个数

基数统计VS集合
集合:

uv = 独立用户浏览量
nginx => 服务端可以获取客户端的ip地址
统计UV => 用Set统计IP信息 => 保留输入的元素本身(IP) => 浪费空间
=> 用HyperLogLog统计 => 只会根据输入的元素(IP)来计算基数, 不会存储输入的元素本身,只能返回元素去重后的个数

  • 优点:当输入元素量特别大时,HyperLogLog需要的空间总是固定的且很小。HyperLogLog键只需要花费12k内存就可以存储2^64不同个元素的基数
  • 缺点:会有0.81%的误差

应用场景:
统计网站UV/文章UV
统计访问人数
热门关键字搜索次数 => count:sc

核心命令

pfadd 添加元素
pfcount 获取基数的个数

127.0.0.1:6379> pfadd hll1 1 2 3 4 5 6 7
(integer) 1
127.0.0.1:6379> pfcount hll1
(integer) 7
127.0.0.1:6379> pfadd hll1 5
(integer) 0

pfmerge 合并基数

127.0.0.1:6379> pfadd hll2 5 6 7 8 9
(integer) 1
127.0.0.1:6379> pfmerge hll3 hll1 hll2
OK
127.0.0.1:6379> pfcount hll3
(integer) 9
127.0.0.1:6379> pfcount hll3 hll1
(integer) 9

二、位图 Bitmap

二进制bit数组 => 每个元素由0和1状态 => 由0和1组成string
010101101

位图 Bitmap => 省空间

使用场景:

  • 用户表:

  • 用户名、…、性别、是否登录、A权限、C权限、D权限、30个权限

  • 数据只有两种状态 => 30个权限 => 设置30个字段
    => 设置1个字段,字段由30位的字符串组成
    01010100011111010101

    cici:A
    cici:B

    cici:permission 101010101001

  • 打卡统计:
    日历表 => 今年的签到情况
    日期、用户、是否签到
    cici:daka 111111111111111111111111111111111111111111

核心命令

setbit key offset value 设置指定偏移量的位(0 或 1)

127.0.0.1:6379> setbit bit1 1 1
(integer) 0
127.0.0.1:6379> setbit bit1 2 0
(integer) 0
127.0.0.1:6379> setbit bit1 0 1
(integer) 0

getbit key offset 查询指定偏移量的位值

127.0.0.1:6379> getbit bit1 1
(integer) 1
127.0.0.1:6379> getbit bit1 0
(integer) 1
127.0.0.1:6379> getbit bit1 2
(integer) 0

统计占用字节数

127.0.0.1:6379> strlen bit1
(integer) 1
127.0.0.1:6379> setbit bit1 200 1
(integer) 0
127.0.0.1:6379> strlen bit1
(integer) 26

bitcount统计值为 1 的位数量

127.0.0.1:6379> bitcount bit1
(integer) 3

位级操作

与 或 非 异或
AND OR NOT XOR

bitop

127.0.0.1:6379> set bitkey1 "\x0F"    # 00001111
OK
127.0.0.1:6379> set bitkey2 "\x33"    # 00110011
OK127.0.0.1:6379> bitop and result bitkey1 bitkey2
(integer) 1
127.0.0.1:6379> get result
"\x03"127.0.0.1:6379> bitop or result bitkey1 bitkey2
(integer) 1
127.0.0.1:6379> get result
"?"127.0.0.1:6379> bitop xor result bitkey1 bitkey2
(integer) 1
127.0.0.1:6379> get result
"<"127.0.0.1:6379> bitop not result bitkey1
(integer) 1
127.0.0.1:6379> get result
"\xf0"

三、位域 Bitfild

Redis字符串可以看作由二进制组成的数组
bitfileld命令可以一次性操作连续的多个bit位,并返回一个响应数组
相当于可以直接修改二进制数据,实现更高效的操作

bitfield 按位域读取 ASCII 码

127.0.0.1:6379> set field1 sanchuang
OK
127.0.0.1:6379> type field1
string
# 读取从位偏移 0开始的 8 位(即第 1 个字节)
127.0.0.1:6379> bitfield field1 get i8 0
1) (integer) 115
# 读取从位偏移 8开始的 8 位(即第 2 个字节)
127.0.0.1:6379> bitfield field1 get i8 8
1) (integer) 97
# 读取从位偏移 16开始的 8 位(即第 3 个字节)
127.0.0.1:6379> bitfield field1 get i8 16
1) (integer) 110

设置位域值

127.0.0.1:6379> bitfield field1 set i8 0 97
1) (integer) 115
127.0.0.1:6379> get field1
"aanchuang"

位域增减,配合 overflow 控制溢出

127.0.0.1:6379> bitfield field1 incrby i8 0 16
1) (integer) 113
127.0.0.1:6379> bitfield field1 incrby i8 0 200
1) (integer) 57
127.0.0.1:6379> get field1
"9anchuang"

当数据溢出overflow

  • WRAP 使用回绕方法处理溢出情况。进位去除 => 默认
  • SAT 使用饱和计算处理溢出情况。 下溢出取最小整数值,上溢出取最大整数值
  • FAIL 拒绝执行溢出计算
# 指定溢出策略为 FAIL
127.0.0.1:6379> bitfield field1 overflow fail set i8 0 300
1) (nil)
127.0.0.1:6379> get field1
"9anchuang"
# 指定溢出策略为 SAT
127.0.0.1:6379> bitfield field1 overflow sat set i8 0 300
1) (integer) 57
127.0.0.1:6379> get field1
"\x7fanchuang"

四、流 Stream

主要用于消息队列(消息中间件MQ)

MQ => Kafaka, rabbitMQ(专业)

生产者-消费者-模型

Redis Stream提供了消息的持久化、主备复制功能

生产数据
xadd keyname id key value [key value]
ID格式:毫秒时间戳-n、当前ID必须比上个ID大
=> 自动生成ID

向流中添加信息

127.0.0.1:6379> xadd mystream * name cici age 10
"1756525141761-0"
127.0.0.1:6379> xadd mystream 1756525202000-1 name wen
"1756525202000-1"
127.0.0.1:6379> type mystream
stream

插入10条数据

127.0.0.1:6379> xadd mystream * name cici1 age 10
"1756525378170-0"
127.0.0.1:6379> xadd mystream * name cici2 age 10
"1756525381002-0"
127.0.0.1:6379> xadd mystream * name cici3 age 10
"1756525383874-0"
127.0.0.1:6379> xadd mystream * name cici4 age 10
"1756525386242-0"
127.0.0.1:6379> xadd mystream * name cici5 age 10
"1756525389683-0"
127.0.0.1:6379> xadd mystream * name cici6 age 10
"1756525392132-0"
127.0.0.1:6379> xadd mystream * name cici7 age 10
"1756525394594-0"
127.0.0.1:6379> xadd mystream * name cici8 age 10
"1756525398326-0"
127.0.0.1:6379> xadd mystream * name cici9 age 10
"1756525401303-0"
127.0.0.1:6379> xadd mystream * name cici10 age 10
"1756525404362-0"

获取消息
小到大
xrange keyname start(-最小值) end(+最大值)
大到小
xrevrange keyname end(+最大值) start(-最小值)
队列长度
xlen keyname

127.0.0.1:6379> xrange mystream - + 1) 1) "1756525141761-0"2) 1) "name"2) "cici"3) "age"4) "10"127.0.0.1:6379> xrange mystream - + count 2
1) 1) "1756525141761-0"2) 1) "name"2) "cici"3) "age"4) "10"
2) 1) "1756525202000-1"2) 1) "name"2) "wen"127.0.0.1:6379> xrevrange mystream + - count 1
1) 1) "1756525404362-0"2) 1) "name"2) "cici10"3) "age"4) "10"127.0.0.1:6379> xlen mystream
(integer) 12

读取消息(读取指定id后的消息-不包含当前id)
id: id/0(最小)/$(最大的后一条-用于阻塞获取)
xread [count n] [block 0/1] streams keyname id

127.0.0.1:6379> xread count 2 streams mystream 1756525202000-1
1) 1) "mystream"2) 1) 1) "1756525378170-0"2) 1) "name"2) "cici1"3) "age"4) "10"2) 1) "1756525381002-0"2) 1) "name"2) "cici2"3) "age"4) "10"127.0.0.1:6379> xread count 2 streams mystream 0
1) 1) "mystream"2) 1) 1) "1756525141761-0"2) 1) "name"2) "cici"3) "age"4) "10"2) 1) "1756525202000-1"2) 1) "name"2) "wen"

查询 Stream 数据类型 相关信息

127.0.0.1:6379> xinfo stream mystream1) "length"2) (integer) 123) "radix-tree-keys"4) (integer) 15) "radix-tree-nodes"6) (integer) 27) "last-generated-id"8) "1756525404362-0"9) "max-deleted-entry-id"
10) "0-0"
11) "entries-added"
12) (integer) 12
13) "recorded-first-entry-id"
14) "1756525141761-0"
15) "groups"
16) (integer) 0
17) "first-entry"
18) 1) "1756525141761-0"2) 1) "name"2) "cici"3) "age"4) "10"
19) "last-entry"
20) 1) "1756525404362-0"2) 1) "name"2) "cici10"3) "age"4) "10"

删除消息

127.0.0.1:6379> xdel mystream 1756525141761-0
(integer) 1

使用场景 (MQ => 提升效率)

  • 有非常多任务需要处理
  • web - 定时任务(生成周报、生成月报-发送给用户)
  • 1w个执行生成周报 => 1个用户生成一个消息 => 消息队列
    生产机(1.10)
    MQ(1.11) 1w 存储与管理消息
    消息者(1.12, 1.13, 1.14) 并行处理任务
http://www.xdnf.cn/news/19139.html

相关文章:

  • LangChain.js 实战与原理:用 LCEL 构建可维护的 RAG / Agent 系统(含 4 套 30+ 行代码)
  • 大语言模型生成的“超龄劳动者权益保障制度系统化完善建议(修订版)”
  • Day17(前端:JavaScript基础阶段)
  • Elasticsearch:Semantic text 字段类型
  • PostgreSQL令牌机制解析
  • Linux从入门到进阶--第四章--Linux使用操作
  • TuringComplete游戏攻略(2.1算数运算)
  • Xshell 自动化脚本大赛技术文章大纲
  • BGP路由协议(三):路径属性
  • Git 的核心工作流程(三区域模型)
  • 第四章:大模型(LLM)】08.Agent 教程-(11)构建历史与数据分析协作系统
  • Kafka 主题级配置从创建到优化
  • 第二十六天-ADC基本原理
  • 一个wordpress的网站需要什么样的服务器配置
  • 医疗AI时代的生物医学Go编程:高性能计算与精准医疗的案例分析(七)
  • 本地运行的检索PDF文件中出现关键字的python程序
  • Coze源码分析-API授权-编辑令牌-后端源码
  • K8s服务日志收集方案文档
  • 【90页PPT】新能源汽车数字化转型SAP解决方案(附下载方式)
  • (纯新手教学)计算机视觉(opencv)实战十——轮廓特征(轮廓面积、 轮廓周长、外接圆与外接矩形)
  • Redis 缓存热身(Cache Warm-up):原理、方案与实践
  • docker,mysql安装
  • 35.Ansible的yaml语法与playbook的写法
  • 嵌入式Linux I2C驱动开发
  • 从零到一:使用Flask构建“我的笔记”网站
  • [光学原理与应用-337]:ZEMAX - 自带的用于学习的样例设计
  • LeetCode100-240搜索二维矩阵Ⅱ
  • Mysql常用函数
  • 针对 “TCP 会话维持与身份验证” 的攻击
  • LabVIEW测斜设备承压试验台