写点什么

Go 训练营第 5 周——评论系统架构设计

用户头像
Glowry
关注
发布于: 2021 年 03 月 19 日


架构设计

本质:理解客户真正的需求,解决其问题。

写评论的压力问题:通过 kafka 消峰、分区扩容的能力解决。

数据设计


mysql 一定需要配置主键,且数据必须顺序写,避免 IO 分裂影响写性能;

考虑评论内容比较大,mysql IO 每次只有 16KB 数据,考虑读写性能,将评论内容、评论元数据独立成两个表,评论的点赞、更新评论数等操作只需要更新元数据表,且每次 IO 可以捞出更多的评论 ID(评论内容表的主键),再通过 ID 点查到评论内容。另外内容和元数据独立也符合读写分离的业务场景。

for update 容易死锁的原因:多个更新同时依赖多个数据,可能会交叉锁对方的资源,导致死锁,可以在操作前先保证操作顺序,避免同一数据行下的多个锁同时出现。

分页:使用流标接口。

思考:图存储更好?


缓存设计

缓存重建问题:一般会采用预加载数据到缓存,但如果预加载过多可能会产生惊群现象,这里采用预加载请求到 kafka,然后通过 job 消费处理预加载。

redis sorted set 冗余多份排序后的数据,解决排序数据的快速加载;

评论内容优化:protobuf 序列化后存入缓存;

可用性设计

缓存穿透问题:

单飞的方式,避免一个进程里多个请求同时去回源数据。

go 的单飞支持:https://pkg.go.dev/golang.org/x/sync/singleflight

缓存抖动:参考https://www.usenix.org/system/files/conference/nsdi13/nsdi13-final170_update.pdf

热点

写热点:消息队列缓冲压力

读热点:local cache,因为内存限制,可以用环形数组+滑动窗口统计数据,再取 topk 出来做 local cache。

加餐

GC 优化:

小对象初始化时用内联方式,避免多次 new 以减少内存小对象。

type Group struct {	s sync.Mutex}
复制代码


内联方式,如果用指针的话,得 new 外层的 Group,再 new sync.Mutex,这里没加指针就是自动创建,且跟外层在同一个内存对象。


mono_repo

基础库

CI/CD


用户头像

Glowry

关注

还未添加个人签名 2019.02.13 加入

还未添加个人简介

评论

发布
暂无评论
Go训练营第5周——评论系统架构设计