现象,一张图片,我没有赞过,而且点赞列表也没有,但是却显示我已经赞过了
1.老版点赞逻辑
(1) date_picId_snsId 拼接字符串
(2) md5该字符串得到16进制字符串,切害字符串,5个字符一组,得到数组
(3) 循环该数组
将字符串转换为10进制,得到一个偏移量offset
(4)在循环里面setbit 操作
key: date_i
offset: offset
2.分析,MD5的碰撞概率没这么高,每个切割完的16进制字符串,只能转换成一个对应的offset
只能是,切割完数组之后数组有重复
举例说明
pic1加密之后得到这个结果,验证. ASD3 EF2B DC
pic2得到结果. ASD3 CE86 FE
pic3得到结果. DE87 EF2B C3
pic4得到结果. CEF3 2D32 DC
for(){
date_1 : ASD3
date_2 : EF2B
date_3 : DC
刚好都存在,认为点过赞了
}
就是md5加密之后,没碰撞,但是根据md5的加密结果,切割数组,数组里面的值可能是有重复的,得到的偏移量值相同,所以就会显示一张图片我没赞过,显示我赞过。
不足:I 点赞有重复
II 是否赞过会一直占用内存,不能清除
3.新版点赞逻辑
(1)图片上传时间在30天内的图片在redis查询是否赞过,超过30天在mongo查询,每天清理一次30天以前的点赞数据
(2)根据uploadTime,每天生成一个key
(3)用hash存,
key: date
域:picture_id
value: 点赞人的snsId列表
(4)每天100万左右点赞量预估,占用内存2G-3G左右,上线之后,点赞占用内存基本维持在这一水平
优点: I 确保点赞不会有重复
II 是否赞过可以被定期清理,占用内存量不会一直增长
4.归纳
(1)老时景用的MD5加密切割数组的形式,获取偏移量,来判断是否赞过,会有两个弊端:
I 点赞有重复
II 是否赞过会一直占用内存,不能清除
(2)新时景用hash存是否赞过,能避免点赞有重复,避免内存一直增长