Redis新数据类型

2023-10-28

Bitmaps

1.简介

现代计算机用二进制(位) 作为信息的基础单位, 1个字节等于8位, 例如“abc”字符串是由3个字节组成, 但实际在计算机存储时将其用二进制表示, “abc”分别对应的ASCII码分别是97、 98、 99, 对应的二进制分别是01100001、 01100010和01100011,如下图
在这里插入图片描述
合理地使用操作位能够有效地提高内存使用率和开发效率。
Redis提供了Bitmaps这个“数据类型”可以实现对位的操作:
(1)Bitmaps本身不是一种数据类型, 实际上它就是字符串(key-value) , 但是它可以对字符串的位进行操作。
(2)Bitmaps单独提供了一套命令, 所以在Redis中使用Bitmaps和使用字符串的方法不太相同。 可以把Bitmaps想象成一个以位为单位的数组, 数组的每个单元只能存储0和1, 数组的下标在Bitmaps中叫做偏移量。

在这里插入图片描述

2.命令

#setbit

(1)格式
setbit<key><offset><value>设置Bitmaps中某个偏移量的值(0或1)
在这里插入图片描述

*offset:偏移量从0开始
实例:
想统计某个用户是否访问过某个网站。
每个独立用户是否访问过网站存放在Bitmaps中, 将访问的用户记做1, 没有访问的用户记做0, 用偏移量作为用户的id。
设置键的第offset个位的值(从0算起) , 假设现在有20个用户,userid=1, 6, 11, 15, 19的用户对网站进行了访问, 那么当前Bitmaps初始化结果如图

在这里插入图片描述
使用setbit 命令操作,将用户id未1,6,11,15,19都设置为访问过网站 1
在这里插入图片描述

注:
很多应用的用户id以一个指定数字(例如10000) 开头, 直接将用户id和Bitmaps的偏移量对应势必会造成一定的浪费, 通常的做法是每次做setbit操作时将用户id减去这个指定数字。
在第一次初始化Bitmaps时, 假如偏移量非常大, 那么整个初始化过程执行会比较慢, 可能会造成Redis的阻塞

getbit
(1)格式
getbit<key><offset>获取Bitmaps中某个偏移量的值
在这里插入图片描述
获取键的第offset位的值(从0开始算)
访问过得都是1
在这里插入图片描述
未访问过得都是0
在这里插入图片描述
注:因为100根本不存在,所以也是返回0
在这里插入图片描述
bitcount
统计字符串被设置为1的bit数。一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。start 和 end 参数的设置,都可以使用负数值:比如 -1 表示最后一个位,而 -2 表示倒数第二个位,start、end 是指bit组的字节的下标数,二者皆包含。
(1)格式
bitcount<key>[start end] 统计字符串从start字节到end字节比特值为1的数量

在这里插入图片描述
例如:
统计1的数量
命令:bitcount users:20210101
返回的是5,因为把5个的值设置成了1
在这里插入图片描述

start和end代表起始和结束字节数, 下面操作计算用户id在第1个字节到第3个字节之间的独立访问用户数, 对应的用户id是11, 15, 19。
举例: K1 【01000001 01000000 00000000 00100001】,对应【0,1,2,3】
bitcount K1 1 2 : 统计下标1、2字节组中bit=1的个数,即01000000 00000000
–》bitcount K1 1 2   --》1

bitcount K1 1 3 : 统计下标1、2字节组中bit=1的个数,即01000000 00000000 00100001
–》bitcount K1 1 3  --》3

bitcount K1 0 -2 : 统计下标0到下标倒数第2,字节组中bit=1的个数,即01000001 01000000 00000000
–》bitcount K1 0 -2  --》3

注意:redis的setbit设置或清除的是bit位置,而bitcount计算的是byte位置。

bitop
(1)格式

bitop  and(or/not/xor) <destkey> [key…]

bitop是一个复合操作, 它可以做多个Bitmaps的and(交集) 、 or(并集) 、 not(非) 、 xor(异或) 操作并将结果保存在destkey中。

实例:
2020-11-04 日访问网站的userid=1,2,5,9。
setbit unique:users:20201104 1 1
setbit unique:users:20201104 2 1
setbit unique:users:20201104 5 1
setbit unique:users:20201104 9 1
在这里插入图片描述

2020-11-03 日访问网站的userid=0,1,4,9。
setbit unique:users:20201103 0 1
setbit unique:users:20201103 1 1
setbit unique:users:20201103 4 1
setbit unique:users:20201103 9 1
在这里插入图片描述

计算出两天都访问过网站的用户数量

bitop and unique:users:and:20201104_03
 unique:users:20201103 unique:users:20201104

在这里插入图片描述
返回2的原因是因为在这2天中都访问过得用户id是2个。分别是1和9
在这里插入图片描述

在这里插入图片描述

计算出任意一天都访问过网站的用户数量(例如月活跃就是类似这种) , 可以使用or求并集

Bitmaps与set对比

假设网站有1亿用户, 每天独立访问的用户有5千万, 如果每天用集合类型和Bitmaps分别存储活跃用户可以得到表
在这里插入图片描述
很明显, 这种情况下使用Bitmaps能节省很多的内存空间, 尤其是随着时间推移节省的内存还是非常可观的
在这里插入图片描述
但Bitmaps并不是万金油, 假如该网站每天的独立访问用户很少, 例如只有10万(大量的僵尸用户) , 那么两者的对比如下表所示, 很显然, 这时候使用Bitmaps就不太合适了, 因为基本上大部分位都是0。
在这里插入图片描述

HyperLogLog

简介

在工作当中,我们经常会遇到与统计相关的功能需求,比如统计网站PV(PageView页面访问量),可以使用Redis的incr、incrby轻松实现。
但像UV(UniqueVisitor,独立访客)、独立IP数、搜索记录数等需要去重和计数的问题如何解决?这种求集合中不重复元素个数的问题称为基数问题。
解决基数问题有很多种方案:
(1)数据存储在MySQL表中,使用distinct count计算不重复个数
(2)使用Redis提供的hash、set、bitmaps等数据结构来处理
以上的方案结果精确,但随着数据不断增加,导致占用空间越来越大,对于非常大的数据集是不切实际的。
能否能够降低一定的精度来平衡存储空间?Redis推出了HyperLogLog
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

什么是基数?
比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

命令

pfadd
1)格式
pfadd < element> [element …] 添加指定元素到 HyperLogLog 中
在这里插入图片描述
实例:

pfadd program "java"
pfadd program "php" 
pfadd program "java"

因为pfadd program "java"第一次已经添加了,所以第二次执行命令的时候是0
在这里插入图片描述
也可以多个添加:

pfadd program "vue" "c++" 

在这里插入图片描述
将所有元素添加到指定HyperLogLog数据结构中。如果执行命令后HLL估计的近似基数发生变化,则返回1,否则返回0。

pfcount
(1)格式
pfcount [key …] 计算HLL的近似基数,可以计算多个HLL,比如用HLL存储每天的UV,计算一周的UV可以使用7天的UV合并计算即可
在这里插入图片描述

实例:

pfcount program

显示的是4,因为 刚刚添加了4个,分别是java,php,vue,c++
在这里插入图片描述

pfmerge
(1)格式
pfmerge [sourcekey …] 将一个或多个HLL合并后的结果存储在另一个HLL中,比如每月活跃用户可以使用每天的活跃用户来合并计算可得
在这里插入图片描述

实例:
先添加个k1 赋2个值 a b
在这里插入图片描述
现在想把program和k1做合并加入到另外一个k2里面去

pfmerge k2 program k1

在这里插入图片描述
在使用pfcount k2 看k2的个数是6 因为program中有4个 k1中有2个
在这里插入图片描述

Geospatial

简介

Redis 3.2 中增加了对GEO类型的支持。GEO,Geographic,地理信息的缩写。该类型,就是元素的2维坐标,在地图上就是经纬度。redis基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度Hash等常见操作。

命令

geoadd
geoadd< longitude> [longitude latitude member…] 添加地理位置(经度,纬度,名称)
在这里插入图片描述
实例:

geoadd china:city 121.47 31.23 shanghai
geoadd china:city 106.50 29.53 chongqing 114.05 22.52 shenzhen 116.38 39.90 beijing

在这里插入图片描述

两极无法直接添加,一般会下载城市数据,直接通过 Java 程序一次性导入。
有效的经度从 -180 度到 180 度。有效的纬度从 -85.05112878 度到 85.05112878 度。
当坐标位置超出指定范围时,该命令将会返回一个错误。
已经添加的数据,是无法再次往里面添加的。
实例:
geopos
(1)格式
geopos [member…] 获得指定地区的坐标值
在这里插入图片描述
实例:

geopos china:city shanghai
geopos china:city beijing

在这里插入图片描述

geodist
(1)格式
geodist [m|km|ft|mi ] 获取两个位置之间的直线距离
在这里插入图片描述
实例:
例如:北京到上海的直线距离 单位以km为例

geodist china:city shanghai beijing km

在这里插入图片描述
单位:
m 表示单位为米[默认值]。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。
如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位

georadius
(1)格式
georadius< longitude>radius m|km|ft|mi 以给定的经纬度为中心,找出某一半径内的元素
在这里插入图片描述
经度 纬度 距离 单位
查看符合东京110度北纬30度 半径为1000km的元素
命令:

georadius china:city 110 30  1000 km

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Redis新数据类型 的相关文章

  • Spring RedisTemplate:8次调用后方法键挂起

    我使用 Spring RedisTemplate spring data redis 1 7 1 与 Redis 进行通信 我需要通过正则表达式获取然后删除键 例如 context user1 我用的方法 RedisTemplate key
  • 保护节点 Redis

    我正在尝试保护 Node Redis IPC 服务器以使用私钥 公钥 我已经关注了本教程 http bencane com 2014 02 18 sending redis traffic through an ssl tunnel wit
  • 如何在节点redis客户端上设置读取超时?

    在 github 上我没有看到读取超时的选项 https github com NodeRedis node redis https github com NodeRedis node redis There s connect timeo
  • Docker-compose Predis 不通过 PHP 连接

    我正在尝试使用 docker compose 将 PHP 与 redis 连接 docker compose yml version 2 services redis image redis 3 2 2 php image company
  • Redis hash写入速度非常慢

    我面临一个非常奇怪的问题 使用 Redis 时 我的写入速度非常糟糕 在理想的情况下 写入速度应该接近 RAM 上的写入速度 这是我的基准 package redisbenchmark import redis clients jedis
  • Redis 排序集和解决关系

    我正在使用 Redis 排序集来存储我正在处理的项目的排名 我们没有预料到 我们想要如何处理关系 Redis 按字典顺序对具有相同分数的条目进行排序 但我们想要做的是对具有相同分数的所有条目给予相同的排名 例如在以下情况 redis 127
  • redis 阻塞直到 key 存在

    我是 Redis 新手 想知道是否有办法能够await get通过它的键来获取值 直到该键存在 最小代码 async def handler data await self fetch key async def fetch key ret
  • 通过 StackExchange.Redis 连接到 Redis Servier

    我尝试使用以下方法制作一个测试项目Redis https redis io服务器 通过 Virtual Box 安装在 Linux Ubuntu 虚拟机上 Linux 机器通过 Virtual Box 的桥接适配器与本地网络连接 Virtu
  • 如何测试我的 Redis 缓存是否正常工作?

    我已经安装了 django redis cache 和 redis py 我遵循了 Django 的缓存文档 据我所知 以下设置就是我所需要的 但我如何判断它是否正常工作 设置 py CACHES default BACKEND redis
  • SignalR 无法连接到 SSL 上的 Azure Redis

    我目前在 Azure 上托管我的 redis 缓存服务器 并让 signalR 依赖它作为骨干 使用以下内容 GlobalHost DependencyResolver UseRedis 服务器 端口 密码 eventKey 这可以在端口
  • 无法启动redis.service:单元redis-server.service被屏蔽

    我在 ubuntu 16 04 上安装了 Redis 服务器 但是当我尝试使用启动redis服务时 sudo systemctl start redis 我收到消息 Failed to start redis service Unit re
  • Redis Docker compose无法处理RDB格式版本10

    我无法在 docker compose 文件中启动 redis 容器 我知道docker compose文件没问题 因为我的同事可以成功启动项目 我读到有一个删除 dump rdb 文件的解决方案 但我找不到它 我使用Windows机器 任
  • 为什么 Redis TimeSeries 不捕获聚合中的最后一个元素?

    我试图了解 Redis 的时间序列规则创建的工作原理 但我很困惑为什么 Redis 会忽略聚合中的最后一项 并想知道这是否是预期的行为 我在中创建了示例代码redis cli为了显示 127 0 0 1 6379 gt FLUSHALL O
  • Laravel 所有会话 ID 与 Redis 驱动程序

    在我的应用程序中 我希望允许某些用户能够注销除他 她之外的所有其他用户 当会话驱动程序设置为文件时 我已经完成了此功能 但现在我使用 redis 作为会话驱动程序 并且我无法找到任何方法来列出所有当前会话 就像我在文件时所做的那样司机 问题
  • 为什么Redis中没有有序的hashmap?

    Redis 数据类型 http redis io topics data types包括排序集 http redis io topics data types intro sorted sets以及其他用于键值存储的必要数据结构 但我想知道
  • 在 Redis 上为 Django 和 Express.js 应用程序共享会话存储

    我想创建一个包含一些登录用户的 Django 应用程序 另一方面 由于我想要一些实时功能 所以我想使用 Express js 应用程序 现在的问题是 我不希望身份不明的用户访问 Express js 应用程序的日期 因此 我必须在 Expr
  • 如何在Redis中只保存一个数据库?

    我是 Redis 新手 有一个与备份相关的问题 目前 我有一个实例在 Windows 服务器上运行 在这个实例中 我当前有一项 工作 将数据存储在一个数据库中 我不想备份这些数据 我必须创造一份新工作 我的第一个想法是将数据存储在另一个数据
  • Redis 队列工作程序在 utcparse 中崩溃

    我正在尝试按照以下教程获得基本的 rq 工作 https blog miguelgrinberg com post the flask mega tutorial part xxii background jobs https blog m
  • 如何使用redis发布/订阅

    目前我正在使用node js和redis来构建应用程序 我使用redis的原因是因为发布 订阅功能 该应用程序只是在用户进入用户或离开房间时通知经理 function publishMsg channel mssage redisClien
  • 超出 Redis 连接/缓冲区大小限制

    在对我们的应用程序服务器进行压力测试时 我们从 Redis 中得到以下异常 ServiceStack Redis RedisException 无法连接到 redis host 6379 处的 redis 实例 gt System Net

随机推荐

  • 机器学习量化应用:用回归策略预测价格

    我们已经知道 监督学习主要就是分类和回归两种方法 本文以支持向量机 support vector machine SVM 来说明 如何采取机器学习中回归方法来预测股票价格 这在传统量化中是根本不可能实现的 在机器学习领域却能达到50 以上的
  • 【QT专栏】QT中实现多线程的四种方式和线程同步

    目录 一 继承QThread 1 基本概念 2 操作流程 二 继承QObject 推荐 1 基本概念 2 操作流程 三 继承QRunnable 配合QThreadPool实现多线程 1 外界通信 2 QMetaObject invokeMe
  • ARM NOEN vfmaq_laneq_f32与vextq_f32指令例子

    vfmaq laneq f32是乘法运算相关指令 vextq f32是取数据相关指令 具体功能用文字描述比较麻烦 直接看个列子一下就懂了 所以在这里记录下来 float32x4 t sum vdupq n f32 0 sum 0 0 0 0
  • element的table组件二次封装,实现动态表头

    封装element的table组件 让其实现动态表头 由于后端传递过来的数据是表头跟数据分开的 而element的table组件是固定死表头的 跟ant design不一样 这怎么搞 只能自己二次封装了 封装思路 1 参照ant desig
  • p5.js炫酷背景动态js特效代码

    下载地址 p5 js炫酷背景动态特效代码 dd
  • 生产管理系统MES详细功能介绍

    MES通过集成各种功能模块 实现了生产过程的全面监控 优化和管理 MES系统在生产过程中被广泛应用 彻底改变了传统的生产方式 MES系统主要有哪些功能模块呢 小编将为大家详细介绍 实时数据采集与监控 MES系统通过连接各种传感器和设备 实时
  • C++开发环境搭建_Visual Studio

    环境搭建步骤 l 下载软件 l 安装软件 l 运行软件 1 下载软件 在百度搜索 visual studio 选择 如下图中的选项 进入Visual Studio 官网后 选择 下载Windows版 并选择Community 2017 社区
  • javafx集成Sqlite工具类,包含增删改查范例

    javafx集成Sqlite工具类 包含增删改查范例 技术分享交流 qq群 835259695 package com hq utils import com hq database entity CollectionBox import
  • 算法练习:707 设计链表(2022-09-23)

    707 设计链表 来源 力扣 LeetCode 链接 https leetcode cn problems design linked list 设计链表的实现 您可以选择使用单链表或双链表 单链表中的节点应该具有两个属性 val和next
  • SmartImageView的简单使用

    SmartImageView主要是为了加速从网上加载图片 支持根据URL地址加载图片 支持异步加载图片 支持图片缓存等 下载地址 http loopj com android smart image view 下载完成后拷贝到项目下的lib
  • nginx反向代理解决vue打包后运行产生的跨域问题

    代理简介 正向代理 客户端明确服务端地址 服务端接收请求时只清楚来自哪个代理服务 反向代理 隐藏服务端信息 访问者并不知道自己访问的时一个地址 反向实现 1 下载nginx 2 修改nginx conf文件 server server 监听
  • 解析excel的坑

    1 解析excel的时候因调用的方法不同导致解析excel的时候数据有时会少一行 hssfSheet getLastRowNum 最后一行行标 比行数小1 hssfSheet getRow k getLastCellNum 获取列数 比最后
  • C++音视频开发从放弃到入门(基于FFmpeg+OpenCV)

    前言 音视频开发一定要学C 吗 答案是肯定的 虽然其它语言也能搞音视频开发 甚至使用起来更简单 但 语言越高级 离真相就越远 当你的功能需求日益增多 程序的性能需求越来越迫切 你想进一步了解程序实现的细节时 使用其它语言往往会面临 无法解决
  • Pinely Round 2 (Div. 1 + Div. 2) A~D

    A Channel 题意 有n个订阅者 a个初始在线人数 q个上下线情况 问是否一定或有可能所有订阅者都阅读了新的帖子 思路 同时在线人数等于n时 一定都阅读了 输出YES 初始在线人数加上所有的上线人数 所有的 号 大于等于n的话输出MA
  • STL- 常用算法(拷贝和替换,算术生成,集合算法)

    目录 1 常用拷贝和替换算法 1 1copy 容器内指定范围的元素拷贝到另一容器中 1 2replace 将容器内指定范围的旧元素修改为新元素 1 3 replace if 将区间内满足条件的元素 替换成指定元素 1 4 swap 互换两个
  • Docker安装redis集群

    文章目录 1 Redis集群介绍 2 Redis 集群的数据分片 3 Redis 集群的主从复制模型 4 docker搭建Redis集群 3主3从 5 主从容错切换迁移案例 6 主从扩容案例 7 主从缩容案例 1 Redis集群介绍 Red
  • 时序预测

    时序预测 MATLAB实现PSO GRU 粒子群优化门控循环单元 时间序列预测 目录 时序预测 MATLAB实现PSO GRU 粒子群优化门控循环单元 时间序列预测 预测效果 基本介绍 模型介绍 PSO模型 GRU模型 PSO GRU模型
  • C++中的静态和动态多态

    之前学过继承 子类继承父类的属性 多态就是基于继承而来的 我们在如果只用继承 那么子类继承父类的各种属性在编译环节 就已经被确认了 导致代码不灵活 如果继承下来的某个子类不支持某种问题的解决 那么父类就需要重新编写代码 这样这个子类ok了
  • (四)为深度伪造预处理数据集

    目录 在Notebook上设置基础 提取视频帧 人脸检测和提取 下载项目文件 75 5 MB 深度伪造 使用深度学习在视频中将一个人的脸换成另一个人的脸 是当今使用人工智能的最有趣和最可怕的方式之一 虽然深度伪造可用于合法目的 但它们也可用
  • Redis新数据类型

    Bitmaps 1 简介 现代计算机用二进制 位 作为信息的基础单位 1个字节等于8位 例如 abc 字符串是由3个字节组成 但实际在计算机存储时将其用二进制表示 abc 分别对应的ASCII码分别是97 98 99 对应的二进制分别是01