
继续答星球水友提问,30WQPS的点赞计数业务,如何设计?
(2)redis天然支持固化,
可以用高可用redis集群来做固化存储
;
(3)
也可以用MySQL来做固化存储
,
redis做缓存
,读写操作都落缓存,
异步线程定期刷DB
;
t_count(msg_id, praise_count)
key:msg_id
value:praise_count

计数系统的难点,还在于
业务扩展性
问题,以及
效率
问题。

(1)用户微博首页,
有多条消息
list<msg_id>
,这是一种扩展;
(2)同一条消息msg_id,
不止有点赞计数,还有阅读计数,转发计数,评论计数
,这也是一种扩展;
假如用最朴素的方式实现,多条消息多个计数的获取伪代码如下:
// (1)获取首页所有消息msg_id
list<msg_id> = getHomePageMsg(uid);
// (2)对于首页的所有消息要拉取多个计数
for( msg_id in list<msg_id>){
//(3.1)获取阅读计数
getReadCount(msg_id);
//(3.2)获取转发计数
getForwordCount(msg_id);
//(3.3)获取评论计数
getCommentCount(msg_id);
//(3.4)获取赞计数
getPraiseCount(msg_id);
}
由于同一个msg_id多了几种业务计数,
redis的key需要带上业务flag
,升级为:
msg_id:read
msg_id:forword
msg_id:comment
msg_id:praise
用来区分共一个msg_id的四种不同业务计数,redis不能支持key的模糊操作,必须访问四次reids。
(1)for循环每一条消息,100条消息100次;
(3)每次调用服务要访问reids,拼装key获取count;
首先看下数据库层面元数据扩展,常见的扩展方式是,
增加列
,记录更多的业务计数。

如上图所示,由一列点赞计数,扩充为四列阅读、转发、评论、点赞计数。
增加列这种业务计数扩展方式的缺点是:
每次要扩充业务计数时,总是需要修改表结构
,增加列,很烦。

t_count(msg_id, count_key, count_value)
当要扩充业务计数时,增加一行就行,不需要修改表结构。
画外音:很多配置业务,会使用这种方案,方便增加配置。
增加行这种业务计数扩展方式的缺点是:
表数据行数会增加
,但这不是主要矛盾,数据库水平扩展能很轻松解决数据量大的问题。

原始方案,通过拼装key来区分同一个msg_id的不同业务计数。

如上图所示,
同一个msg_id的四个计数
,存储在一个value里,从而避免多次redis访问。
画外音:通过value来扩展,是不是很巧妙?
计数业务,在数据量大,并发量大的时候,要考虑的一些技术点:
(4)要考虑扩展性,数据库层面常见的优化有:列扩展,行扩展两种方式;
(5)要考虑批量操作,缓存层面常见的优化有:一个value存储多个业务计数;