ElasticSearch中bulkProcesser使用遇到的问题

本文探讨了Elasticsearch中使用BulkAPI进行批量数据插入的优化策略,详细介绍了如何设置批量提交条件,包括请求数量、数据大小及时间间隔,并分析了实际运行中遇到的批量提交未按预期触发的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

废话不多说,直接上代码


/**
 * Elasticsearch的Bulk API允许批量提交index和delete请求。
 */
public class EsBulkApi {
	
	private ElasticsearchConfig esConfig;
	
	/**es 索引 index*/
	public static final String TEST_SEARCH_INDEX = "test.search";
	/**es 类型 type*/
	public static final String TEST_SEARCH_TYPE = "test_search";
/**
	 * bulkapi
	 * 在例子中,当请求超过1000个(default=1000)或者总大小超过1024MB(default=5MB)或者30s 时,触发批量提交动作。
	 */
	public void bulkApiAction2(){
		EsClientPool pool = EsUtils.esClientPool(esConfig);
		EsClient esClient = pool.getEsClient();
		BulkProcessor bulkProcessor = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			bulkProcessor = BulkProcessor.builder(esClient.getClient(), 
					new BulkProcessor.Listener() {
						/**
						 * beforeBulk会在批量提交之前执行,可以从BulkRequest中获取请求信息request.requests()或者请求数量request.numberOfActions()。 
						 */
						@Override
						public void beforeBulk(long executionId, BulkRequest request) {
							log.info("---尝试插入{}条数据---", request.numberOfActions());
						}
						/**
						 * 会在批量失败后执行。
						 */
						@Override
						public void afterBulk(long executionId, BulkRequest request, Throwable failure) {
							log.error("[es错误]---尝试插入数据失败---", failure);
						}
						/**
						 * 会在批量成功后执行,可以跟beforeBulk配合计算批量所需时间。
						 */
						@Override
						public void afterBulk(long executionId, BulkRequest request, BulkResponse response) {
							boolean hasFailures = response.hasFailures();
							if(hasFailures){
								String buildFailureMessage = response.buildFailureMessage();
								log.info("---尝试插入{}条数据失败---", request.numberOfActions());
								log.info("---失败原因---"+buildFailureMessage);
							} else{
								log.info("---尝试插入{}条数据成功---", request.numberOfActions());
							}
						}
					})
					.setBulkActions(1000)
					.setBulkSize(new ByteSizeValue(1024, ByteSizeUnit.MB))
					.setFlushInterval(TimeValue.timeValueSeconds(30))
					.build();
			for(int i=0; i<180; i++){
				Map<String,Object> searchMap = new HashMap<String,Object>();
				searchMap.put("userId", i);
				searchMap.put("userName", "yuguo"+i);
				searchMap.put("createTime", sdf.format(new Date()));
				bulkProcessor.add(new IndexRequest(TEST_SEARCH_INDEX, TEST_SEARCH_TYPE, i+"").source(searchMap));
			}
		} catch (Exception e) {
			log.error("bulk api action error",e);
		} finally {
			if(bulkProcessor != null) {
				bulkProcessor.close();
			}
			pool.removeEsClient(esClient);
		}
	}
}

在批量插入的时候,我设置当请求数据量超过1000条,或者总大小超过1024MB时,或者当请求数据量和大小都不满足要求时我设置的是每30s执行触发批量提交动作。
但是当我实际运行的时候,180条数据就是瞬间完成的。也就是说我设置的三个条件并没有生效。
按道理说,应该是要到30s后才会触发批量提交。
有没有大佬遇到过这种问题?我代码的问题在哪里?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值