Keywords: 缓存抗读写、数据库扩展(列扩展+行扩展)、批量操作、计数系统与业务系统分离、业务拓展性、读写效率

# 1. 一些概念

QPS:并发量 / 平均响应时间。即每秒的响应请求数,也是最大吞吐能力。

# 2. 思路考虑

Redis做缓存层,数据固化落到DB上。核心数据设计:

  • mysql:t_count(msg_id, parise_count)
  • redis(k-v): key: msg_id; value: praise_count

物理机依托mysql和redis,水平拓展不是问题。

# 3. 计数系统的难点与优化

# 3.1 真实业务场景

记数系统的难点在于:业务拓展性,以及读写效率

业务拓展性:体现在下面这张图中,一个消息中,除了点赞数,还有评论、转发、阅读数。

img

效率:一个页面中,有很多条消息(只能在代码中循环每一条消息)。

# 3.2 一种不算完美的解决方案

Redis的k-v设计上,k的生成规则可以使用:msg_id:业务flag 的格式。比如对于第一条消息的阅读数,它的key就是:1:read;对于评论数:1:comment

在针对指定消息查询的时候,需要对redis发起多次RPC调用。浪费次数。

Mysql的设计上,常见就是列扩展。如下所示:

msg_id read_count comment_count
1 100000 1000
2 200000 2000

但是更改表结构的时候,存在着效率问题。

# 3.3 比较好的方案

针对Redis,能做的就是降低单独消息的RPC调用次数,减少Redis访问次数。可以将count的计数,放在同一个value中。如下所示:

Key value
1 100000:1000

针对Mysql,可以使用行扩展来解决列扩展问题,表结构设计如下:

msg_id count_key count_value
1 read 100000
1 comment 1000

# 3.4 读写效率问题

对于计数系统来说,读的次数远远大于写的次数。因此,影响读写效率的主要是读操作。对于redis的valu结构优化来说,写的话需要2次RPC,读的话仅需1次,使用写效率换读效率。

# 🔗 参考链接