redis 实现点赞功能
公司的员工风采栏目下,有文章需要处理点赞。搜索了网上的案例,普遍做法有两种,一种是mysql 直接连数据库,进行存储。有点
缺点是热门文章频繁点赞时,对数据库的访问压力变大。另外一种就是利用点赞的业务特征来扔到redis(或memcache)中, 然后离线刷回mysql等。
直接写入Mysql
直接写入Mysql是最简单的做法。
做三个表即可,
-
comment_info
记录文章的主要内容,主要有like_count,hate_count,score这三个字段是我们本次功能的主要字段。
-
comment_like
记录文章被赞的次数,已有多少人赞过这种数据就可以直接从表中查到;
-
user_like_comment
记录用户赞过了哪些文章, 当打开文章列表时,显示的有没有赞过的数据就在这里面;
缺点
-
数据库读写压力大
热门文章会有很多用户点赞,甚至是短时间内被大量点赞, 直接操作数据库从长久来看不是很理想的做法
redis存储随后批量刷回数据库
redis主要的特点就是快, 毕竟主要数据都在内存嘛;
另外为啥我选择redis而不是memcache的主要原因在于redis支持更多的数据类型, 例如hash, set, zset等。
下面具体的会用到这几个类型。
优点
-
性能高
-
缓解数据库读写压力
其实我更多的在于缓解写压力, 至于读压力, 通过mysql主从甚至通过加入redis对热点数据做缓存都可以解决,
写压力对于前面的方案确实是不大好使。
缺点
-
开发复杂
这个比直接写mysql的方案要复杂很多, 需要考虑的地方也很多;
-
不能保证数据安全性
redis挂掉的时候会丢失数据, 同时不及时同步redis中的数据, 可能会在redis内存置换的时候被淘汰掉;
不过对于我们点赞而已, 稍微丢失一点数据问题不大;
其实上面第二点缺点是可以避免的,这就涉及到redis 的一些设计模式,不懂没关系,我尽量详细的写,后面我会给出如何解决这个缺点。
设计功能前知识准备
1.将要用到的redis数据类型(具体的类型说明,请看底部链接,有详细说明):
- zset 这个类型主要用来做排序或者数字的增减,这里被用作like 和hate的数字记录,以及热度的记录。
- set 这个是无序集合,主要用来记录今天需不需要更新,将今天被点赞(包括点讨厌)过的文章id记录下来,方便晚上或者有时间对这部分数据更新。
- hash 这个是散列,主要用来存储数据以及索引。这里被用来记录用户对哪个文章点了什么,方便下次判断(我看过一些网上的介绍使用set来记录,那个也可以,但是本人觉得这样做更省空间,以及方便管理,再有就是hash的速度快)。
- list 这个是队列大佬,我们的数据能不能 安全 回到mysql就靠它了。
2.关于热度如何去判断:
大家都知道,文章获得点赞数越高,文章的热度就越高,那么怎么判断呢?不就直接记录点赞数就行啦,但是对于最新的文章怎么办?例如有一篇文章一年前发布的,获得50个赞,有篇最新文章获得49个赞,但是按照上面所说的一年前的文章热度还比最新的高,这就不合理了,文章都是时效性,谁都想看最新最热的。
so!我们要换个方法去处理这个时效性,绝大部分语言都有 时间戳 生成的方法,时间戳随着时间越新,数字越大,直接将时间戳初始化赋值给文章的score,这样最新的文章相比以前的文章就会靠前了。接着是点赞对score的影响,我们假设一天得到20个赞算是一天最热,一天60*60*24=86400秒,然后得到一个赞就是得到86400 / 20 = 4320分。具体数字看自己的业务需求定,我只是举例子而已。点hate当然也会减去相应的数字。
代码后面再详细写。