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

本文介绍了Redis中的位图数据结构,如何通过位来节省存储空间,以及如何使用SETBIT,GETBIT和BITCOUNT命令进行操作。位图特别适合记录签到、登录等频繁计数场景,具有高效和节省空间的优势。

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

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

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

位数组

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

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

位图应用原理

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

### DCI Bitmap位图的作用 DCI bitmap位图用于指示物理下行共享信道(PDSCH)所占用的资源块组(RBG)[^4]。通过这种方式,基站可以灵活地向用户设备(UE)传达具体的频域资源分配信息。 对于Type0类型的PDSCH资源分配,DCI-RIV字段携带了一个bitmap来表示哪些RBG被分配给了特定的传输。每个bit代表一个RBG的状态:如果该位置上的值为1,则对应的RBG被分配;反之,若为0,则未分配此RBG。 ### 原理 在5G NR标准下,为了适应不同带宽需求和服务质量(QoS),引入了两种主要的PDSCH资源分配模式——Type0和Type1。其中: - **Type0** 是一种非连续性的资源分配方案; - **Type1** 则适用于连续性资源分配场景。 针对Type0而言,其采用了一种基于位图(bitmap)的方法来进行更细粒度的资源配置管理。具体来说,就是利用一系列二进制数(bits),每一个都映射到某个预定义大小的RBGs上,以此决定这些RBGs是否参与当前的数据发送过程。 此外,在计算所需bitmap长度时,会考虑到整个BWP尺寸以及起始位置等因素的影响,确保能够覆盖所有潜在可用的RBGs,并据此调整最终形成的bitmap规模\[N_{RBG}=\lceil\frac{(N_{BWP\_size}\%+\text{mod}(N_{BWP\_start},P))}{P}\rceil\]。 这里\(N_{RBG}\)指的是总的RBG数量,而\(P\)则是由协议规定的单个RBG内含有的虚拟资源块(VRBs)数目。 ### 实现方式 实际应用中,当网络侧准备下发调度指令给终端时,会在Downlink Control Information(DCI)消息里嵌入上述提到过的bitmap数据结构。接收端解析这条命令后就能获知确切应该监听哪个部分的无线频率范围内的信号。 下面给出一段简化版C++伪代码片段展示如何创建并解释这样一个bitmap: ```cpp // 计算所需的bitmap长度 int calculateBitmapLength(int bwpSize, int bwpStart, int rbgSize){ return ceil((bwpSize + fmod(bwpStart,rbgSize))/(float)rbgSize); } void generateAndParseBitmap(std::vector<bool>& bitmap, const std::string& dciPayload){ // 解析来自高层传来的dci payload获得bitmap... // 示例模拟填充bitmap逻辑 for(size_t i = 0 ;i<calculateBitmapLength(/* 参数 */); ++i){ bool isAllocated = /* ... */; bitmap.push_back(isAllocated); } } ``` 这段代码展示了基本框架,但在真实环境中还需要考虑更多细节如错误检测机制等。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值