如何设计一个点赞系统?

Sherwin.Wei Lv7

如何设计一个点赞系统?

点赞系统看似简单,实则非常复杂,它可以从系统架构、库表设计、数据存储、性能优化、容灾备份等多个角度来思考设计。

我们可以由浅入深的向面试官来说出这个实现方案:

系统架构设计

从架构方面需要考虑:服务拆分、异步、缓存。

1)分布式架构

大流量场景下,可以将点赞功能独立成一个服务,解耦业务逻辑,便于扩展和维护。例如点赞服务压力倍增的时候,可以仅扩容点赞服务即可。

2)异步处理

只要涉及到大流量,且实时性并没有那么强烈的场景,就需要考虑异步。可以使用消息队列(如 Kafka、RocketMQ)来异步处理点赞请求,减少直接写数据库的压力。

3)缓存机制

除了异步,其实也可以利用缓存(如 Redis、Memcached)存储点赞数,减少数据库访问

库表设计

这边简单给一个库表设计供大家参考:

1)点赞记录表

1
2
3
4
5
6
7
CREATE TABLE like_record (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
item_id BIGINT NOT NULL,
liked_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_user_item (user_id, item_id)
) ENGINE=InnoDB;

2)点赞数汇总表

1
2
3
4
CREATE TABLE like_count (
item_id BIGINT PRIMARY KEY,
like_count BIGINT DEFAULT 0
) ENGINE=InnoDB;

数据存储

上面我们提到了缓存,实际上很多公司除了用 MySQL 存储数据之外,还会利用缓存来存储这种高并发修改的数据。

例如使用 Redis 存储点赞数,承接实时的热数据,后续再将点赞数落库存储至 MySQL 中。即将热门的点赞数缓存到 Redis 中,设置适当的过期时间,定期同步到数据库。

有些大公司还会对缓存进行改造,保证缓存本身的数据持久性。

性能优化

1)数据库优化

例如为常用查询添加合适的索引。like_record 表的 user_id 和 item_id 字段。

如果整体的数据量过大,我们还根据 item_id 或 user_id 对数据进行分库分表,减少单个表的写压力。

2)缓存优化

处理上面提到的 Redis 分布式缓存,还可以利用本地缓存来减轻 Redis 的压力,但是要考虑好数据同步的问题。

3)异步批量处理

对于点赞数的写入,我们可以将一定时间窗口内的点赞请求批量更新到数据库,减少数据库的写操作。

如果用了缓存,那么可以使用定时任务定期将 Redis 中的数据同步到数据库,确保数据一致性。

容灾备份

一个系统的设计肯定需要考虑容灾备份,所以这点跟面试官提出来,会觉得你考虑周到,比较有经验。

1)数据备份

  • 定期备份:对数据库进行定期备份,使用增量备份和全量备份相结合的策略。
  • 异地备份:有条件的公司(几乎很少)会进行异地备份,防止极端情况发生。

2)高可用架构

  • 数据库主从复制:使用 MySQL 主从复制或 Redis 主从复制,实现数据的高可用性。

3)容灾演练

定期进行容灾演练,确保在发生故障时系统能够快速恢复。有些公司还有混沌工程。

混沌工程是一种故意向系统注入故障以测试其恢复能力的做法。其目的是找出潜在的故障点,并在它们造成实际中断或其他破坏之前加以纠正

简单来说,例如随便把线上的一台服务停了,看看系统是否能正常运行,来测试故障情况下系统的稳定性。

Comments