bitset存储用户和歌曲的购买关系

问题的背景

1亿个用户,1000万首歌,当用户第一次购买了这首歌,后续就可以永久免费了,如何记录这个用户和歌的对应关系。方案是很多的,可以记录数据库,放到redis里面等都是可以的,但是随着用户和歌曲关系的增加,数据库或是redis是抗不住的,理论上用户和歌曲的关系有1亿*1000万中关系,要记录所有的关系,数据库或是redis都是不能满足的。

下面我提出基于bitset的实现方案,欢迎大家探讨更优的方案,bitset的原理可以参考https://my.oschina.net/cloudcoder/blog/294810,也可以自己google。


第一种场景(bitset不稀疏):

适用与版权出售商,这种场景下用户数不会太多,因为这些用户都是版权购买商,比如百度音乐,QQ音乐等,但是版权出售商需要记录哪些音乐的版权被买了,这种场景下可以用bitset精确记录这种对应关系。由于每个版权购买商购买的音乐数量很多,因此bitset不会稀疏,内存浪费不多,不要压缩。假设歌曲的ID为整数递增,实现方案就是把歌曲的主键id映射到bitset的某位上,1M=8 *1024*1024bit = 8388608 bit, 1M的内存可以表示830个数字。1000万歌曲大概消耗内存1.2M左右。在redis中可以用bitmap 实现,key会用户ID,每位代表歌曲的id, 具体参考http://blog.csdn.net/hguisu/article/details/9191389


第二种场景(bitset 稀疏):

如果用户数目很多很大,购买的歌曲又很少,比如上面的场景1亿用户,如果用bitset,一个用户要记录与所有歌曲的对应关系需要1.2M, 那表示所有对应关系理论上需要1.2亿M,这个是多大的内存(我脑子算不过来了)。这种场景下一个用户对应的歌曲很少,bitset很稀疏(bitset里面为1的个数很少,用过用RLE压缩算法,所需要的内存也是非常非常大的),使用bitset不仅不能节约内存,还比redis直接用list或set存储用户歌曲关系还要耗内存。下面提出一种对bitset的改进方法,使用bloomfilter来存储。将用户id和歌曲id连个拼接起来,作为一个唯一表示,然后放入bloomfilter里面。理论上用多少个用户,bloomfilter里面就有多少个元素,这样可以达到降低内存使用率。但是bloomfilter减低内存使用率是牺牲了正确性的,会出现误报(会出现没有购买的用户计算为购买),hash算法选取的好,已经bitset位很大,误报率会很低很低。

下面附上测试数据,具体参考http://www.cnblogs.com/wxisme/p/5742456.html

bitmap的实现参考:http://blog.csdn.net/hguisu/article/details/9191389

bloomfilter参考:http://www.cnblogs.com/wxisme/p/5742456.html

cfilter参考:https://github.com/irfansharif/cfilter



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值