SQL高并发统计优化_计数缓存与异步更新

2次阅读

并发统计应采用缓存+异步双策略:用redis缓存高频计数并同步增减,多维聚合通过日志异步计算;辅以降级、校准和强一致兜底机制。

SQL高并发统计优化_计数缓存与异步更新

高并发场景下直接对数据库执行 count(*) 或实时聚合统计,极易成为性能瓶颈。核心思路是:用缓存扛读、用异步解耦写,避免统计逻辑拖慢主业务。

计数缓存:用 Redis 代替实时 COUNT

将高频查询的统计结果(如文章总浏览量、商品销量、用户发帖数)缓存在 Redis 中,每次操作只更新缓存值,不查库。

  • 初始化时用一次 sql 聚合(如 select COUNT(*) FROM posts WHERE user_id = 123)同步到 Redis 的 INCRBYSET 键中
  • 新增/删除记录时,业务代码同步执行 INCR keyDECR key,不触发数据库 COUNT
  • 缓存键建议带业务维度,例如 user:123:post_countitem:456:sales,便于局部失效
  • 设置合理过期时间(如 24 小时),并配合定时任务或旁路双检机制兜底数据一致性

异步更新:统计归集与延迟写入分离

对于需多维聚合(如按小时/地区/设备统计 PV/UV)的场景,禁止在请求链路中执行 GROUP BY + SUM。应把原始行为日志先落盘,再由后台消费者异步计算。

  • 前端或网关将点击、曝光等事件写入 kafka / Pulsar / 本地日志文件,格式轻量(json 或 Protobuf)
  • 独立消费服务拉取日志,按窗口(如 1 分钟滚动)批量解析、聚合,结果写入 Redis 或专用统计表(如 stat_daily_summary
  • 主业务接口只读缓存或宽表,响应控制在 10ms 内;统计延迟接受秒级到分钟级,不强求实时
  • 关键指标(如订单成交数)可额外走“预写日志 + 异步补偿”双保险,防止消息丢失导致漏统

兜底与一致性保障

缓存和异步不是银弹,必须设计降级与校准机制。

  • Redis 不可用时,自动降级为走数据库 SELECT COUNT(*) WITH (NOLOCK)(SQL Server)或 /*+ READ_UNCOMMITTED */mysql),并加短超时(500ms)和熔断
  • 每日凌晨用离线任务(spark / flink SQL)全量比对缓存值与事实表,输出差异报告,人工或自动触发修复
  • 对强一致要求的场景(如库存余量),禁用纯缓存计数,改用数据库行锁 + 原子更新(UPDATE stock SET qty = qty – 1 WHERE id = 789 AND qty >= 1

不复杂但容易忽略。缓存不是得越多越好,异步不是扔进队列就完事——关键是明确哪些统计能容忍延迟、哪些必须精确、哪些可以近似,再匹配对应策略。

text=ZqhQzanResources