←

读多写少的接口,把数据库移出请求路径

这个接口在组件被拉取时做策略匹配,并带上对应的风险数据。QPS 大约 20,压大约 10 分钟进程就会退出。机器是 32 核,压测时 MySQL 的 CPU 到 3000%。

核心路径上每一步都打了耗时,再用 trace id 串起同一次请求。时间在两处:5 次 MySQL 查询大约占 80%,一次拉取风险数据的 HTTP 大约占 20%。

旁路缓存是先想到的方案:读缓存,没有再回源数据库。它被否掉了。策略和组件的数量都很大,进程刚启动时缓存是空的,进来的请求会一起打到数据库上,服务会先被自己的冷启动打挂。这又是读很多、写很少的数据,没有理由让数据库留在每一次拉取上。

查询改到 Redis,请求只读缓存。

进程启动时把策略和风险名单装进去,第一批请求不用回源。数据库新增、修改、删除时同时改 Redis。每 10 分钟再对一次,补上某次双写没有写成功的情况。过期时间设为 15 分钟,校对发生在过期之前,避免一批键同时失效、请求再打回数据库。值里只留匹配要用的字段。大约 6 万条占 30MB。QPS 到 600 时,Redis 还不是瓶颈。

5 次 SQL 和 1 次 HTTP 变成读 Redis。QPS 从大约 20 到大约 600,CPU 从大约 3000% 降到大约 60%。跑一段时间就退出的情况没有再出现。

并发再往上加,这项改动就不再带来收益。下一步要看的是 pprof、MySQL 连接池、Redis 连接池和 TCP 连接数。那一轮还没有结论,所以这里不写后续优化的效果。