1028 字
约 3 分钟
0
为什么引入 Redis 缓存要自定义线程池配置类
很多人有个误解:一引入 Redis 缓存,就要配一个线程池配置类。其实如果只是同步 get/set,一个线程池都不需要。真正逼着你写线程配置的,是缓存场景里躲不开的异步化。
这篇文章就讲清楚:缓存为什么会牵扯出线程池、为什么不能直接用默认的、以及自定义时到底在配什么。
一、缓存一旦"异步",线程池就躲不开
缓存最典型的三个异步场景:
- 异步回填 / 重建缓存:热点 key 失效瞬间,如果让请求同步去查库重建,响应会被拖慢;通常把"查库 + 写回 Redis"丢到线程池异步执行,请求先返回;
- 缓存删除(延迟双删):更新数据库后要删旧缓存,为保一致性常做"延迟删除",删缓存这步异步做,避免阻塞主链路;
- 缓存预热 / 定时刷新:启动时或定时把热点数据异步预热进缓存。
这些异步操作都需要一个线程池来承载,于是"引入缓存 → 要异步 → 要线程池"这条链就成立了。
二、为什么不能直接用默认线程池
如果随手用 Java 自带的方式建线程,生产环境会踩一堆坑:
| 写法 | 问题 |
|---|---|
ForkJoinPool.commonPool()(CompletableFuture 默认) |
全局共享、容量小(≈ CPU 核数 - 1),被并行流等占用,任务一多就线程饥饿 |
Executors.newFixedThreadPool() |
底层是无界队列,任务积压会无限占内存 |
Executors.newCachedThreadPool() |
线程数不封顶,高并发下疯狂建线程,直接 OOM |
| 不指定线程名 | 线上堆栈全是 pool-1-thread-1,排障定位极其痛苦 |
自定义线程池能显式控制核心线程数、最大线程数、队列容量、拒绝策略、线程名前缀、优雅关闭——这些在缓存这种高并发场景下都是保命参数。
三、结合笔记服务实战来看
在"查询用户信息接口 + Redis 缓存"这类服务里,常用 CompletableFuture.supplyAsync(...) 并发调用下游服务。注意:
supplyAsync(...)不传线程池时,默认跑在ForkJoinPool.commonPool()上;- 如果服务里多处并发异步,全部挤在全局公共池里,线程互相抢占、任务互相阻塞,流量去向也说不清;
- 所以需要自定义一个
ThreadPoolTaskExecutorBean,给"缓存相关 + 下游并发调用"一个专属、可控、有名字的线程池。
四、自定义时重点配置这 4 项
@Configuration
public class ThreadPoolConfig {
@Bean("cacheThreadPool")
public ThreadPoolTaskExecutor cacheThreadPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(4);
executor.setMaxPoolSize(8);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("cache-async-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
- 核心 / 最大线程数:按 CPU 密集或 IO 密集来定,缓存、查库属于 IO 密集,可适当调大;
- 队列容量:给任务一个缓冲,避免任务一多直接触发拒绝;
- 线程名前缀:
cache-async-方便在日志、Arthas、监控里一眼认出线程来源; - 拒绝策略:缓存回填这类"丢了也无所谓"的任务可丢弃;"不能丢"的任务用
CallerRunsPolicy(由调用线程自己执行,天然形成背压)。
五、总结
- 不是"Redis 要线程配置",而是缓存带来的异步操作(回填、延迟双删、预热、并发调用下游)需要可靠可控的线程池;
- 默认线程池(公共 ForkJoinPool / 无界队列 / 不封顶线程数)扛不住生产环境的并发与排障需求;
- 自定义线程池 = 可控的线程数 + 有界的队列 + 明确的拒绝策略 + 可识别的线程名,是缓存异步化的基础设施。
下次再看到项目里的 ThreadPoolConfig,你就知道它服务的不是"Redis 本身",而是缓存背后那一整条异步链路。
为什么引入 Redis 缓存要自定义线程池配置类
https://www.clxhxhhr.top/posts/4590/ 评论
0 条
还没有评论,先写一条吧。