记一次服务端大数据处理过程

业务背景

用户留存分析

如图所示为用户留存分析功能前端

需求分析

该柱状图展现的为用户留存百分比.redis

以按周展现为例算法

U:活跃用户数 x:第几周 y:活跃占比数据库

公式

需求整理:数组

  1. 按日,按周,按月 三种固定日期的对比
  2. 日期选择 随机日期的对比

对于这种数据后台的功能,做为服务端开发,咱们会尽可能要求数据库将结果统计好,由咱们服务端直接取结果作展现.数据结构

可是因为有随机日期的对比,假设由数据组来进行统计,意味着须要对天天都作对比统计(统计结果数据量大,耗费性能),并不现实.性能

因此最终仍是决定由服务端来作实时统计.大数据

实时统计,主要考虑前端的响应速度.优化

方案1: 以天维度存放用户登陆信息

采用bitmap按天纬度来存放用户登陆数据..net

实现过程:

  1. 估算总用户量为4亿,使用bitmap存储大概须要50M大小
  2. 给用户排序,简单实现:存表取id自增 (暂不考虑存表效率)
  3. 天天的登陆用户生成一条bitmap
  4. 当计算y(x(i))时,只需提取x(1)与x(i)的bitmap作and操做,再统计结果为1的个数,再除以x(i)的bitmap中为1的个数

方案2: 以用户维度存放用户登录时间信息

采用bitmap按用户纬度存放登陆时间信息(哪几天登陆)

  1. 记当天为标准第0天

  2. 对每一个登陆用户,将对每一个登陆用户,将当前天数对应的位置为1

  3. 当计算y(x(i))时

    用户 描述 bitmap
    a 第-4,-3,-1,0天登陆 [1,1,0,1,1]
    b 第-3,-2,0天登陆 [1,1,0,1]
    B(-3,0) 第-3,0天登陆 [1,0,0,1]
    B(0) 第0天登陆 [1]
    1. 遍历a,b与B(1,4)作and操做,统计结果==B(1,4)的个数,即1,4天都登陆用户个数
    2. 再如法炮制获得第4天登陆用户个数,相除即获得结果
优势 缺点
方案一 查询快,只须要作一次and操做 空间占用太大,天天都要以最大用户量生成一条bitmap
方案二 节省空间,空间占用随用户量增加,每一个用户的bitmap随登录状况变化 查询略慢,须要遍历全部用户作and操做

简单归纳: 方案一费空间,方案二查询慢

实际开发过程当中,因为咱们采用redis进行存储.

采用方案一的话内存过于浪费.而采用方案二,以个人macpro-i5配置只能负载20w/s的and操做,响应速度方面难以接受.

综合上述方式一二都不能知足要求,只能看是否还有优化空间.

通过同事提醒,针对方式一采用一种空间压缩算法,解决了方案一空间浪费的缺陷.

方案3: 使用RoaringBitmap以天维度存放用户登陆信息

RoaringBitmap介绍看这

简单归纳:

  1. 假设数据量为不超过2^32.

  2. 将数据拆分为高16位,低16位

  3. 对高位进行聚合(以高位作key,value为有相同高位的全部低位数组)

  4. 根据低位的数据量(不一样高位聚合出的低位数组长度不相同),使用不一样的container(数据结构)存储

    1. len<4K ArrayContainer 直接存值

    2. len>=4K BitmapContainer 使用bitmap存储

      4K的取值缘由:value的最大总数是为2^16=65536. 假设以bitmap方式存储须要65536bit=8kb,而直接存值的方式,一个值16,4K个总共须要2byte*4K=8kb.因此当value总量<4k时,使用直接存值的方式更节省空间

    3. RunContainer 压缩存储

      RunContainer中的Run指的是行程长度压缩算法(Run Length Encoding),对连续数据有比较好的压缩效果.对于数列11,12,13,14,15,21,22 它会压缩为11,4,21,1

      1. 最优,value数组彻底连续,那么只会存储2个short,占用4kb
      2. 最差,value数组彻底不连续(全奇/全偶),那么会存储须要存储65536个short,128kb.

内存占用

  1. 空间压缩主要体如今:

    1. 高位聚合(假设数据中有100w个高位相同的值,原先须要100w*2byte,如今只要1*2byte)
    2. 低位压缩(ArrayContainer省空间,BitmapContainer不省,RunContainer可能省)
  2. 对数据的位操做速度有影响(3种container相互and.乐观状况两个BitmapContainer作and切BitCount()>4096,则数据无影响)

综上: 使用RoaringBitmap的优缺点

  1. 节约空间(最优数据集高位都相同,最差数据集高位都不一样)
  2. 位操做速度对原生bitmap有所降低

方案3能够说是平衡了方案一二,是本次的最优选择

相关文章
相关标签/搜索