巧用redis位图存储亿级数据与访问 - 简书
业务背景
现有一个业务需求,需要从一批很大的用户活跃数据(2亿+)中判断用户是否是活跃用户。由于此数据是基于用户的各种行为日志清洗才能得到,数据部门不能提供实时接口,只能提供包含用户及是否活跃的指定格式的文本由业务方使用。
存在的挑战
- 海量数据如何尽可能用小的空间存储
- 如何能快速获取指定的数据
- 如何能快速的写入到目标存储
解决思路
由于我的业务中只需要根据某个用户id查询是否是活跃用户,不存在复杂的查询条件,所以用redis很合适。
如此大的数据如果用普通的键值对一一存储所有用户的活跃数据,即使每个key/value占用的内存很小,但数亿个key/value所花费的内存每个节点随便都需要数G,业务中有很多类似的需求,都用这种方式的话,存储是个很大的问题。
这里使用redis的位图来处理。
redis中所有数据都是二进制形式存储的。redis支持一个setbit和getbit操作,它支持在某个key的value上直接对某个二进制位操作,每个二进制位都只有0和1两种状态,正好可以表示用户是否活跃两种状态。
比如redis中键a的value数据的二进制码是
0110 0110 0001
它总共有12位,在redis的位操作中,二进制中的第几位称为offset。
我们可以这样将这个数据的第10位设置为1:
setbit a 10 1
这样,原来的数据就变成了
0110 0110 0101
如果key不存在,也会自动创建。
当然,如果某个位还不存在,redis也会自动填充。
可以通过getbit获取某个二进制位的值
getbit a 10 //获取键a的值上第10位的值(0或1两种状态)
这是所谓的位图。
那么我们考虑在redis中放一个key,通过这个key直接操作二进制位,redis中单个key的最大值是512M,可以达到40多亿bit,足够很多业务的需要了。我们以用户id作为offset,该offset的值作为是否活跃的值即可达到我们的目的。这样只需要一个key就能解决对所有数据的查询问题。假设我们的id最大值是1亿,那么我们需要一亿个bit就行了,相当于只需要1亿/(810241024)=11.9M内存。这里大家了解下二进制就能理解。
//用户id123456是活跃用户
setbit a 123456 1
//用户id234567不是活跃用户
setbit a 234567 0
getbit a 123456
具体操作:
循环所有id列表,id作为offset,通过setbit写入该id是否活跃。
查询时,调用getbit a 123456即可
这样完美解决了存储和访问的问题!
- 接下来还要解决数据写入问题,这么多数据要怎样快速写入呢?使用redis官方提供的方式,将数据转成redis协议格式,使用redis-cli提供的pipe模式写入。
一个命令的例子:
*4
$6
setbit
$9
is_active
$3
123
$1
1
上面*4表示这个命令总共有四个参数:
$数据表示下面的参数的字节数量,一个参数对应一个$
以换行结尾,注意,换行必须是\r\n,linux中需要转换。
得到redis协议格式的文本后,使用redis-cli执行。
cat data.txt|redis-cli --pipe
巧用redis位图存储亿级数据与访问 - 简书的更多相关文章
- 巧用redis位图存储亿级数据与访问
业务背景 现有一个业务需求,需要从一批很大的用户活跃数据(2亿+)中判断用户是否是活跃用户.由于此数据是基于用户的各种行为日志清洗才能得到,数据部门不能提供实时接口,只能提供包含用户及是否活跃的指定格 ...
- 分布式数据库中间件Mycat百亿级数据存储(转)
此文转自: https://www.jianshu.com/p/9f1347ef75dd 2013年阿里的Cobar在社区使用过程中发现存在一些比较严重的问题,如高并发下的假死,心跳连接的故障,只实现 ...
- 基于Redis位图实现系统用户登录统计
项目需求,试着写了一个简单登录统计,基本功能都实现了,日志数据量小.具体性能没有进行测试~ 记录下开发过程与代码,留着以后改进! 1. 需求 1. 实现记录用户哪天进行了登录,每天只记录是否登录过,重 ...
- Redis位图法记录在线用户的状态
Redis位图法记录在线用户的状态 位图 Redis官方文档对于位图的介绍如下: 位图不是一个真实的数据类型,而是定义在字符串类型上的面向位的操作的集合.由于字符串类型是二进制安全的二进制大对象,并且 ...
- 通用技术 mysql 亿级数据优化
通用技术 mysql 亿级数据优化 一定要正确设计索引 一定要避免SQL语句全表扫描,所以SQL一定要走索引(如:一切的 > < != 等等之类的写法都会导致全表扫描) 一定要避免 lim ...
- Redis位图实现用户签到功能
场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 当月签到满 ...
- 基于Redis位图实现用户签到功能
场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 当月签到满 ...
- 基于Mysql数据库亿级数据下的分库分表方案
移动互联网时代,海量的用户数据每天都在产生,基于用户使用数据的用户行为分析等这样的分析,都需要依靠数据都统计和分析,当数据量小时,问题没有暴露出来,数据库方面的优化显得不太重要,一旦数据量越来越大时, ...
- Mongodb亿级数据量的性能测试
进行了一下Mongodb亿级数据量的性能测试,分别测试如下几个项目: (所有插入都是单线程进行,所有读取都是多线程进行) 1) 普通插入性能 (插入的数据每条大约在1KB左右) 2) 批量插入性能 ...
随机推荐
- nginx+tomcat 架构 HttpServletRequest.getScheme()获取正确的协议
http://blog.csdn.net/ofofw/article/details/46791447
- (转)linux screen 命令详解
转自:http://www.cnblogs.com/mchina/archive/2013/01/30/2880680.html 一.背景 系统管理员经常需要SSH 或者telent 远程登录到Lin ...
- [Angular] Two ways to create Angular Animation, using animation() or using state()
We have two blocks to show to difference ways to do animation in Angular: <button (click)="t ...
- OpenNI2获取华硕XtionProLive深度图和彩色图并用OpenCV显示
使用OpenNI2打开XtionProLive时有个问题,彩色图分辨率不管怎样设置始终是320*240,深度图倒是能够设成640*480,而OpenNI1.x是能够获取640*480的彩色图的. 彩色 ...
- cURL(wget)—— 测试 RESTful 接口及模拟 GET/POST/PUT/DELETE/OPTIONS 请求
cURL 是一个简单的 http 命令行工具.与最优秀的 Unix 工具一样,在设计之时,cURL 是个小型程序,功能十分专一,而且是故意为之,仅用于访问 http 服务器.(在 Linux 中,可以 ...
- MVC中url路由规则
Routing:首先获取视图页面传过来的请求,并接受url路径中的controller和action以及参数数据,根据规则将识别出来的数据传递给某controller中的某个action方法 MapR ...
- smack capable(CAP_MAC_OVERRIDE)
https://blog.csdn.net/ning_wei/article/details/9670947 LINUX中的capable int smk_curacc(char *obj_label ...
- malloc和realloc
malloc函数: extern void *malloc(unsigned int num_bytes); malloc 向系统申请分配指定size个字节的内存空间. 如果分配成功则返回指向被分配内 ...
- Spring配置文件头及xsd文件版本
最初Spring配置文件的头部声明如下: Xml代码 <?xml version="1.0" encoding="UTF-8"?> <!D ...
- MHA 一主两从搭建-keepalived-手动切换
环境介绍:主机名 IP MHA角色 MySQL角色node1 192.168.56.26 Node MySQL Master node2 192.168.56.27 Node MySQL Master ...