Redis教程——Redis bitmap位图操作(图解)

这篇具有很好参考价值的文章主要介绍了Redis教程——Redis bitmap位图操作(图解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在平时开发过程中,经常会有一些 bool 类型数据需要存取。比如记录用户一年内签到的次数,签了是 1,没签是 0。如果使用 key-value 来存储,那么每个用户都要记录 365 次,当用户成百上亿时,需要的存储空间将非常巨大。为了解决这个问题,Redis 提供了位图结构。

位图(bitmap)同样属于 string 数据类型。Redis 中一个字符串类型的值最多能存储 512 MB 的内容,每个字符串由多个字节组成,每个字节又由 8 个 Bit 位组成。位图结构正是使用“位”来实现存储的,它通过将比特位设置为 0 或 1来达到数据存取的目的,这大大增加了 value 存储数量,它存储上限为2^32

位图本质上就是一个普通的字节串,也就是 bytes 数组。您可以使用getbit/setbit命令来处理这个位数组,位图的结构如下所示:

Redis教程——Redis bitmap位图操作(图解),redis,java,数据库

位图适用于一些特定的应用场景,比如用户签到次数、或者登录次数等。上图是表示一位用户 10 天内来网站的签到次数,1 代表签到,0 代表未签到,这样可以很轻松地统计出用户的活跃程度。相比于直接使用字符串而言,位图中的每一条记录仅占用一个 bit 位,从而大大降低了内存空间使用率。

Redis 官方也做了一个实验,他们模拟了一个拥有 1 亿 2 千 8 百万用户的系统,然后使用 Redis 的位图来统计“日均用户数量”,最终所用时间的约为 50ms,且仅仅占用  16 MB内存。

位图应用原理

某网站要统计一个用户一年的签到记录,若用 sring 类型存储,则需要 365 个键值对。若使用位图存储,用户签到就存 1,否则存 0。最后会生成 11010101... 这样的存储结果,其中每天的记录只占一位,一年就是 365 位,约为 46 个字节。如果只想统计用户签到的天数,那么统计 1 的个数即可。

位图操作的优势,相比于字符串而言,它不仅效率高,而且还非常的节省空间。

Redis  的位数组是自动扩展的,如果设置了某个偏移位置超出了现有的内容范围,位数组就会自动扩充。

下面设置一个名为 a 的 key,我们对这个 key 进行位图操作,使得 a 的对应的 value 变为“he”。

首先我们分别获取字符“h”和字符“e”的八位二进制码,如下所示:

>>> bin(ord("h"))
'0b1101000'
>>> bin(ord("e"))
'0b1100101'

接下来,只要对需值为 1 的位进行操作即可。如下图所示:

Redis教程——Redis bitmap位图操作(图解),redis,java,数据库

把 h 和 e 的二进制码连接在一起,第一位的下标是 0,依次递增至 15,然后将数字为 1 的位置标记出来,得到 1/2/4/9/10/13/15,我们把这组数字称为位的“偏置数”,最后按照上述偏置数对字符 a 进行如下位图操作。注意,key 的初始二进制位全部为 0。

C:\Users\Administrator>redis-cli
127.0.0.1:6379> SETBIT a 1 1
(integer) 0
127.0.0.1:6379> SETBIT a 2 1
(integer) 0
127.0.0.1:6379> SETBIT a 4 1
(integer) 0
127.0.0.1:6379> get hello
"h"
127.0.0.1:6379> SETBIT a 9 1
(integer) 0
127.0.0.1:6379> SETBIT a 10 1
(integer) 0
127.0.0.1:6379> SETBIT a 13 1
(integer) 0
127.0.0.1:6379> SETBIT a 15 1
(integer) 0
127.0.0.1:6379> get hello
"he"

从上述示例可以得出,位图操作会自动对 key 进行扩容。

如果对应位的字节是不可以被打印的,那么 Redis 会以该字符的十六进制数来表示它,如下所示:

127.0.0.1:6379> SETBIT b 0 1
(integer) 0
127.0.0.1:6379> SETBIT b 1 1
(integer) 0
127.0.0.1:6379> get b
"\xc0"

位图常用命令

1) SETBIT命令

用来设置或者清除某一位上的值,其返回值是原来位上存储的值。key 在初始状态下所有的位都为 0 ,语法格式如下:

SETBIT key offset value

其中 offset 表示偏移量,从 0 开始。示例如下:

127.0.0.1:6379> SET user:1 a
OK
#设置偏移量为0
127.0.0.1:6379> SETBIT user:1 0 1
(integer) 0
#当对应位的字符是不可打印字符,redis会以16进制形式显示
127.0.0.1:6379> GET user:1
"\xe1"
2) GETBIT命令

用来获取某一位上的值。示例如下:

127.0.0.1:6379> GETBIT user:1 0
(integer) 1

当偏移量 offset 比字符串的长度大,或者当 key 不存在时,返回 0。

redis> EXISTS bits
(integer) 0
redis> GETBIT bits 100000
(integer) 0
3) BITCOUNT命令

统计指定位区间上,值为 1 的个数。语法格式如下:

BITCOUNT key [start end]

示例如下:

127.0.0.1:6379> BITCOUNT user:1
(integer) 8

通过指定的 start 和 end 参数,可以让计数只在特定的字节上进行。start 和 end 参数和 GETRANGE 命令的参数类似,都可以使用负数,比如 -1 表示倒数第一个位, -2 表示倒数第二个位。

黑马程序员Redis入门到实战教程,深度透析redis底层原理+redis分布式锁+企业解决方案+黑马点评实战项目文章来源地址https://www.toymoban.com/news/detail-809925.html

到了这里,关于Redis教程——Redis bitmap位图操作(图解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springboot+redis+mysql+quartz-通过Java操作jedis定时使用lua脚本获取缓存数据并更新数据库

    springboot+redis+mysql+quartz-通过Java操作jedis定时使用lua脚本获取缓存数据并更新数据库 代码讲解:7.1点赞功能-定时持久化到数据库-Java整合lua_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1ZX4y1H7JT/ 代码: blogLike_schedule/like07 · xin麒/XinQiUtilsOrDemo - 码云 - 开源中国 (gitee.com) https://gitee

    2024年02月13日
    浏览(55)
  • Redis的BitMap使用

    Redis 为我们提供了位图这一数据结构,每个用户每天的登录记录只占据一位,365天就是365位,仅仅需要46字节就可存储,极大地节约了存储空间。 位图不是实际的数据类型,而是一组面向位的操作 在被视为位向量的字符串类型上定义。 由于字符串是二进制安全 blob,其最大长

    2024年02月07日
    浏览(42)
  • redis之Bitmap

    位图数据结构其实并不是一个全新的玩意,我们可以简单的认为就是个数组,只是里面的内容只能为0或1而已(二进制位数组)。 GETBIT 用于返回位数组在偏移量上的二进制位的值。 值得我们注意的是, GETBIT 的时间复杂度是 O(1) 。 GETBIT 命令的执行过程如下: 计算 (即 3 ),by

    2024年02月15日
    浏览(32)
  • Redis - Bitmap

    操作String数据类型的key所存储的字符串指定偏移量上的位,返回原位置的值 优点: 节省空间通过一个bit位来表示某个元素对应的值或者状态,其中key就是对应元素的值。实际上8个bit可以组成一个Byte,所以是及其节省空间的 效率高setbit 和 getbit的时间复杂度都是O(1),其他位运

    2024年02月15日
    浏览(52)
  • Redis之bitmap类型解读

    目录 基本介绍 基本命令  Setbit  Getbit  BITCOUNT  应用场景 统计当日活跃用户 用户签到 bitmap - Redis布隆过滤器 (应对缓存穿透问题) 基本介绍 Redis 的位图(bitmap)是由多个二进制位组成的数组,只有两种状态,0和1, 数组中的每个二进制位都有与之对应的偏移量(从 0 开始)

    2024年02月11日
    浏览(36)
  • Redis高级数据结构之Bitmaps

    现代计算机使用二进制位作为信息存储的基本单元。一个字节(Byte)等于8个二进制位(bit)。合理的使用位能有效提高内存使用率和开发效率。 位是最小信息单位,可以表示两个状态之一。 字节是更大的单位,用多个位组成,在计算机中数据以字节为单位进行存储和访问。

    2024年02月07日
    浏览(37)
  • 轻松打卡:使用Spring Boot和Redis Bitmap构建高效签到系统【redis实战 四】

    欢迎来到我的博客,代码的世界里,每一行都是一个故事 Redis List:打造高效消息队列的秘密武器【redis实战 一】 Redis Streams在Spring Boot中的应用:构建可靠的消息队列解决方案【redis实战 二】 Spring Boot和Redis Geo实现附近的人【redis实战 三】 在数字化时代,签到系统已成为许多

    2024年01月23日
    浏览(42)
  • Redis的3大特殊数据类型(1)-BitMap

    BitMap(位图/位数组) 是Redis2.2.0版本中引入的一种新数据类型,该数据类型本质是一个 仅含0和1 的二进制字符串。因此可以把 Bitmap 想象成一个 以位为单位的数组 ,数组的每个单元 只能存储 0 和 1 ,数组的下标在 Bitmap 中叫做偏移量 offset,bitmap默认值都为0. BitMap底层实际上使

    2024年02月11日
    浏览(45)
  • redis及mongoDB数据库操作

    Redis作业 1、string类型数据的命令操作: (1) 设置键值: SET key value 例如: SET name \\\"John\\\" (2) 读取键值: GET key 例如: GET name (3) 数值类型自增1: INCR key 例如: INCR count (4) 数值类型自减1: DECR key 例如: DECR count (5) 查看值的长度: STRLEN key 例如: STRLEN name 2、lis

    2024年02月16日
    浏览(40)
  • Python 操作 Redis 数据库介绍

    Redis 作为常用的 NoSql 数据库,主要用于缓存数据,提高数据读取效率,那在 Python 中应该如果连接和操作 Redis 呢?今天就为大概简单介绍下,在 Python 中操作 Redis 常用命令。 首先还是需要先安装 redis 模块,使用如下命令: 安装成功后就可以在代码中导入模块,然后通过创建

    2024年02月11日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包