jetcache RefreshCache处理key值较多的缓存场景时是否会有潜在问题?

55ooxyrt  于 2022-11-06  发布在  其他
关注(0)|答案(8)|浏览(355)

主要比较关注自动更新缓存这个功能,查看了下源码发现这部分实现使用了Executors.newScheduledThreadPool()方法构建线程池,但是这个方法默认最大线程池为无限,是否在key值比较多的时候可能因为创建线程数过多导致OOM?而且因为这个阿里巴巴Java开发手册也强制不允许使用Executors创建线程池。

所以想问下如果我的使用场景是“key比较,实时性要求不高,加载开销非常大的缓存场景”,这种情况是否不太适合使用RefreshCache这个功能。

另外我在文档中也看到过您提到“对一些key比较少,实时性要求不高,加载开销非常大的缓存场景,适合使用自动刷新“,您这里说的”key比较少“能具体化已下么?key值大概为多少的时候定义为”比较少“呢?

jq6vz3qz

jq6vz3qz1#

JetCacheExecutor上面的heavyIOExecutor是可以定制的。

具体数字你可以建模来计算,比如如果你使用10个最大线程的固定线程池,应用服务器5台,平均每个加载耗时2秒,30秒刷新一次,那么理论上最多只能刷新30 / 2 * 10 * 5=750个key。

通过设置stopRefreshAfterLastAccess,可以自动停止无意义的刷新。

ygya80vv

ygya80vv2#

这个heavyIOExecutor的默认值我也改一下吧

llmtgqce

llmtgqce3#

ScheduledThreadPoolExecutor的构造方法不能直接指定最大线程数,强制指定一个线程池和队列的边界会导致无法保证调度,一时没看明白构造方法中的RejectedExecutionHandler handler是干什么用的,这个我再看看吧

xoefb8l8

xoefb8l84#

开发团队人比较多的话,容易滥用,还是在key比较少的时候谨慎的使用吧

2w3kk1z5

2w3kk1z55#

ScheduledThreadPoolExecutor的构造方法不能直接指定最大线程数,强制指定一个线程池和队列的边界会导致无法保证调度,一时没看明白构造方法中的RejectedExecutionHandler handler是干什么用的,这个我再看看吧

RejectedExecutionHandler handler是拒绝策略吧,当要创建的线程数量大于设置的线程池最大线程数的时候,新的任务就会被拒绝(抛弃、抛异常或扔给主线程)

但是刚才又看了下ScheduledThreadPoolExecutor构造方法用的默认队列是DelayedWorkQueue,这是一个无界队列,里面的grow方法会在容量不够时一直扩容下去,这种情况下新的任务只会一直被阻塞下去,直到服务器被搞崩,这样maximumPoolSize和RejectedExecutionHandler也没啥意义了

那我自动刷新还是小心点用好了

puruo6ea

puruo6ea6#

有个构造函数要指定handler,那么肯定是有用的,这些天比较忙,暂时还顾不上细看

hgtggwj0

hgtggwj07#

ScheduledThreadPoolExecutor的构造方法不能直接指定最大线程数,强制指定一个线程池和队列的边界会导致无法保证调度,一时没看明白构造方法中的RejectedExecutionHandler handler是干什么用的,这个我再看看吧

RejectedExecutionHandler handler是拒绝策略吧,当要创建的线程数量大于设置的线程池最大线程数的时候,新的任务就会被拒绝(抛弃、抛异常或扔给主线程)

但是刚才又看了下ScheduledThreadPoolExecutor构造方法用的默认队列是DelayedWorkQueue,这是一个无界队列,里面的grow方法会在容量不够时一直扩容下去,这种情况下新的任务只会一直被阻塞下去,直到服务器被搞崩,这样maximumPoolSize和RejectedExecutionHandler也没啥意义了

那我自动刷新还是小心点用好了

ScheduledThreadPoolExecutor的maximumPoolSize是没有用的,默认情况下就是一个固定大小的线程池,不会因为线程无限增长耗尽内存,当然任务太多也是不行的。

rqdpfwrv

rqdpfwrv8#

ScheduledThreadPoolExecutor的构造方法不能直接指定最大线程数,强制指定一个线程池和队列的边界会导致无法保证调度,一时没看明白构造方法中的RejectedExecutionHandler handler是干什么用的,这个我再看看吧

RejectedExecutionHandler handler是拒绝策略吧,当要创建的线程数量大于设置的线程池最大线程数的时候,新的任务就会被拒绝(抛弃、抛异常或扔给主线程)
但是刚才又看了下ScheduledThreadPoolExecutor构造方法用的默认队列是DelayedWorkQueue,这是一个无界队列,里面的grow方法会在容量不够时一直扩容下去,这种情况下新的任务只会一直被阻塞下去,直到服务器被搞崩,这样maximumPoolSize和RejectedExecutionHandler也没啥意义了
那我自动刷新还是小心点用好了

ScheduledThreadPoolExecutor的maximumPoolSize是没有用的,默认情况下就是一个固定大小的线程池,不会因为线程无限增长耗尽内存,当然任务太多也是不行的。

请问这个问题后续有结论吗,我看ScheduledThreadPoolExecutor底层的阻塞队列DelayedWorkQueue是一个无界队列,这会无限创建无数的线程,可能导致内存溢出;我理解虽然核心线程池大小是固定的,同时执行的线程数也是因此固定的,这没问题,但是阻塞队列是无界的,这应该会导致在队列中等待执行的线程特别多而内存溢出。此问题可参考: https://www.jianshu.com/p/5d994ee6d4ff

相关问题