redis位图巧用,节约内存
最近要做一个圣诞抽奖活动,需要记录每天用户签到的记录,以前一般都是用普通的字符串数据类型,每个用户的签到用一个 key
// 用户10在活动第一天的签到key为record:1:10
$key = "record:$day:$id";
if ($redis->get($key)) {
echo '已签到';
} else {
$redis->set($key, 1)
}
那么一个用户一天的签到记录就要占一个字节,用户一多就产生非常多的 key,浪费宝贵的内存。
位图
为了解决这个问题,redis 另一种数据类型位图就非常适合。位图并不是特殊的数据类型,内容其实就是字符串,每一位只存储0或1,非常适合存储这种布尔类型的数据
位图使用 setbit/getbit 来存取数据
> SETBIT key offset value
> GETBIT key offset
比如一个用户圣诞连续五天的签到记录可以只使用一个 key, 10010 代表用户只有第二天和第五天签过到
$key = "record:$id";
if ($redis->getbit($key, $day)) {
echo '已签到';
} else {
$redis->setbit($key, $day, 1)
}
现在一个用户五天的签到记录只会产生一个 key,占用内存仅为 5bit 不到一个字节
进一步,如果你的用户系统中用户 id 是连续的 int 类型,还能更节省。因为只记录每个用户5天的签到记录,在一串位图中,每个用户占5个坑,这样所有的用户的签到数据只会使用一个 key
// 用户1占前5个坑
$offset = ($id - 1) * 5 + $day -1;
if ($redis->getbit('record', $offset)) {
echo '已签到';
} else {
$redis->setbit('record', $offset, 1)
}
现在只需要一个 key 就可以存下所有用户的签到记录了。
需要注意的是位图一个 key 最多存储 512mb 的内容,如果你的用户数大于 8*1024*1024*1024*512 / 5 ≈ 87 亿 并不适用这个方法。
其他用法
bitcount 用来统计指定位置范围内 1 的个数,bitpos 用来查找指定范围内出现的第一个 0 或 1。
> setbit s 0 1
> setbit s 3 1 #s=1001
> bitcount s [start, end]
(integer) 2
> bitpos s 0 [start, end]
(integer) 1
redis位图巧用,节约内存的更多相关文章
- Redis实战(18)Redis位图巧用,节约内存
序言 资料 https://www.cnblogs.com/luke44/p/12031078.html
- 节约内存:Instagram的Redis实践(转)
一.问题: 数据库表数据量极大(千万条),要求让服务器更加快速地响应用户的需求. 二.解决方案: 1.通过高速服务器Cache缓存数据库数据 2.内存数据库 三.主流解Ca ...
- 巧用redis位图存储亿级数据与访问 - 简书
原文:巧用redis位图存储亿级数据与访问 - 简书 业务背景 现有一个业务需求,需要从一批很大的用户活跃数据(2亿+)中判断用户是否是活跃用户.由于此数据是基于用户的各种行为日志清洗才能得到,数据部 ...
- 节约内存:Instagram的Redis实践(转)
Instagram可以说是网拍App的始祖级应用,也是当前最火热的拍照App之一,Instagram的照片数量已经达到3亿,而在Instagram里,我们需要知道每一张照片的作者是谁,下面就是Inst ...
- 节约内存:Instagram的Redis实践
Instagram可以说是网拍App的始祖级应用,也是当前最火热的拍照App之一,Instagram的照片数量已经达到3亿,而在Instagram里,我们需要知道每一张照片的作者是谁,下面就是Inst ...
- Redis位图实现用户签到功能
场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 当月签到满 ...
- 基于Redis位图实现用户签到功能
场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 当月签到满 ...
- Redis位图法记录在线用户的状态
Redis位图法记录在线用户的状态 位图 Redis官方文档对于位图的介绍如下: 位图不是一个真实的数据类型,而是定义在字符串类型上的面向位的操作的集合.由于字符串类型是二进制安全的二进制大对象,并且 ...
- Redis(八)理解内存
Redis所有的数据都存在内存中,当前内存虽然越来越便宜,但跟廉价的硬盘相比成本还是比较昂贵,因此如何高效利用Redis内存变得非常重要. 高效利用Redis内存首先需要理解Redis内存消耗在哪里, ...
随机推荐
- 基于 ThinkPHP5 + Bootstrap 的后台开发框架 FastAdmin
FastAdmin是一款基于 ThinkPHP5 + Bootstrap 的极速后台开发框架. 主要特性 基于Auth验证的权限管理系统 支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及 ...
- jquery微信浏览器阻止页面拖动
jquery微信浏览器阻止页面拖动<pre>function bodyScroll(event) { event.preventDefault();} document.body.addE ...
- Python文件打包exe教程——Pyinstaller(亲测有效)
今天将要解决一个问题,如何打包Pyhon文件 众所周知,Python文件的后缀名为“.py” 所以执行Python文件的要求之一便是具有python环境. 偶尔特殊情况,或者运行一些比较简单的工具,但 ...
- show语句大全
基于本人对MySQL的使用,现将常用的MySQL show 语句列举如下: 1.show databases ; // 显示mysql中所有数据库的名称 2.show tables [from dat ...
- Redis持久化的几种方式——深入解析RDB
Redis 的读写都是在内存中,所以它的性能较高,但在内存中的数据会随着服务器的重启而丢失,为了保证数据不丢失,我们需要将内存中的数据存储到磁盘,以便 Redis 重启时能够从磁盘中恢复原有的数据,而 ...
- [ASP.NET Core 3框架揭秘] 文件系统[1]:抽象的“文件系统”
ASP.NET Core应用 具有很多读取文件的场景,比如配置文件.静态Web资源文件(比如CSS.JavaScript和图片文件等)以及MVC应用的View文件,甚至是直接编译到程序集中的内嵌资源文 ...
- windows 10安装和配置caffe教程 | Install and Configure Caffe on windows 10
本文首发于个人博客https://kezunlin.me/post/1739694c/,欢迎阅读! Install and Configure Caffe on windows 10 Part 1: ...
- [ML机器学习 - Stanford University] - Week1 - 01 Introduction
What is Machine Learning? Two definitions of Machine Learning are offered. Arthur Samuel described i ...
- drf组件之jwt认证
drf组件之jwt认证模块 一.认证规则 全称:json web token 解释:加密字符串的原始数据是json,后台产生,通过web传输给前台存储 格式:三段式 - 头.载荷.签名 - 头和载荷才 ...
- NN入门,手把手教你用Numpy手撕NN(三)
NN入门,手把手教你用Numpy手撕NN(3) 这是一篇包含极少数学的CNN入门文章 上篇文章中简单介绍了NN的反向传播,并利用反向传播实现了一个简单的NN,在这篇文章中将介绍一下CNN. CNN C ...