项目背景
客户的数据量徒增,每天1QWPV,1个月1张表的话大约这一个客户有30亿数据,页面上一些接口的响应变慢。
原因是:后端数据存在了ES中,ES特点是模糊查询很开,但是但是如果用到了一些叫复杂的聚合函数需要进行索引扫描,所以效率了堪忧。
优化方案
- 每天,用定时器将客户网站数据归档,目前是采用mysql保存。
- 前端查询采用缓存数据+当天数据的方式呈现给客户,当日的数据很小所以可以满足性能上的要求。
- 考虑到将来会有很多客户,可能一个定时器执行效率慢,所以定时器要支持水平扩展。
具体执行
- 将数据库中所有的网站ID放到redis的zset中,为什么用zset?有序-支持分页,排重;
- 利用setNx做锁, 从zset取出一条数据锁住:setNx的key是:prefix:statslock:id:yyyyMMdd, ttl:1天;
- 因为采用的是RedisTemplate不支持setNx和expire排异常轻快无法解锁,所以锁是按天锁住数据
- ES查询昨天的数据,归档
- 前端查询ES当钱数据+归档数据返回,测试从10sec请求变为了600ms
示例代码如下:
1 | public void doWafDataArchiveByDate(LocalDateTime localDateTime) { |
遗留的坑以及方案
待补充