【背景】
随着我们系统使用,数据的增多,系统还是之前的架构,那么如何面对数据增多,优化我们系统呢?
【方法】
一、内存
多台服务器,会涉及分布式,而且放到内存重启机器,数据会丢失。
二、中间件
redis可以,但是迁移成本高
三、锁
可以,但是mysql乐观锁和悲观锁,加锁效率会低,操作不当可能导致锁全表
四、分片
在分布式任务调度平台有执行模式,有分片模式,可以先将数据建立一个索引,这个索引就是分配给那台机器处理的编号。
然后在定时任务执行的时候,获取分布式任务调度平台传递的分片,机器根据分片去获取自己所处理的数据。
我们只执行分片有时候效率还是比较低,我们可以再加上多线程,但是多线程没有限制的话,会继续导致CPU的飙升。
java
//分批处理:每批最的数据
final int batchSize = 25;
int totalProcessed = 0;
//创建固定大小的线程池用于处理每个批次
int processedCount = Runtime.getRuntime().availableProcessors();
logger.info(" 目前可用的线程数,线程池大小为:" + processedCount);
int threadPoolSize = Math.min(5,processedCount);//最多使用5个线程,避免过度占用率CPU
logger.info(" 这次定时任务处理使用的线程数,线程池大小为:" + threadPoolSize);
ExecutorService batchExecutor = Executors.newFixedThreadPool(threadPoolSize);
try {
//遍历所有批次,顺序处理
for (int batchIndex=0; batchIndex<shardList.size();batchIndex+=batchSize){
//获取当前批次的任务
int endIndex = Math.min(batchIndex+batchSize,shardList.size());
List<ConfigGenerationShard> batch = shardList.subList(batchIndex, endIndex);
logger.info("TwoBDDeployConfigTaskExecJob 处理批次 " + (batchIndex/batchSize + 1) + "/" +
(int)Math.ceil((double)shardList.size()/batchSize) + ", 任务数量: " + batch.size());
// 在当前批次内使用多线程处理每个任务
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (ConfigGenerationShard record : batch) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
//任务逻辑
}, batchExecutor);
futures.add(future);
finally {
//关闭线程池
batchExecutor.shutdown();
}
这样的话,就完全解决了CPU飙升导致系统卡主的问题,而且处理速度也很快。