Bulk API
承接上文,使用Java High Level REST Client操作elasticsearch
Bulk API
高级客户端提供了批量处理器以协助批量请求
Bulk Request
BulkRequest可以在一次请求中执行多个索引,更新或者删除操作。一次请求至少需要一个操作。
//创建BulkRequest实例
BulkRequest request = new BulkRequest();
//使用IndexRequest添加三个文档,不清楚用法可以参考Index API
request.add(new IndexRequest("posts", "doc", "1")
.source(XContentType.JSON,"field", "foo"));
request.add(new IndexRequest("posts", "doc", "2")
.source(XContentType.JSON,"field", "bar"));
request.add(new IndexRequest("posts", "doc", "3")
.source(XContentType.JSON,"field", "baz"));
Bulk API仅支持以JSON或SMILE编码的文档。 提供任何其他格式的文档将导致错误。
同一个BulkRequest可以添加不同类型的操作。
// 添加 DeleteRequest到BulkRequest,不清楚用法可以参考Delete API
request.add(new DeleteRequest("posts", "doc", "3"));
// 添加 UpdateRequest到BulkRequest,不清楚用法可以参考Update API
request.add(new UpdateRequest("posts", "doc", "2")
.doc(XContentType.JSON, "other", "test"));
// 添加 一个使用SMILE格式的IndexRequest
request.add(new IndexRequest("posts", "doc", "4")
.source(XContentType.SMILE, "field", "baz"));
可选参数
//设置超时,等待批处理被执行的超时时间(使用TimeValue形式)
request.timeout(TimeValue.timeValueMinutes(2));
//设置超时,等待批处理被执行的超时时间(字符串形式)
request.timeout("2m");
//刷新策略
request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);//WriteRequest.RefreshPolicy实例方式
request.setRefreshPolicy("wait_for");//字符串方式
//设置在执行索引/更新/删除操作之前必须处于活动状态的分片副本数。
request.waitForActiveShards(2);
//使用ActiveShardCount方式来提供分片副本数:可以是ActiveShardCount.ALL,ActiveShardCount.ONE或ActiveShardCount.DEFAULT(默认)
request.waitForActiveShards(ActiveShardCount.ALL);
同步执行
BulkResponse bulkResponse = client.bulk(request);
异步执行
批量请求的异步执行需要将BulkRequest实例和ActionListener实例传递给异步方法:
//当BulkRequest执行完成时,ActionListener会被调用
client.bulkAsync(request, listener);
异步方法不会阻塞并会立即返回。完成后,如果执行成功完成,则使用onResponse方法回调ActionListener,如果失败则使用onFailure方法。
BulkResponse 的典型监听器如下所示:
ActionListener<BulkResponse> listener = new ActionListener<BulkResponse>() {
@Override
public void onResponse(BulkResponse bulkResponse) {
//执行成功完成时调用。 response作为参数提供,并包含已执行的每个操作的单个结果列表。 请注意,一个或多个操作可能已失败,然而其他操作已成功执行。
} @Override
public void onFailure(Exception e) {
//在整个BulkRequest失败时调用。 在这种情况下,exception作为参数提供,并且没有执行任何操作。
}
};
Bulk Response
返回的BulkResponse包含有关已执行操作的信息,并允许迭代每个结果,如下所示:
//遍历所有操作结果
for (BulkItemResponse bulkItemResponse : bulkResponse) {
//获取操作的响应,可以是IndexResponse,UpdateResponse或DeleteResponse,
// 它们都可以被视为DocWriteResponse实例
DocWriteResponse itemResponse = bulkItemResponse.getResponse(); if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.INDEX
|| bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE) {
//处理index操作
IndexResponse indexResponse = (IndexResponse) itemResponse; } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.UPDATE) {
//处理update操作
UpdateResponse updateResponse = (UpdateResponse) itemResponse; } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.DELETE) {
//处理delete操作
DeleteResponse deleteResponse = (DeleteResponse) itemResponse;
}
}
批量响应提供了用于快速检查一个或多个操作是否失败的方法:
if (bulkResponse.hasFailures()) {
//该方法只要有一个操作失败都会返回true
}
如果想要查看操作失败的原因,则需要遍历所有操作结果:
for (BulkItemResponse bulkItemResponse : bulkResponse) {
if (bulkItemResponse.isFailed()) {//判断当前操作是否失败
//获取失败对象,拿到了failure对象,想怎么玩都行
BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
}
}
Bulk Processor
BulkProcessor通过提供一个工具类来简化Bulk API的使用,允许索引/更新/删除操作在添加到处理器后透明地执行。
为了执行请求,BulkProcessor需要以下组件:
RestHighLevelClient
此客户端用于执行BulkRequest并获取BulkResponse
BulkProcessor.Listener
在每次BulkRequest执行之前和之后或BulkRequest失败时调用此监听器
然后BulkProcessor.builder方法可用于构建新的BulkProcessor:
//创建BulkProcessor.Listener
BulkProcessor.Listener listener1 = new BulkProcessor.Listener() {
@Override
public void beforeBulk(long executionId, BulkRequest request) {
//在每次执行BulkRequest之前调用此方法
} @Override
public void afterBulk(long executionId, BulkRequest request,BulkResponse response) {
//在每次执行BulkRequest之后调用此方法
} @Override
public void afterBulk(long executionId, BulkRequest request, Throwable failure) {
//执行BulkRequest失败时调用此方法
}
};
//通过从BulkProcessor.Builder调用build()方法来创建BulkProcessor。
//RestHighLevelClient.bulkAsync()方法将用来执行BulkRequest。
BulkProcessor bulkProcessor = BulkProcessor.builder(client::bulkAsync, listener1).build();
BulkProcessor.Builder提供了配置BulkProcessor应如何处理请求执行的方法:
BulkProcessor.Builder builder = BulkProcessor.builder(client::bulkAsync, listener1);
//设置何时刷新新的批量请求,根据当前已添加的操作数量(默认为1000,使用-1禁用它)
builder.setBulkActions(500);//操作数为500时就刷新请求
//设置何时刷新新的批量请求,根据当前已添加的操作大小(默认为5Mb,使用-1禁用它)
builder.setBulkSize(new ByteSizeValue(1L, ByteSizeUnit.MB));//操作大小为1M时就刷新请求
//设置允许执行的并发请求数(默认为1,使用0只允许执行单个请求)
builder.setConcurrentRequests(0);//不并发执行
//设置刷新间隔时间,如果超过了间隔时间,则随便刷新一个BulkRequest挂起(默认为未设置)
builder.setFlushInterval(TimeValue.timeValueSeconds(10L));
//设置一个最初等待1秒,最多重试3次的常量退避策略。
// 有关更多选项,请参阅BackoffPolicy.noBackoff(),BackoffPolicy.constantBackoff()和BackoffPolicy.exponentialBackoff()。
builder.setBackoffPolicy(BackoffPolicy.constantBackoff(TimeValue.timeValueSeconds(1L), 3));
创建BulkProcessor后,就可以向其添加请求了:
IndexRequest one = new IndexRequest("posts", "doc", "1").
source(XContentType.JSON, "title",
"In which order are my Elasticsearch queries executed?");
IndexRequest two = new IndexRequest("posts", "doc", "2")
.source(XContentType.JSON, "title",
"Current status and upcoming changes in Elasticsearch");
IndexRequest three = new IndexRequest("posts", "doc", "3")
.source(XContentType.JSON, "title",
"The Future of Federated Search in Elasticsearch"); bulkProcessor.add(one);
bulkProcessor.add(two);
bulkProcessor.add(three);
这些请求将由BulkProcessor执行,BulkProcessor负责为每个批量请求调用BulkProcessor.Listener。
侦听器提供访问BulkRequest和BulkResponse的方法:
BulkProcessor.Listener listener = new BulkProcessor.Listener() {
@Override
public void beforeBulk(long executionId, BulkRequest request) {
//在每次执行BulkRequest之前调用,通过此方法可以获取将在BulkRequest中执行的操作数
int numberOfActions = request.numberOfActions();
logger.debug("Executing bulk [{}] with {} requests",
executionId, numberOfActions);
} @Override
public void afterBulk(long executionId, BulkRequest request, BulkResponse response) {
//在每次执行BulkRequest后调用,通过此方法可以获取BulkResponse是否包含错误
if (response.hasFailures()) {
logger.warn("Bulk [{}] executed with failures", executionId);
} else {
logger.debug("Bulk [{}] completed in {} milliseconds",
executionId, response.getTook().getMillis());
}
} @Override
public void afterBulk(long executionId, BulkRequest request, Throwable failure) {
//如果BulkRequest失败,通过调用此方法可以获取失败
logger.error("Failed to execute bulk", failure);
}
};
将所有请求添加到BulkProcessor后,需要使用两种可用的关闭方法之一关闭其实例。
awaitClose()方法可用于等待所有请求都已处理或过了指定的等待时间:
boolean terminated = bulkProcessor.awaitClose(30L, TimeUnit.SECONDS);
如果所有批量请求都已完成,则该方法返回true;如果在所有批量请求完成之前等待时间已过,则返回false
close()方法可用于立即关闭BulkProcessor:
bulkProcessor.close();
两种方法在关闭处理器之前会刷新已添加到处理器的请求,并且还会禁止将任何新请求添加到处理器。
官方文档:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-bulk.html#_optional_arguments_4
Bulk API的更多相关文章
- Elasticsearch批处理操作——bulk API
Elasticsearch提供的批量处理功能,是通过使用_bulk API实现的.这个功能之所以重要,在于它提供了非常高效的机制来尽可能快的完成多个操作,与此同时使用尽可能少的网络往返. 1.批量索引 ...
- Salesforce Bulk API 基于.Net平台下的实施
在最近的salesforce实施项目中应用到Bulk API来做数据接口.顺便把实际应用的例子写下来.希望对做salesforce接口的朋友有借鉴作用. 一 参考网络牛人写好的Demo. 下载地址:h ...
- elasticsearch6.7 05. Document APIs(9)Bulk API
8.Bulk API 可以把多个index或delete操作放在单个bulk API中执行.这样可以极大地提高索引速度. /_bulkAPI使用如下的JSON结构: action_and_meta_d ...
- ElasticSearch(十三) bulk api奇特的json格式的原因
bulk api的语法 正常的语法: {"action": {"meta"}}\n {"data"}\n {"action&quo ...
- ElasticSearch Bulk API
做一个简单的记录,以便自己后续查找 一.环境要求 ElasticSearch 7.3.0 Kibana 7.3.0 二.详情 ElasticSearch 的 Bulk API 可以批量进行索引或者删除 ...
- Elasticsearch由浅入深(六)批量操作:mget批量查询、bulk批量增删改、路由原理、增删改内部原理、document查询内部原理、bulk api的奇特json格式
mget批量查询 批量查询的好处就是一条一条的查询,比如说要查询100条数据,那么就要发送100次网络请求,这个开销还是很大的如果进行批量查询的话,查询100条数据,就只要发送1次网络请求,网络请求的 ...
- elasticsearch 中文API bulk(六)
bulk API bulk API允许开发者在一个请求中索引和删除多个文档.下面是使用实例. import static org.elasticsearch.common.xcontent.XCont ...
- elasticsearch中常用的API
elasticsearch中常用的API分类如下: 文档API: 提供对文档的增删改查操作 搜索API: 提供对文档进行某个字段的查询 索引API: 提供对索引进行操作,查看索引信息等 查看API: ...
- elasticsearch中的API
elasticsearch中的API es中的API按照大类分为下面几种: 文档API: 提供对文档的增删改查操作 搜索API: 提供对文档进行某个字段的查询 索引API: 提供对索引进行操作 查看A ...
随机推荐
- .call() 与 .apply() 的用法及区别
首先说明两个方法的含义: apply:调用一个对象的一个方法,用另一个对象替换当前对象.例如:B.apply(A, arguments);即A对象应用B对象的方法.call:调用一个对象的一个方法,用 ...
- 备考2019年6月份PMP考试-分享一些(备考)考试心得
I'm iron man,纪念离去的钢铁侠(复联4) 话说任何一个写程序的人都不可能干一辈子(有些人例外),大部分都是要转行的. 技术转管理是一条路,技术转创业是一条路,技术干销售是一条路,技术转售前 ...
- UGUI打字机效果文本组件
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; ...
- 023_System Integrity Protection in macos
背景:之前写的在/usr/bin下的一个登陆线上脚本,由于使用timemachine还原了系统,发现怎么也修改不了,加sudo也不行. 后来查询才得知系统默认开启了"系统集成保护" ...
- mysql tp5 find_in_set写法
[['','exp',"FIND_IN_SET(".$data['type'].",place_category)"]]
- 用Python建立连接直接读取与更改Rockwell Control Logix Controller的tag值
请参考如下连接的开源项目 源代码在本地测试好用. 注: 这里所用的Python 版本是 2.7.11 https://github.com/dmroeder/pylogix
- 《ServerSuperIO Designer IDE使用教程》- 6.增加与阿里云物联网(IOT)对接服务,实现数据交互。发布:v4.2.4 版本
v4.2.4 更新内容:1.增加了对接阿里物联网平台的服务.下载地址:官方下载 6. 增加与阿里云物联网(IOT)对接服务,实现数据交互 6.1 概述 为了满足业务系统数据上云的要求,Se ...
- CentOS 7.0开放指定端口
>>> CentOS 7.0默认使用的是firewall作为防火墙,使用iptables必须重新设置一下 1.直接关闭防火墙 systemctl stop firewalld.ser ...
- idea看源码
idea看源码,可以直接搜索.看接口具体调用的是哪个类里面的方法(多态)
- Vagrant 安装以及private_network配置
(需先安装virtuabox,vagrant) 1.下载centos 7 镜像,vagrant box add ceshi 镜像名 或者是使用先前vagrant package出来的box,进行加载镜 ...