承接上文,使用Java High Level REST Client操作elasticsearch

Bulk API

高级客户端提供了批量处理器以协助批量请求

Bulk Request

BulkRequest可以在一次请求中执行多个索引,更新或者删除操作。一次请求至少需要一个操作。

  1. //创建BulkRequest实例
  2. BulkRequest request = new BulkRequest();
  3. //使用IndexRequest添加三个文档,不清楚用法可以参考Index API
  4. request.add(new IndexRequest("posts", "doc", "1")
  5. .source(XContentType.JSON,"field", "foo"));
  6. request.add(new IndexRequest("posts", "doc", "2")
  7. .source(XContentType.JSON,"field", "bar"));
  8. request.add(new IndexRequest("posts", "doc", "3")
  9. .source(XContentType.JSON,"field", "baz"));

Bulk API仅支持以JSON或SMILE编码的文档。 提供任何其他格式的文档将导致错误。

同一个BulkRequest可以添加不同类型的操作。

  1.     // 添加 DeleteRequest到BulkRequest,不清楚用法可以参考Delete API
  2. request.add(new DeleteRequest("posts", "doc", "3"));
  3. // 添加 UpdateRequest到BulkRequest,不清楚用法可以参考Update API
  4. request.add(new UpdateRequest("posts", "doc", "2")
  5. .doc(XContentType.JSON, "other", "test"));
  6. // 添加 一个使用SMILE格式的IndexRequest
  7. request.add(new IndexRequest("posts", "doc", "4")
  8. .source(XContentType.SMILE, "field", "baz"));

可选参数

  1. //设置超时,等待批处理被执行的超时时间(使用TimeValue形式)
  2. request.timeout(TimeValue.timeValueMinutes(2));
  3. //设置超时,等待批处理被执行的超时时间(字符串形式)
  4. request.timeout("2m");
  1. //刷新策略
  2. request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);//WriteRequest.RefreshPolicy实例方式
  3. request.setRefreshPolicy("wait_for");//字符串方式
  1. //设置在执行索引/更新/删除操作之前必须处于活动状态的分片副本数。
  2. request.waitForActiveShards(2);
  3. //使用ActiveShardCount方式来提供分片副本数:可以是ActiveShardCount.ALL,ActiveShardCount.ONE或ActiveShardCount.DEFAULT(默认)
  4. request.waitForActiveShards(ActiveShardCount.ALL);

同步执行

  1. BulkResponse bulkResponse = client.bulk(request);

异步执行

批量请求的异步执行需要将BulkRequest实例和ActionListener实例传递给异步方法:

  1. //当BulkRequest执行完成时,ActionListener会被调用
  2. client.bulkAsync(request, listener);

异步方法不会阻塞并会立即返回。完成后,如果执行成功完成,则使用onResponse方法回调ActionListener,如果失败则使用onFailure方法。
BulkResponse 的典型监听器如下所示:

  1. ActionListener<BulkResponse> listener = new ActionListener<BulkResponse>() {
  2. @Override
  3. public void onResponse(BulkResponse bulkResponse) {
  4. //执行成功完成时调用。 response作为参数提供,并包含已执行的每个操作的单个结果列表。 请注意,一个或多个操作可能已失败,然而其他操作已成功执行。
  5. }
  6.  
  7. @Override
  8. public void onFailure(Exception e) {
  9. //在整个BulkRequest失败时调用。 在这种情况下,exception作为参数提供,并且没有执行任何操作。
  10. }
  11. };

Bulk Response

返回的BulkResponse包含有关已执行操作的信息,并允许迭代每个结果,如下所示:

  1.     //遍历所有操作结果
  2. for (BulkItemResponse bulkItemResponse : bulkResponse) {
  3. //获取操作的响应,可以是IndexResponse,UpdateResponse或DeleteResponse,
  4. // 它们都可以被视为DocWriteResponse实例
  5. DocWriteResponse itemResponse = bulkItemResponse.getResponse();
  6.  
  7. if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.INDEX
  8. || bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE) {
  9. //处理index操作
  10. IndexResponse indexResponse = (IndexResponse) itemResponse;
  11.  
  12. } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.UPDATE) {
  13. //处理update操作
  14. UpdateResponse updateResponse = (UpdateResponse) itemResponse;
  15.  
  16. } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.DELETE) {
  17. //处理delete操作
  18. DeleteResponse deleteResponse = (DeleteResponse) itemResponse;
  19. }
  20. }

批量响应提供了用于快速检查一个或多个操作是否失败的方法:

  1. if (bulkResponse.hasFailures()) {
  2. //该方法只要有一个操作失败都会返回true
  3. }

如果想要查看操作失败的原因,则需要遍历所有操作结果:

  1. for (BulkItemResponse bulkItemResponse : bulkResponse) {
  2. if (bulkItemResponse.isFailed()) {//判断当前操作是否失败
  3. //获取失败对象,拿到了failure对象,想怎么玩都行
  4. BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
  5. }
  6. }

Bulk Processor

BulkProcessor通过提供一个工具类来简化Bulk API的使用,允许索引/更新/删除操作在添加到处理器后透明地执行。

为了执行请求,BulkProcessor需要以下组件:

RestHighLevelClient
此客户端用于执行BulkRequest并获取BulkResponse
BulkProcessor.Listener
在每次BulkRequest执行之前和之后或BulkRequest失败时调用此监听器
然后BulkProcessor.builder方法可用于构建新的BulkProcessor:

  1. //创建BulkProcessor.Listener
  2. BulkProcessor.Listener listener1 = new BulkProcessor.Listener() {
  3. @Override
  4. public void beforeBulk(long executionId, BulkRequest request) {
  5. //在每次执行BulkRequest之前调用此方法
  6. }
  7.  
  8. @Override
  9. public void afterBulk(long executionId, BulkRequest request,BulkResponse response) {
  10. //在每次执行BulkRequest之后调用此方法
  11. }
  12.  
  13. @Override
  14. public void afterBulk(long executionId, BulkRequest request, Throwable failure) {
  15. //执行BulkRequest失败时调用此方法
  16. }
  17. };
  18.      //通过从BulkProcessor.Builder调用build()方法来创建BulkProcessor。
  19.      //RestHighLevelClient.bulkAsync()方法将用来执行BulkRequest。
  20. BulkProcessor bulkProcessor = BulkProcessor.builder(client::bulkAsync, listener1).build();

BulkProcessor.Builder提供了配置BulkProcessor应如何处理请求执行的方法:

  1. BulkProcessor.Builder builder = BulkProcessor.builder(client::bulkAsync, listener1);
  2. //设置何时刷新新的批量请求,根据当前已添加的操作数量(默认为1000,使用-1禁用它)
  3. builder.setBulkActions(500);//操作数为500时就刷新请求
  4. //设置何时刷新新的批量请求,根据当前已添加的操作大小(默认为5Mb,使用-1禁用它)
  5. builder.setBulkSize(new ByteSizeValue(1L, ByteSizeUnit.MB));//操作大小为1M时就刷新请求
  6. //设置允许执行的并发请求数(默认为1,使用0只允许执行单个请求)
  7. builder.setConcurrentRequests(0);//不并发执行
  8. //设置刷新间隔时间,如果超过了间隔时间,则随便刷新一个BulkRequest挂起(默认为未设置)
  9. builder.setFlushInterval(TimeValue.timeValueSeconds(10L));
  10. //设置一个最初等待1秒,最多重试3次的常量退避策略。
  11. // 有关更多选项,请参阅BackoffPolicy.noBackoff(),BackoffPolicy.constantBackoff()和BackoffPolicy.exponentialBackoff()。
  12. builder.setBackoffPolicy(BackoffPolicy.constantBackoff(TimeValue.timeValueSeconds(1L), 3));

创建BulkProcessor后,就可以向其添加请求了:

  1. IndexRequest one = new IndexRequest("posts", "doc", "1").
  2. source(XContentType.JSON, "title",
  3. "In which order are my Elasticsearch queries executed?");
  4. IndexRequest two = new IndexRequest("posts", "doc", "2")
  5. .source(XContentType.JSON, "title",
  6. "Current status and upcoming changes in Elasticsearch");
  7. IndexRequest three = new IndexRequest("posts", "doc", "3")
  8. .source(XContentType.JSON, "title",
  9. "The Future of Federated Search in Elasticsearch");
  10.  
  11. bulkProcessor.add(one);
  12. bulkProcessor.add(two);
  13. bulkProcessor.add(three);

这些请求将由BulkProcessor执行,BulkProcessor负责为每个批量请求调用BulkProcessor.Listener。
侦听器提供访问BulkRequest和BulkResponse的方法:

  1.        BulkProcessor.Listener listener = new BulkProcessor.Listener() {
  2. @Override
  3. public void beforeBulk(long executionId, BulkRequest request) {
  4. //在每次执行BulkRequest之前调用,通过此方法可以获取将在BulkRequest中执行的操作数
  5. int numberOfActions = request.numberOfActions();
  6. logger.debug("Executing bulk [{}] with {} requests",
  7. executionId, numberOfActions);
  8. }
  9.  
  10. @Override
  11. public void afterBulk(long executionId, BulkRequest request, BulkResponse response) {
  12. //在每次执行BulkRequest后调用,通过此方法可以获取BulkResponse是否包含错误
  13. if (response.hasFailures()) {
  14. logger.warn("Bulk [{}] executed with failures", executionId);
  15. } else {
  16. logger.debug("Bulk [{}] completed in {} milliseconds",
  17. executionId, response.getTook().getMillis());
  18. }
  19. }
  20.  
  21. @Override
  22. public void afterBulk(long executionId, BulkRequest request, Throwable failure) {
  23. //如果BulkRequest失败,通过调用此方法可以获取失败
  24. logger.error("Failed to execute bulk", failure);
  25. }
  26. };

将所有请求添加到BulkProcessor后,需要使用两种可用的关闭方法之一关闭其实例。

awaitClose()方法可用于等待所有请求都已处理或过了指定的等待时间:

  1. boolean terminated = bulkProcessor.awaitClose(30L, TimeUnit.SECONDS);

如果所有批量请求都已完成,则该方法返回true;如果在所有批量请求完成之前等待时间已过,则返回false

close()方法可用于立即关闭BulkProcessor:

  1. bulkProcessor.close();

两种方法在关闭处理器之前会刷新已添加到处理器的请求,并且还会禁止将任何新请求添加到处理器。

官方文档:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-bulk.html#_optional_arguments_4

Bulk API的更多相关文章

  1. Elasticsearch批处理操作——bulk API

    Elasticsearch提供的批量处理功能,是通过使用_bulk API实现的.这个功能之所以重要,在于它提供了非常高效的机制来尽可能快的完成多个操作,与此同时使用尽可能少的网络往返. 1.批量索引 ...

  2. Salesforce Bulk API 基于.Net平台下的实施

    在最近的salesforce实施项目中应用到Bulk API来做数据接口.顺便把实际应用的例子写下来.希望对做salesforce接口的朋友有借鉴作用. 一 参考网络牛人写好的Demo. 下载地址:h ...

  3. elasticsearch6.7 05. Document APIs(9)Bulk API

    8.Bulk API 可以把多个index或delete操作放在单个bulk API中执行.这样可以极大地提高索引速度. /_bulkAPI使用如下的JSON结构: action_and_meta_d ...

  4. ElasticSearch(十三) bulk api奇特的json格式的原因

    bulk api的语法 正常的语法: {"action": {"meta"}}\n {"data"}\n {"action&quo ...

  5. ElasticSearch Bulk API

    做一个简单的记录,以便自己后续查找 一.环境要求 ElasticSearch 7.3.0 Kibana 7.3.0 二.详情 ElasticSearch 的 Bulk API 可以批量进行索引或者删除 ...

  6. Elasticsearch由浅入深(六)批量操作:mget批量查询、bulk批量增删改、路由原理、增删改内部原理、document查询内部原理、bulk api的奇特json格式

    mget批量查询 批量查询的好处就是一条一条的查询,比如说要查询100条数据,那么就要发送100次网络请求,这个开销还是很大的如果进行批量查询的话,查询100条数据,就只要发送1次网络请求,网络请求的 ...

  7. elasticsearch 中文API bulk(六)

    bulk API bulk API允许开发者在一个请求中索引和删除多个文档.下面是使用实例. import static org.elasticsearch.common.xcontent.XCont ...

  8. elasticsearch中常用的API

    elasticsearch中常用的API分类如下: 文档API: 提供对文档的增删改查操作 搜索API: 提供对文档进行某个字段的查询 索引API: 提供对索引进行操作,查看索引信息等 查看API: ...

  9. elasticsearch中的API

    elasticsearch中的API es中的API按照大类分为下面几种: 文档API: 提供对文档的增删改查操作 搜索API: 提供对文档进行某个字段的查询 索引API: 提供对索引进行操作 查看A ...

随机推荐

  1. 前端笔记知识点整合之JavaScript(三)关于条件判断语句、循环语句那点事

      一.条件分支语句 条件分支语句,也叫作条件判断语句,就是根据某种条件执行某些语句,不执行某些语句. JS中有三种语法是可以表示条件分支的 1.1 if……else…… 条件分支的主力语法,这个主力 ...

  2. mingw-gcc-8.3.0-i686-posix-sjlj

    网上无法找到 gcc-8.3.0 的 posix 版本, 所以自己编译了这个版本 gcc -v Using built-in specs. COLLECT_GCC=d:\msys\mingw\bin\ ...

  3. IDEA内的SpringBoot插件安装与SpringBoot项目生成地址

    最新安装idea,在新建项目时没有spring initializr选项,也没有spring assistant选项.因此需要安装相应插件 在菜单栏 file>>settings>& ...

  4. USB鼠标键盘数据格式以及按键键值

    鼠标发送给PC的数据每次4个字节 BYTE1 BYTE2 BYTE3 BYTE4 定义分别是: BYTE1 --        |--bit7:   1   表示   Y   坐标的变化量超出-256 ...

  5. 使用requests+pyquery爬取dd373地下城跨五最新商品信息

    废话不多说直接上代码: 可以使用openpyel库对爬取的信息写入Execl表格中代码我就不上传了 import requests from urllib.parse import urlencode ...

  6. Linux 常用命令介绍

    介绍常用命令,在忘记时便于即使查询 复制.移动.删除     cp.mv.rm.pwd 1. CP 介绍 用法:CP [-adfilprsu]  源文件  目标文件 参数:参数说明: -a:是指arc ...

  7. Java中三种代理模式

    代理模式 代理(Proxy)是一种设计模式,提供了间接对目标对象进行访问的方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的功能上,增加额外的功能补充,即扩展目标对象的功能. 这就 ...

  8. tomcat配置文件及性能优化

    收藏两个地址 配置文件: https://www.cnblogs.com/sunshine-1/p/8990044.html 性能调优: https://www.cnblogs.com/zhuawan ...

  9. 【webpack系列】从零搭建 webpack4+react 脚手架(一)

    搭建一个React工程的方式有很多,官方也有自己的脚手架,如果你和我一样,喜欢刨根究底,从零开始自己一行一行代码创建一个React脚手架项目,那你就来对地方了.本教程是针对React新手,以及对web ...

  10. java文件过滤器的使用

    前言: java.io.FileFilter(过滤器接口)boolean accept(File pathname) File类提供了如下方法使用过滤器:public File[] listFiles ...