内容简介:{"action": {"meta"}}n{"data"}n{"action": {"meta"}}n
bulk api奇特的json格式
{"action": {"meta"}}n
{"data"}n
{"action": {"meta"}}n
{"data"}n
...
为什么bulk要采用这种奇特的json格式?
由于bulk中的每个操作都可能要转发到不同的node的shard去执行,假设我们不用这种奇特的json格式,采用比较良好的json数组格式,允许任意的换行,整个可读性非常棒,读起来很爽。但是ES拿到这种标准格式的json串之后,要按照下述流程去进行执行处理。
格式如下:
[
{
"action": { }, "data": { }
}
]
(1)将json数组解析为JSONArray对象,这个时候,整个数据,就会在内存中出现一份一摸一样的拷贝,一份数据是json文本,一份数据是JSONArray对象
(2)解析json数组里面的每个json,对每个请求中的document进行路由
(3)为路由到同一个shard上的多个请求,创建一个请求数组
(4)将这个请求数组序列化
(5)将序列化后的请求数组发送到对应的节点上去
不难看出这样就会耗费更多的内存,更多的jvm gc开销。
假设一个场景,对于bulk size的大小一般建议在几千条,大小在10MB左右,所以说,可怕的事情来了。假设说现在100个bulk请求发送到了一个节点上去,然后每个请求是10MB,100个请求就是1000MB=1G,然后每个请求的json都copy一份JSONArray对象,此时内存中的占用就会翻倍,就会占用2GB的内存,甚至还不止,因为弄成JSONArray对象之后,还可能会多弄一些其它的数据结构,2GB+的内存占用。
占用更多的内存可能就会积压其它请求的内存使用量,比如说最重要的搜索请求,分析请求等等。此时就可能会导致其它请求的性能急速下降,另外的话,占用内存更多,就会导致 java 虚拟机的垃圾回收次数更多,更加频繁,每次要回收的垃圾对象更多,耗费的时间更多,导致ES的java虚拟机停止工作线程的时间更多。
而使用这个奇特格式的json
{"action": {"meta"}}n
{"data"}n
{"action": {"meta"}}n
{"data"}n
...
(1)不用将其转换为json对象,不会出现内存中的相同数据的拷贝,直接按照换行符切割json
(2)对每两个一组的json,读取meta,进行document路由
(3)直接将对应的json发送到node上去
和标准格式的json相比,最大的优势在于不需要将json数组解析为一个JSONArray对象,形成一份大数据的拷贝,浪费内存空间,尽可能的保证性能。
实战:
PUT _bulk {"index": {"_index": "test", "_id": "1"}} {"field1": "value1", "field2": "value2"} {"index": {"_index": "test", "_id": "2"}} {"field1": "value1 id2", "field2": "value2 id2"} {"delete": {"_index": "test", "_id": "2"}} {"create": {"_index": "test", "_id": "3"}} {"field1": "value3"} {"update": {"_index": "test", "_id": "1"}} {"doc": {"field2": "value2"}} { "took" : 68, "errors" : true, "items" : [ { "index" : { "_index" : "test", "_type" : "_doc", "_id" : "1", "_version" : 2, "result" : "updated", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 4, "_primary_term" : 1, "status" : 200 } }, { "index" : { "_index" : "test", "_type" : "_doc", "_id" : "2", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 5, "_primary_term" : 1, "status" : 201 } }, { "delete" : { "_index" : "test", "_type" : "_doc", "_id" : "2", "_version" : 2, "result" : "deleted", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 6, "_primary_term" : 1, "status" : 200 } }, { "create" : { "_index" : "test", "_type" : "_doc", "_id" : "3", "status" : 409, "error" : { "type" : "version_conflict_engine_exception", "reason" : "[3]: version conflict, document already exists (current version [1])", "index_uuid" : "rOLJZzIVTDCWtDQcJuei6w", "shard" : "0", "index" : "test" } } }, { "update" : { "_index" : "test", "_type" : "_doc", "_id" : "1", "_version" : 2, "result" : "noop", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "status" : 200 } } ] }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 云计算底层技术之高性能集群趣谈
- FISCO BCOS v2.0.0-rc3 发布,底层平台性能优化
- FISCO BCOS v2.0.0-rc3 发布,底层平台性能优化
- JavaScript是如何工作的: CSS 和 JS 动画底层原理及如何优化它们的性能
- 基于 Swoole 构建高性能 Laravel 应用系列 —— 基于 Swoole 实现协程篇(一):基本概念和底层原理
- avue 1.5.2 优化大量底层代码,crud 和 form 底层公用
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入Linux内核架构
Wolfgang Mauerer / 郭旭 / 人民邮电出版社 / 201005 / 149.00元
众所周知,Linux操作系统的源代码复杂、文档少,对程序员的要求高,要想看懂这些代码并不是一件容易事。本书结合内核版本2.6.24源代码中最关键的部分,深入讨论Linux内核的概念、结构和实现。具体包括进程管理和调度、虚拟内存、进程间通信、设备驱动程序、虚拟文件系统、网络、时间管理、数据同步等方面的内容。本书引导你阅读内核源代码,熟悉Linux所有的内在工作机理,充分展现Linux系统的魅力。 ......一起来看看 《深入Linux内核架构》 这本书的介绍吧!