统计看板定时缓存刷新策略:降低跨境代购后台数据库高频聚合压力-CSDN博客
后台运营人员会高频刷新订单、运单、用户三大统计看板,每次刷新都会触发数据库聚合查询,工作日高峰期每分钟数十次报表请求,持续占用 MySQLCPU 资源,挤压订单、支付等核心业务数据库算力。我在优化 Taocarts 统计模块性能时,引入分层定时缓存刷新策略,区分实时指标、日度时序指标、月度汇总指标设置差异化缓存时效,定时任务主动刷新缓存,前端请求直接读取 Redis 缓存数据,大幅减少数据库聚合查询频次,本文完整讲解缓存分层设计、定时刷新任务、缓存失效降级逻辑、前端缓存友好交互代码,适配所有反向代购、跨境转运平台统计看板性能优化。
传统无缓存统计模式存在资源浪费问题:
第一,运营频繁切换日期筛选,相同日期范围重复执行相同聚合 SQL;
第二,实时汇总指标(今日订单、今日销售额)每秒刷新无意义,5 分钟内数据变动极小;
第三,月度、年度汇总数据几乎全天无变动,却持续重复查询数据库;第四,缓存无主动刷新机制,全靠请求被动写入,高并发刷新时大量请求击穿缓存直达数据库,造成缓存雪崩。
分层缓存策略设计三类缓存:
实时短期缓存(5 分钟时效):今日实时汇总指标、当日营业趋势数据,定时任务每 5 分钟主动刷新写入 Redis;
日度时序缓存(2 小时时效):指定日期区间每日预聚合时序数据,前端筛选日期后缓存对应区间结果;
月度汇总长效缓存(24 小时时效):月度营收、线路月度排行、用户月度分层数据,凌晨定时任务一次性刷新。
同时增加缓存雪崩防护:不同类型缓存刷新时间错峰执行,避免同一时刻大量定时任务同时查询数据库;缓存失效时开启降级逻辑,直接返回上一版本缓存数据,不阻塞用户页面加载。
统计缓存定时主动刷新任务代码:
// src/modules/statistics/task/stat-cache.task.ts
import
{
Injectable
}
from
'@nestjs/common'
;
import
{
Cron
,
CronExpression
}
from
'@nestjs/schedule'
;
import
{
OrderStatService
}
from
'../service/order-stat.service'
;
import
{
TransStatService
}
from
'../service/trans-stat.service'
;
import
{
UserStatService
}
from
'../service/user-stat.service'
;
import
{
RedisService
}
from
'src/common/redis/redis.service'
;
@
Injectable
(
)
export
class
StatCacheTask
{
constructor
(
private
orderStat
:
OrderStatService
,
private
transStat
:
TransStatService
,
private
userStat
:
UserStatService
,
private
redis
:
RedisService
)
{
}
// 每5分钟刷新今日实时统计缓存(错峰0分、5分、10分…)
@
Cron
(
'*/5 * * * *'
)
async
refreshTodayRealCache
(
)
{
const
today
=
new
Date
(
)
;
const
start
=
new
Date
(
today
.
toLocaleDateString
(
)
+
' 00:00:00'
)
;
const
end
=
new
Date
(
today
.
getTime
(
)
)
;
// 同步刷新三大模块今日实时数据缓存
const
orderData
=
await
this
.
orderStat
.
getRangeStat
(
start
,
end
)
;
const
transData
=
await
this
.
transStat
.
getTransTotalStat
(
start
,
end
)
;
const
userData
=
await
this
.
userStat
.
getUserOverview
(
start
,
end
)
;
await
Promise
.
all
(
[
this
.
redis
.
set
(
'stat:order:today'
,
JSON
.
stringify
(
orderData
)
,
300
)
,
this
.
redis
.
set
(
'stat:trans:today'
,
JSON
.
stringify
(
transData
)
,
300
)
,
this
.
redis
.
set
(
'stat:user:today'
,
JSON
.
stringify
(
userData
)
,
300
)
]
)
;
}
// 每日凌晨2点刷新月度长效缓存
@
Cron
(
'0 2 * * *'
)
async
refreshMonthLongCache
(
)
{
const
now
=
new
Date
(
)
;
const
monthStart
=
new
Date
(
now
.
getFullYear
(
)
,
now
.
getMonth
(
)
,
1
)
;
const
monthEnd
=
new
Date
(
)
;
const
monthKey
=
`
${
now
.
getFullYear
(
)
}
${
String
(
now
.
getMonth
(
)
+
1
)
.
padStart
(
2
,
'0'
)
}
`
;
const
routeTop
=
await
this
.
transStat
.
getRouteTopList
(
monthStart
,
monthEnd
,
'payTotal'
)
;
await
this
.
redis
.
set
(
`
stat:route:month:
${
monthKey
}
`
,
JSON
.
stringify
(
routeTop
)
,
86400
)
;
}
}
统计接口缓存读取 + 降级逻辑封装
async
getOrderRangeStat
(
start
:
Date
,
end
:
Date
)
{
const
cacheKey
=
`
stat:order:range:
${
start
.
getTime
(
)
}
-
${
end
.
getTime
(
)
}
`
;
const
cacheVal
=
await
this
.
redis
.
get
(
cacheKey
)
;
// 缓存存在直接返回,无需查库
if
(
cacheVal
)
return
JSON
.
parse
(
cacheVal
)
;
// 无缓存查询数据库
const
dbData
=
await
this
.
shardStat
.
rangeQuery
(
start
,
end
)
;
// 写入2小时缓存
await
this
.
redis
.
set
(
cacheKey
,
JSON
.
stringify
(
dbData
)
,
7200
)
;
return
dbData
;
}
前端页面增加缓存加载提示,区分缓存数据、实时数据库数据展示标识,运营可直观感知数据更新时效。整套缓存策略上线后,统计模块数据库聚合查询请求量下降 85%,数据库 CPU 负载显著降低,不会因为后台高频刷新报表挤压订单、支付核心业务算力,完美适配高访问量淘宝 1688 代购系统、跨境集运独立站长期稳定运营。