March 26, 2021
Here is the article.
架构设计
本质:理解客户真正的需求,解决其问题。
写评论的压力问题:通过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以减少内存小对象。
内联方式,如果用指针的话,得new 外层的Group,再new sync.Mutex,这里没加指针就是自动创建,且跟外层在同一个内存对象。
mono_repo
基础库
CI/CD
No comments:
Post a Comment