项目实时数据大屏展示导致数据库阻塞问题诊断
项目之前做过一个大屏数据展示的单页,需要展示实时的订单数、订单金额,还有设备、商铺方面的排行榜。因为前、后端开发对于 SQL 数据查询阻塞缺乏认知(也是因为懒),将单页中的所有数据都通过一个接口返回,前端每 10s 刷新一次数据。
后来发现了数据查询的阻塞问题,后端使用了 redis 缓存查询结果 1 个小时。这本来是可以缓解一些数据阻塞问题,因为按照理想状态,只要第一次查询到了数据,后续 1 个小时内都不会再有新的、相同的数据查询。唯一忽视的问题是,前端是 10s 刷新一次数据,如果数据不能够在限定时间内查询到,那么就会造成可怕的后果。
前端请求是有超时时间的,在这次的问题里发现,请求返回了 504。这意味着每 10s 一次,大概有 10 几次的请求,都没有等到查询结果就结束了。程序上应该是在 sql 返回结果前就结束了,这样 redis 永远拿不到缓存,即缓存没有起作用。
针对现有的问题,大概想到以下几种优化方法:
1. 降低实时数据的即时性。
前端降低查询的频次间隔,改为 5 分钟或 10 分钟一次刷新数据。针对存在不停刷新页面导致的不间断请求情况,后台设置 redis 标识字段,表示查询进行中。每次开始查询后,设置为进行中,查询结束之后才可以再次查询。针对前一次查询进行中的二次查询,直接返回空数据,或错误提示让前端耐心等待。
2. 拆分查询请求,区分需要即时查询的数据和普通时效的数据
可以将请求根据时效性拆分成多个查询请求,这样不仅降低了查询请求时间,还能针对不同时效的数据做不同级别的缓存。同时针对一些查全表的统计数据,可以做二级缓冲表,按年月生成记录,然后对二级表做统计。