Bitmaps-创新互联

1. 简介

10多年的渝中网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都全网营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整渝中建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联建站从事“渝中网站设计”,“渝中网站推广”以来,每个客户项目都认真落实执行。

现在计算机用二进制(位)作为信息的基础单位,1个字节等于8位,例如 "abc" 字符串是由3个字节组成,单实际在计算机存储时将其用二进制表示, "abc" 分别对应的 ASCII 码分别是97、98、99,对应的二进制分别是01100001、01100010和01100011,如下

a >>>>01100001

b >>>>01100010 >>>>abc >>>>011000010110001001100011

c >>>>01100011

合理地使用操作位能够有效的提高内存使用率和开发效率。

Redis 提供了 Bitmaps 这个“数据类型”可以实现对位的操作:

  (1) Bitmaps 本身不是一种数据类型,实际上它就是字符串(key-value),但是它可以对字符串的位进行操作。

  (2) Bitmaps 单独提供了一套命令,所以在 Redis 中使用 Bitmaps 和使用字符串的方法不太相同。可以吧 Bitmaps 想象成一个以位为单位的数组,数组的每个单元智能存储0和1,数组的下标在 Bitmaps 中叫做偏移量。

key >>>>value 011000010110001001100011

2. 命令

setbit

(1)格式

setbit设置 Bitmaps 中某个偏移量的值(0或1)

127.0.0.1:6379>setbit

* offset :偏移量从0开始

(2)实例

  每个独立用户是否访问过网站存放在 Bitmaps 中,将访问的用户记做1,没有访问的用户自作0,用偏移量记做用户的 id 。

  设置键的第 offset 个位的值(从0算起),假设现在有20个用户, userid =1,6,11,15,19的用户对网站进行了访问,那么当前 Bitmaps 初始化结果如图

1234567891011121314151617181920
012345678910111213141516171819
01000010000100010001

unique:users:20201106 代表2020-11-06这天的独立访问用户的 Bitmaps

127.0.0.1:6379>setbit unique:users:20201106 1 1
(integer) 0
127.0.0.1:6379>setbit unique:users:20201106 6 1
(integer) 0
127.0.0.1:6379>setbit unique:users:20201106 11 1
(integer) 0
127.0.0.1:6379>setbit unique:users:20201106 15 1
(integer) 0 
127.0.0.1:6379>setbit unique:users:20201106 19 1
(integer) 0

注:

  很多应用的用户 id 以一个指定数字(例如10000)开头,直接将用户 id 和 Bitmaps 的偏移量对应势必会造成一定的浪费,通常的做法是每次做 setbit 操作时将用户 id 减去这个指定数字。

  在第一次初始化 Bitmaps 时,假如偏移量非常大,那么整个初始化过程执行会比较慢,可能会造成 Redis 的阻塞。

getbit

(1)格式

getbit获取 Bitmaps 中某个偏移量的值

127.0.0.1:6379>getbit

获取键的第 offset 位的值(从0开始算)

(2)实例

获取 id =8的用户是否在2020-11-06这天访问过,返回0说明没访问过:

127.0.0.1:6379>getbit unique:users:20201106 8
(integer) 0
127.0.0.1:6379>getbit unique:users:20201106 1
(integer) 1
127.0.0.1:6379>getbit unique:users:20201106 100
(integer) 0

注:因为100根本不存在,所以也是返回0

bitcount

统计字符串被设置为1的 bit 数。一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。 start 和 end 参数的设置,都可以使用负数值:比如-1表示最后一个位,而-2表示倒数第二个位, start 、 end 是指 bit 组的字节的下标数,二者皆包含。

(1)格式

bitcount[start end] 统计字符串从 start 字节到 end 字节比特值为1的数量

127.0.0.1:6379>bitcount

(2)实例

计算2020-11-06这天的独立访问用户数量

127.0.0.1:6379>bitcount unique:users:20201106
(integer) 5

start 和 end 代表起始和结束字节数,下面操作计算用户 id 在第1个字节到第3个字节之间的独立访问用户数量,对应的用户 id 是11,15,19。

127.0.0.1:6379>bitcount unique:users:20201106 1 3
(integer) 3

举例:K1【01000001 01000000 00000000 00100001】,对应【0,1,2,3】

bitcount K1 1 2  :统计下标1、2字节组中 bit =1的个数,即01000000 00000000 >>>>1

bitcount K1 1 3  :统计下标1、3字节组中 bit =1的个数,即01000000 00100001 >>>>3

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

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

bitop

(1)格式

bitop and (or/not/xor)[key...]

127.0.0.1:6379>bittop

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

(2)实例

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

127.0.0.1:6379>bitop and unique:users:and:20201104_03 unique:users:20201103 unique:users:20201104
(integer) 2
127.0.0.1:6379>bitcount unique:users:and:20201104_03

unique:users:202011040110010001
0123456789

                             ↓

unique:users:202011031100100001
0123456789

  ↓

unique:users:20201104_030100000001
0123456789

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

127.0.0.1:6379>bitop or unique:users:or:20201104_03 unique:users:20201103 unique:users:20201104
(integer) 2
127.0.0.1:6379>bitcount unique:users:or:20201104_03
(integer) 6

3. Bitmaps 与 set 对比

  假设网站有1亿用户,每天独立访问的用户有5千万,如果每天用集合类型和 Bitmaps 分别存储活跃用户可以得到表

set 和 Bitmaps 存储一天活跃用户对比
数据类型每个用户 id 占用空间需要存储的用户量全部内存量
集合类型64位5000000064位*50000000=400MB
Bitmaps1位1000000001位*100000000=12.5MB

  很明显,这种情况下使用 Bitmaps 能节省很多的内存空间,尤其是随着时间推移节省的内存还是非常可观的

set 和 Bitmaps 存储一天活跃用户对比
数据类型一天一个月一年
集合类型400MB12GB144GB
Bitmaps12.5MB375MB4.5GB

  但 Bitmaps 并不是万金油,假如该网站每天的嘟噜访问用户很少,例如只有10万(大量的僵尸用户),那么两者的对比如下表所示,很显然,这时候使用 Bitmaps 就不太合适了,因为基本上大部分位都是0

set 和 Bitmaps 存储一天活跃用户对比(独立用户比较少)
数据类型每个用户 id 占用空间需要存储的用户量全部内存量
集合类型64位10000064位*100000=800KB
Bitmaps1位1000000001位*100000000=12.5MB

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


标题名称:Bitmaps-创新互联
当前链接:http://myzitong.com/article/dspsjg.html