精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

絕了!Spring Batch 百萬(wàn)數(shù)據(jù)分區(qū)處理,僅需五秒搞定

開(kāi)發(fā) 前端
Spring Batch允許將輸入數(shù)據(jù)從Manager步驟傳遞到Worker步驟,以便每個(gè)Worker都確切知道要做什么。JobRepository確保在作業(yè)的單個(gè)執(zhí)行過(guò)程中,每個(gè)Worker只被執(zhí)行一次。

環(huán)境:SpringBoot3.4.2

1. 簡(jiǎn)介

Spring Batch默認(rèn)是單線程的。為了實(shí)現(xiàn)并行處理,我們需要對(duì)批處理作業(yè)的步驟進(jìn)行分區(qū)。

如上圖所示,作業(yè)在左側(cè)以一系列步驟(Step)實(shí)例的順序運(yùn)行,其中一個(gè)步驟實(shí)例被標(biāo)記為管理者(manager)。圖中的所有工作節(jié)點(diǎn)(workers)均為同一步驟(Step)的相同實(shí)例,實(shí)際上這些工作節(jié)點(diǎn)完全可以替代管理者的角色,且對(duì)作業(yè)的最終結(jié)果不會(huì)產(chǎn)生任何影響。工作節(jié)點(diǎn)通常為遠(yuǎn)程服務(wù),但也可以是本地執(zhí)行線程。

Spring Batch允許將輸入數(shù)據(jù)從Manager步驟傳遞到Worker步驟,以便每個(gè)Worker都確切知道要做什么。JobRepository確保在作業(yè)的單個(gè)執(zhí)行過(guò)程中,每個(gè)Worker只被執(zhí)行一次。

分區(qū)使用多個(gè)線程來(lái)處理一系列數(shù)據(jù)集。數(shù)據(jù)集的范圍可以通過(guò)編程方式定義。根據(jù)用例,我們可以決定在分區(qū)中創(chuàng)建多少個(gè)線程來(lái)使用。線程的數(shù)量純粹基于需求/要求。

當(dāng)我們需要從源系統(tǒng)中讀取數(shù)百萬(wàn)條記錄,并且不能僅依賴(lài)單個(gè)線程來(lái)處理所有記錄(這可能會(huì)很耗時(shí))時(shí),分區(qū)就非常有用。我們希望使用多個(gè)線程來(lái)讀取和處理數(shù)據(jù),以有效地利用系統(tǒng)資源。

接下來(lái),我們將通過(guò)Spring Batch分區(qū)功能實(shí)現(xiàn)百萬(wàn)數(shù)據(jù)的讀取處理。

2.實(shí)戰(zhàn)案例

依賴(lài)管理

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-batch</artifactId>
</dependency>

開(kāi)啟批處理:

@Configuration
@EnableBatchProcessing
public class AppConfig {}

準(zhǔn)備數(shù)據(jù)如下:

數(shù)據(jù)總是為:

2.1 自定義分區(qū)

分區(qū)器(Partitioner)是用于為分區(qū)步驟創(chuàng)建輸入?yún)?shù)的核心策略接口,其輸入?yún)?shù)形式為ExecutionContext實(shí)例。通常目標(biāo)是生成一組互不重疊的輸入值集合,例如一組無(wú)重疊的主鍵范圍或唯一文件名。

在此示例中,我們通過(guò)查詢(xún)表獲取最大ID值和最小ID值(假設(shè)ID是連續(xù)的,如果你的ID是UUID,那么可以通過(guò)時(shí)間字段來(lái)劃分),并基于此在所有記錄間創(chuàng)建分區(qū)。

對(duì)于分區(qū)器,我們將網(wǎng)格大?。╣ridSize)設(shè)置為線程數(shù)量??筛鶕?jù)實(shí)際需求使用自定義值。

public class IdRangePartitioner implements Partitioner {


  private final JdbcClient jdbcClient;
  public IdRangePartitioner(JdbcClient jdbcClient) {
    this.jdbcClient = jdbcClient;
  }
  @Override
  public Map<String, ExecutionContext> partition(int gridSize) {
    int min = this.jdbcClient.sql("SELECT MIN(id) FROM o_user").query(Integer.class).single() ;
    int max = this.jdbcClient.sql("SELECT MAX(id) FROM o_user").query(Integer.class).single() ;
    int targetSize = (max - min) / gridSize + 1;


    Map<String, ExecutionContext> result = new HashMap<>();
    int number = 0;
    int start = min;
    int end = start + targetSize - 1;
    while (start <= max) {
      ExecutionContext value = new ExecutionContext();
      result.put("partition" + number, value);
      if (end >= max) {
        end = max;
      }
      // 這里設(shè)置的值每一個(gè)Worker,都將會(huì)在具體的ItemReader中通過(guò)SpEL動(dòng)態(tài)獲取
      value.putInt("minValue", start);
      value.putInt("maxValue", end);
      start += targetSize;
      end += targetSize;
      number++;
    }
    return result ;
  }
}

2.2 配置Job

接下來(lái),我們需要配置job執(zhí)行所需要的bean(Reader,Writer,Step)。

@Configuration
public class JobConfig {


  private final JobRepository jobRepository;
  private final PlatformTransactionManager transactionManager;
  private final DataSource dataSource ;
  public JobConfig(JobRepository jobRepository, PlatformTransactionManager transactionManager, 
      DataSource dataSource) {
    this.jobRepository = jobRepository;
    this.transactionManager = transactionManager;
    this.dataSource = dataSource ;
  }
  @Bean
  IdRangePartitioner partitioner(JdbcClient jdbcClient) {
    IdRangePartitioner columnRangePartitioner = new IdRangePartitioner(jdbcClient);
    return columnRangePartitioner;
  }


  @Bean
  @StepScope
  JdbcPagingItemReader<User> pagingItemReader(
      @Value("#{stepExecutionContext['minValue']}") Long minValue,
      @Value("#{stepExecutionContext['maxValue']}") Long maxValue) {
    System.out.println("reading " + minValue + " to " + maxValue);
    Map<String, Order> sortKeys = new HashMap<>();
    sortKeys.put("id", Order.ASCENDING);
    MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();
    queryProvider.setSelectClause("id, name, age, phone, sex");
    queryProvider.setFromClause("from o_user");
    queryProvider.setWhereClause("where id >= " + minValue + " and id < " + maxValue);
    queryProvider.setSortKeys(sortKeys);
    JdbcPagingItemReader<User> reader = new JdbcPagingItemReader<>();
    reader.setDataSource(this.dataSource);
    reader.setFetchSize(1000);
    reader.setRowMapper(new UserRowMapper());
    reader.setQueryProvider(queryProvider);
    return reader;
  }


  @Bean
  @StepScope
  JdbcBatchItemWriter<User> userItemWriter() {
    JdbcBatchItemWriter<User> itemWriter = new JdbcBatchItemWriter<>();
    itemWriter.setDataSource(dataSource);
    itemWriter.setSql("insert into n_user values (:id, :name, :age, :phone, :sex)");
    itemWriter.setItemSqlParameterSourceProvider
        (new BeanPropertyItemSqlParameterSourceProvider<>());
    return itemWriter;
  }


  // 主Step
  @Bean
  Step stepMaster(IdRangePartitioner partitioner) {
    return new StepBuilder("stepMaster", jobRepository)
        .partitioner(slaveStep().getName(), partitioner)
        .step(slaveStep())
        // 配置線程數(shù)
        .gridSize(50)
        .taskExecutor(new SimpleAsyncTaskExecutor())
        .build();
  }


  @Bean
  Step slaveStep() {
    return new StepBuilder("slaveStep", jobRepository)
        .<User, User>chunk(1000, transactionManager)
        .reader(pagingItemReader(null, null))
        .writer(userItemWriter())
        .build();
  }


  @Bean
  Job job(@Qualifier("stepMaster") Step stepMaster) {
    return new JobBuilder("job", jobRepository)
        .start(stepMaster)
        .build();
  }
}

說(shuō)明:

  • stepMaster中設(shè)置了任務(wù)執(zhí)行器SimpleAsyncTaskExecutor,使用該執(zhí)行器我們也可以非常方便的設(shè)置使用虛擬線程執(zhí)行(setVirtualThreads(true))。
  • 步驟(Step)中使用的資源(如數(shù)據(jù)源DataSource)可能存在并發(fā)限制。
  • IdRangePartitioner:用于為分區(qū)步驟創(chuàng)建輸入?yún)?shù)的核心策略接口,輸入?yún)?shù)形式為ExecutionContext實(shí)例。
  • JdbcPagingItemReader:此Bean使用分頁(yè)方式讀取數(shù)據(jù),并根據(jù)范圍接受最小值(minValue)和最大值(maxValue),獲取該范圍內(nèi)的數(shù)據(jù)。同時(shí)我們?cè)O(shè)置每次讀取1000條。
  • JdbcBatchItemWriter:此Bean將數(shù)據(jù)寫(xiě)入另一個(gè)表。
  • Step:這是批處理作業(yè)中配置的步驟,負(fù)責(zé)數(shù)據(jù)的讀取和寫(xiě)入操作。
  • Job:表示批處理作業(yè)的批處理領(lǐng)域?qū)ο蟆?/li>

2.3 其它輔助類(lèi)

User實(shí)體對(duì)象

public class User {
  private Integer id ;
  private String name ;
  private Integer age ;
  private String phone ;
  private String sex ;
  // getters, setters
}

表數(shù)據(jù)到對(duì)象的映射Mapper類(lèi)

public class UserRowMapper implements RowMapper<User> {
  @Override
  public User mapRow(ResultSet rs, int rowNum) throws SQLException {
    User user = new User();
    user.setId(rs.getInt("id"));
    user.setName(rs.getString("name"));
    user.setPhone(rs.getString("phone"));
    user.setSex(rs.getString("sex"));
    user.setAge(rs.getInt("age"));
    return user;
  }
}

2.4 測(cè)試

@Component
public class TaskRunner implements CommandLineRunner {
  private final JobLauncher jobLauncher;
  private final Job job;
  public TaskRunner(JobLauncher jobLauncher, Job job) {
    this.jobLauncher = jobLauncher;
    this.job = job;
  }
  @Override
  public void run(String... args) throws Exception {
    long start = System.currentTimeMillis() ;
    JobParameters jobParameters = new JobParametersBuilder()
        .addString("JobId", String.valueOf(System.currentTimeMillis()))
        .toJobParameters();
    JobExecution execution = jobLauncher.run(job, jobParameters);
    System.err.println("STATUS :: " + execution.getStatus());
  }
}

啟動(dòng)服務(wù)后,控制臺(tái)首先輸出的是分區(qū)信息:

當(dāng)完成以后輸出結(jié)果:


責(zé)任編輯:武曉燕 來(lái)源: Springboot全家桶實(shí)戰(zhàn)案例
相關(guān)推薦

2009-09-02 15:37:26

Windows 7Windows XP操作系統(tǒng)

2018-12-18 11:20:28

前端模塊化JavaScript

2025-02-11 10:48:08

2023-10-06 19:21:49

Initializr應(yīng)用Spring

2021-02-25 09:59:10

數(shù)據(jù)安全惡意攻擊密碼

2025-03-03 08:00:00

SpringBootEasyExcel數(shù)據(jù)導(dǎo)出

2011-04-21 15:56:10

筆記本硬盤(pán)

2009-08-11 09:47:01

Spring整合Str

2020-12-11 11:26:47

Spring批處理重試

2022-01-28 09:15:54

電腦間歇卡頓

2025-04-17 04:00:00

2025-07-21 09:26:00

AI開(kāi)源模型

2022-08-02 20:47:38

Spring框架應(yīng)用程序

2023-08-22 08:01:42

SpringBatch事務(wù)管理

2025-07-21 08:45:00

2025-04-29 08:00:36

2017-04-24 07:48:32

2016-04-29 10:02:39

2025-03-18 09:20:00

Go語(yǔ)言Golang

2022-09-26 09:41:25

MySQL數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

久久99精品久久久久婷婷| 日韩高清成人| 国产精品一区免费在线观看| 在线精品国产欧美| 亚洲黄色小视频在线观看| 欧美扣逼视频| 日韩高清在线电影| 一区二区在线视频播放| www.色欧美| 午夜dj在线观看高清视频完整版| 成人性生交大片免费| 久久久亚洲福利精品午夜| 四虎永久免费影院| 日韩精品三区| 亚洲色图制服丝袜| 国产三区精品| 久久久精品毛片| 成人影院在线| 欧美不卡一区二区三区四区| www.爱色av.com| 天堂资源在线中文| 成人激情动漫在线观看| 国产成人精品免高潮在线观看| 成人无码精品1区2区3区免费看| 视频二区欧美毛片免费观看| 欧美性xxxx极品hd欧美风情| 中文字幕中文字幕在线中心一区 | 国产一区二区三区网| 欧美妇女性影城| 99视频在线免费播放| 欧美18一19xxx性| 99久久精品国产网站| 国产精品亚洲一区二区三区| 久久视频免费看| re久久精品视频| 精品粉嫩超白一线天av| 色播五月综合网| sm久久捆绑调教精品一区| 国产精品国模大尺度视频| 精品国产电影| 国产黄色小视频在线观看| 久久福利精品| 久久久久久久一区二区| 一级免费黄色录像| 综合亚洲色图| 欧美tickling挠脚心丨vk| 亚洲欧美自拍另类日韩| 中文一区一区三区高中清不卡免费| 日韩码欧中文字| 欧美日韩喷水| 黄色av网站免费在线观看| 蜜桃视频在线观看一区二区| 欧美最猛性xxxx| 久久久久久av无码免费网站| 久久久久国产精品| 一本色道久久综合亚洲精品小说 | 96sao精品免费视频观看| 欧美性猛交xxxx久久久| av网站大全免费| 国产精品一区二区三区视频网站| 国产亚洲成av人在线观看导航| 国产精品一区二| 国产高清免费av| 麻豆国产欧美一区二区三区| 国产成人avxxxxx在线看 | 国产日产精品一区二区三区四区的观看方式| 日韩一级二级三级| 91视频福利网| 天天综合91| 欧美日韩亚洲国产综合| 波多野结衣天堂| 自拍偷自拍亚洲精品被多人伦好爽| 亚洲h在线观看| 国产精品成人久久电影| 久久久123| 亚洲成人一区二区在线观看| 老子影院午夜伦不卡大全| 日本在线观看大片免费视频| 亚洲精品日韩一| 亚洲激情免费视频| 亚洲性图自拍| 亚洲国产欧美日韩另类综合 | 国产无遮挡裸体免费视频| 一区在线视频| 海角国产乱辈乱精品视频| 日韩av一二三区| 国产欧美日本| 国产97色在线| 夜夜嗨aⅴ一区二区三区| 久久99久久99| 666精品在线| 精品久久久无码中文字幕| 国产a级毛片一区| 国产精品一区二区三区免费观看 | 亚洲动漫第一页| 老太脱裤让老头玩ⅹxxxx| 亚洲午夜天堂| 欧美色综合久久| www.桃色.com| 国产伦理久久久久久妇女| 亚洲精品自产拍| 又嫩又硬又黄又爽的视频| 在线国产一区| 91精品国产777在线观看| 国产伦精品一区二区三区视频网站| 青青草国产成人99久久| 亚洲www永久成人夜色| 成人免费视频国产免费麻豆| 91美女福利视频| 一区二区91美女张开腿让人桶| 亚洲丝袜一区| 欧美性videos高清精品| 国产欧美精品一二三| 精品国产导航| 亚洲一区二区黄| 国产精品 欧美激情| 免费视频一区| 91精品在线看| 婷婷亚洲一区二区三区| 国产精品1luya在线播放| 亚洲精品美女免费| 91香蕉视频污在线观看| 在线看片日韩| 国产欧美婷婷中文| 手机看片1024日韩| 一色屋精品亚洲香蕉网站| 国精产品一区一区三区视频| 国产69精品久久久久9999人| 亚洲成人久久久久| 狂野欧美性猛交| 中文亚洲字幕| 亚洲综合国产精品| 国产精品久久一区二区三区不卡 | 美女尤物久久精品| 成人免费黄色网| 熟妇人妻系列aⅴ无码专区友真希 熟妇人妻av无码一区二区三区 | caoporen国产精品视频| 中日韩在线视频| 毛片电影在线| 日韩欧美亚洲一区二区| 亚欧精品视频一区二区三区| 在线日韩视频| 91网在线免费观看| 国产精品一二三区视频| 精品国产乱码久久久久酒店 | 亚洲综合社区网| 成人动漫在线免费观看| 亚洲va欧美va人人爽午夜| 色一情一区二区三区| 欧美**字幕| 69av在线视频| 亚洲精品字幕在线| 亚洲黄色av一区| 一级黄色录像在线观看| 精品美女久久久| 欧洲中文字幕国产精品| 亚洲av片在线观看| 亚洲444eee在线观看| 人妻少妇偷人精品久久久任期| 日韩激情在线| 国产成人午夜视频网址| 欧美另类自拍| 色婷婷av一区二区三区大白胸| 91玉足脚交白嫩脚丫| 亚洲天堂成人| 成人自拍爱视频| 欧洲中文在线| 精品少妇一区二区三区视频免付费| 欧美特级一级片| 韩国一区二区三区| 亚洲国产精品女人| 精品国产三区在线| 欧美成人四级hd版| 精品人妻久久久久一区二区三区| 亚洲视频一区二区在线| 中文字幕视频三区| 亚洲老妇激情| 97久草视频| 24小时免费看片在线观看| 欧美精品一区二区久久婷婷| www.99re7.com| 9色porny自拍视频一区二区| av之家在线观看| 免费国产自久久久久三四区久久| 日韩免费中文字幕| 麻豆系列在线观看| 日韩久久精品一区| www..com国产| 国产亚洲婷婷免费| 亚洲第一天堂久久| 欧美日韩亚洲一区二区三区在线| 国产精品一区二区a| 欧美成人免费电影| 日韩在线观看免费全集电视剧网站 | 国产精品66部| 国产亚洲黄色片| 亚洲精品国模| 国产精品免费久久久| 国产原创精品视频| 亚洲护士老师的毛茸茸最新章节| 一级做a爰片久久毛片| 中文字幕在线观看不卡| www.四虎精品| 久久国产精品亚洲77777| 亚洲看片网站| 91精品国产自产精品男人的天堂| 欧美一级视频在线观看| 永久免费av片在线观看全网站| 欧美一区二区啪啪| aaaaaa毛片| 亚洲欧洲精品成人久久奇米网| 黑森林av导航| 日韩精品电影在线| 男人添女人下部视频免费| 日韩有码中文字幕在线| 成人高清视频观看www| yellow字幕网在线| 中文字幕亚洲综合久久| 欧美一区二区三区黄片| 欧美日韩精品系列| 亚洲欧美在线视频免费| 国产精品久久三区| 日本xxx在线播放| 精品一区二区三区免费毛片爱| 日韩欧美国产综合在线| 91精品国产乱码久久久久久久| 久久久com| 亚洲国产欧美国产第一区| 国产精品第一区| 白白色在线观看| 久久人人爽人人爽人人片亚洲| 视频一区二区三区在线看免费看 | 成人免费播放器| 国产精品久久久久无码av| 欧美日韩国产精品一区二区| 亚洲视频精选| 国产综合视频在线观看| 奇米777日韩| 国内精品400部情侣激情| 免费日本一区二区三区视频| 亚洲视频免费一区| 欧美熟妇乱码在线一区 | 国产一区二区视频免费观看| 日韩欧美中文字幕在线观看| 青青草手机在线观看| 中文字幕一区二| 国产精品高清无码在线观看| 99久久精品一区二区| 亚洲成a人片在线www| 久久99久久久久| www.com黄色片| 久久久水蜜桃av免费网站| 成人性免费视频| 欧美日韩岛国| 欧美一级黄色录像片| 99久久亚洲精品蜜臀| 日韩在线电影一区| 国产一区二区三区91| 免费av一区二区三区| 女人抽搐喷水高潮国产精品| 国产精品v欧美精品∨日韩| 久久的色偷偷| 91亚洲va在线va天堂va国| 日韩一区二区三免费高清在线观看| 国产精品九九九| 成人在线视频播放| 国产精品无码专区在线观看| 国产原创一区| 国产一区视频在线| 亚洲日韩中文字幕一区| 91亚洲永久免费精品| 看亚洲a级一级毛片| 99re国产视频| 高清日韩欧美| 精品国产乱码久久久久久108| 日韩超碰人人爽人人做人人添| 国产原创精品| 久久99免费视频| 色一情一乱一伦一区二区三欧美 | 日韩资源av在线| 欧美精品一区二区三区中文字幕| 日韩久久在线| 国产精品二区不卡| 996这里只有精品| 亚洲激情黄色| 日韩欧美精品在线观看视频| 日韩不卡一区二区三区| 亚洲欧美偷拍另类| 国产不卡高清在线观看视频| 视频免费在线观看| 国产欧美日韩在线看| 欧美成人短视频| 亚洲日本青草视频在线怡红院| 国产成人精品av久久| 狠狠爱在线视频一区| 中文在线最新版天堂| 91精品国产综合久久小美女| 免费国产精品视频| 亚洲欧美一区二区激情| 三区四区在线视频| 欧美激情2020午夜免费观看| 综合日韩av| 国产在线日韩在线| 狠狠一区二区三区| 亚洲国产一区二区三区在线播 | 日本一区中文字幕| 初高中福利视频网站| 26uuu精品一区二区在线观看| 欧美激情久久久久久久| 一区二区三区四区不卡在线| 天干夜夜爽爽日日日日| 欧美一二三区精品| 亚洲欧美日本在线观看| 久久伊人色综合| 美女搞黄视频在线观看| 成人黄在线观看| 精品人人人人| 在线亚洲美日韩| 亚洲精品裸体| www.色就是色.com| wwwwww.欧美系列| 蜜臀av午夜精品久久| 亚洲18色成人| av无码精品一区二区三区宅噜噜| 日韩毛片中文字幕| 2020国产在线视频| 国产精品黄视频| 成人台湾亚洲精品一区二区| 日韩精品一区二区三区外面| 国内视频精品| 伊人免费视频二| 国产欧美精品一区二区色综合朱莉 | 亚洲欧美另类在线视频| 日韩一区二区影院| 大地资源中文在线观看免费版| 久久频这里精品99香蕉| www久久久| 亚洲国产精品123| 亚洲日本久久| 成年人看片网站| 亚洲国产精品精华液ab| 天码人妻一区二区三区在线看| 精品久久久影院| 中文字幕在线三区| 91欧美精品成人综合在线观看| 精品国产一区二区三区香蕉沈先生| 精品少妇人欧美激情在线观看| 国内精品视频666| gv天堂gv无码男同在线观看 | www欧美在线| 精品国产伦一区二区三区观看方式 | 91视频免费观看网站| 午夜伦理一区二区| 刘亦菲毛片一区二区三区| 欧美激情久久久| 久久国产精品免费一区二区三区| 水蜜桃亚洲精品| 日韩高清在线不卡| 精品国产av无码| 欧美日韩一区二区三区| 无码国产精品一区二区色情男同 | 色屁屁www国产馆在线观看| 成人女保姆的销魂服务| 仙踪林久久久久久久999| 中文字幕久久av| 中文字幕一区二区在线播放 | 极品日韩av| 大尺度在线观看| 婷婷中文字幕综合| 香蕉国产在线视频| 欧美亚洲伦理www| 蜜桃a∨噜噜一区二区三区| 999香蕉视频| 久久蜜桃av一区精品变态类天堂| 丰满少妇xoxoxo视频| 亚洲性xxxx| av在线播放一区| 一区二区视频在线观看| 国产精品18久久久久久久久久久久| 深夜福利影院在线观看| 精品日韩一区二区三区| 欧美巨大丰满猛性社交| 欧美在线3区| 美女爽到高潮91| 无码人妻精品中文字幕| 日韩欧美一级二级三级久久久| 青草在线视频| 国产综合 伊人色| 亚洲综合日本| 性猛交ⅹxxx富婆video| 欧美日韩亚洲不卡| jizz性欧美10| 国产日韩亚洲精品| 日韩成人一级片| 国产真实乱在线更新| 精品日韩一区二区| 韩日成人影院| 一本色道久久综合亚洲精品婷婷| 国产电影精品久久禁18| 可以免费在线观看的av|