Elasticsearch Document Bulk API详解、原理与示例

   Bulk API可以在一次API调用中包含多个索引操作,例如更新索引,删除索引等,相当于批量操作。
   详细API如下:

  • public final BulkResponse bulk(BulkRequest bulkRequest, RequestOptions options) throws IOException
  • public final void bulkAsync(BulkRequest bulkRequest, RequestOptions options, ActionListener listener)

1、BulkRequest详解
在这里插入图片描述
   我们先一一来看一下其 核心属性与与典型方法:

  • final List requests = new ArrayList<>():单个命令容器,DocWriteRequest的子类包括:IndexRequest、UpdateRequest、DeleteRequest。
  • private final Set indices = new HashSet<>():List requests涉及到的索引。
    List payloads = null:有效载荷,6.4.0版本,貌似该字段意义不大,通常命令的请求体(负载数据)存放在DocWriteRequest对象中,例如IndexRequest的source字段。
  • protected TimeValue timeout = BulkShardRequest.DEFAULT_TIMEOUT:timeout机制,针对一个Bulk请求生效。
  • private ActiveShardCount waitForActiveShards = ActiveShardCount.DEFAULT: waitForActiveShards,针对一个Bulk请求生效,各个请求中waitForActiveShards优先。
  • private RefreshPolicy refreshPolicy = RefreshPolicy.NONE:刷新策略。
  • private long sizeInBytes = 0:整个Bulk请求的大小。

通过add api为BulkRequest添加一个请求。

2、Bulk API请求格式详解
   Bulk Rest请求协议基于如下格式:

POST _bulk
{ "index" : { "_index" : "test", "_type" : "_doc", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_type" : "_doc", "_id" : "2" } }
{ "create" : { "_index" : "test", "_type" : "_doc", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_type" : "_doc", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }

   其请求格式定义如下(restfull):

  • POST请求,其Content-Type为application/x-ndjson。
  • 每一个命令占用两行,每行的结束字符为\r\n。
  • 第一行为元数据,“opType” : {元数据}。
  • 第二行为有效载体(非必选),例如Index操作,其有效载荷为IndexRequest#source字段。
  • opType可选值 index、create、update、delete。

   公用元数据(index、create、update、delete)如下
      1)_index :索引名
      2)_type:类型名
      3)_id:文档ID
      4)routing:路由值
      5)parent
      6)version:数据版本号
      7)version_type:版本类型
   各操作特有元数据
   1、index | create
      1)pipeline
   2、update
      1)retry_on_conflict :更新冲突时重试次数。
      2)_source:字段过滤。
   有效载荷说明
   1、index | create
   其有效载荷为_source字段。
   2、update
   其有效载荷为:partial doc, upsert and script。
   3、delete
   没有有效载荷。
   对请求格式为什么要设计成metdata+有效载体的方式,主要是为了在接受端节点(所谓的接受端节点是指收到命令的第一节点),只需解析 metadata,然后将请求直接转发给对应的数据节点。

3、bulk API通用特性分析
3.1 版本管理
   每一个Bulk条目拥有独自的version,存在于请求条目的item的元数据中。

3.2 路由
   每一个Bulk条目各自生效。

3.3 Wait For Active Shards
   通常可以设置BulkRequest#waitForActiveShards来要求Bulk批量执行之前要求处于激活的最小副本数。

4、Bulk Demo

public static final void testBulk() {
		RestHighLevelClient client = EsClient.getClient();
		try {
			IndexRequest indexRequest = new IndexRequest("twitter", "_doc", "12")
					.source(buildTwitter("dingw", "2009-11-18T14:12:12", "test bulk"));
			UpdateRequest updateRequest = new UpdateRequest("twitter", "_doc", "11")
						.doc(new IndexRequest("twitter", "_doc", "11")
								.source(buildTwitter("dingw", "2009-11-18T14:12:12", "test bulk update")));
			BulkRequest request = new BulkRequest();
			request.add(indexRequest);
			request.add(updateRequest);
			BulkResponse bulkResponse = client.bulk(request, RequestOptions.DEFAULT);
			for (BulkItemResponse bulkItemResponse : bulkResponse) { 
				if (bulkItemResponse.isFailed()) { 
                    BulkItemResponse.Failure failure = bulkItemResponse.getFailure(); 
                    System.out.println(failure);
                    continue;
                }
                DocWriteResponse itemResponse = bulkItemResponse.getResponse(); 
                if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.INDEX
                        || bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE) { 
                    IndexResponse indexResponse = (IndexResponse) itemResponse;
                    System.out.println(indexRequest);
                } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.UPDATE) {
                    UpdateResponse updateResponse = (UpdateResponse) itemResponse;
                    System.out.println(updateRequest);
                } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.DELETE) { 
                    DeleteResponse deleteResponse = (DeleteResponse) itemResponse;
                    System.out.println(deleteResponse);
                }
            }
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			EsClient.close(client);
		}
	}

批量更新bulk api就介绍到这里了。


见文如面,我是威哥,热衷于成体系剖析JAVA主流中间件,关注公众号『中间件兴趣圈』,回复专栏可获取成体系专栏导航,回复资料可以获取笔者的学习思维导图。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

中间件兴趣圈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值