es⼤批量写⼊提⾼性能的策略
1、⽤bulk批量写⼊
你如果要往es⾥⾯灌⼊数据的话,那么根据你的业务场景来,如果你的业务场景可以⽀持让你将⼀批数据聚合起来,⼀次性写⼊es,那么就尽量采⽤bulk的⽅式,每次批量写个⼏百条这样⼦。
bulk批量写⼊的性能⽐你⼀条⼀条写⼊⼤量的document的性能要好很多。但是如果要知道⼀个bulk请求最佳的⼤⼩,需要对单个es node的单个shard做压测。先bulk写⼊100个document,然后200个,400个,以此类推,每次都将bulk size加倍⼀次。如果bulk 写⼊性能开始变平缓的时候,那么这个就是最佳的bulk⼤⼩。并不是bulk size越⼤越好,⽽是根据你的集等环境具体要测试出来的,因为越⼤的bulk size会导致内存压⼒过⼤,因此最好⼀个请求不要发送超过10mb的数据量。
先确定⼀个是bulk size,此时就尽量是单线程,⼀个es node,⼀个shard,进⾏测试。看看单线程最多⼀次性写多少条数据,性能是⽐较好的。
curl是什么命令2、使⽤多线程将数据写⼊es
单线程发送bulk请求是⽆法最⼤化es集写⼊的吞吐量的。如果要利⽤集的所有资源,就需要使⽤多线程并发将数据bulk写⼊集中。为了更好的利⽤集的资源,这样多线程并发写⼊,可以减少每次底
层磁盘fsync的次数和开销。⾸先对单个es节点的单个shard 做压测,⽐如说,先是2个线程,然后是4个线程,然后是8个线程,16个,每次线程数量倍增。⼀旦发现es返回了
TOO_MANY_REQUESTS的错误,JavaClient也就是EsRejectedExecutionException。此时那么就说明es是说已经到了⼀个并发写⼊的最⼤瓶颈了,此时我们就知道最多只能⽀撑这么⾼的并发写⼊了。
3、增加refresh间隔
默认的refresh间隔是1s,⽤fresh_interval参数可以设置,这样会其强迫es每秒中都将内存中的数据写⼊磁盘中,创建⼀个新的segment file。正是这个间隔,让我们每次写⼊数据后,1s以后才能看到。但是如果我们将这个间隔调⼤,⽐如30s,可以接受写⼊的数据30s后才看到,那么我们就可以获取更⼤的写⼊吞吐量,因为30s内都是写内存的,每隔30s才会创建⼀个segment file。
4、禁⽌refresh和replia
如果我们要⼀次性加载⼤批量的数据进es,可以先禁⽌refresh和replia复制,将fresh_interval设置为-1,将
index.number_of_replicas设置为0即可。这可能会导致我们的数据丢失,因为没有refresh和replica机制了。但是不需要创建segment file,也不需要将数据replica复制到其他的replica shasrd上⾯去。此时
写⼊的速度会⾮常快,⼀旦写完之后,可以将refresh和replica修改回正常的状态。
5、禁⽌swapping交换内存
如果要将es jvm内存交换到磁盘,再交换回内存,⼤量磁盘IO,性能很差
6、给filesystem cache更多的内存
filesystem cache被⽤来执⾏更多的IO操作,如果我们能给filesystemcache更多的内存资源,那么es的写⼊性能会好很多。
7、使⽤⾃动⽣成的id
如果我们要⼿动给es document设置⼀个id,那么es需要每次都去确认⼀下那个id是否存在,这个过程是⽐较耗费时间的。如果我们使⽤⾃动⽣成的id,那么es就可以跳过这个步骤,写⼊性能会更好。对于你的业务中的表id,可以作为es document的⼀个field。
8、⽤性能更好的硬件
我们可以给filesystem cache更多的内存,也可以使⽤SSD替代机械硬盘,避免使⽤NAS等⽹络存储,考虑使⽤RAID 0来条带化存储提升磁盘并⾏读写效率,等等。
9、index buffer
如果我们要进⾏⾮常重的⾼并发写⼊操作,那么最好将index buffer调⼤⼀些,index_buffer_size,这个可以调节⼤⼀些,设置的这个index buffer⼤⼩,是所有的shard公⽤的,但是如果除以shard数量以后,算出来平均每个shard可以使⽤的内存⼤⼩,⼀般建议,但是对于每个shard来说,最多给512mb,因为再⼤性能就没什么提升了。es会将这个设置作为每个shard共享的index buffer,那些特别活跃的shard会更多的使⽤这个buffer。默认这个参数的值是10%,也就是jvm heap的10%,如果我们给jvmheap分配10gb内存,那么这个index buffer就有1gb,对于两个shard共享来说,是⾜够的了。
10、json⽂件导⼊
⽤REST API的_bulk来批量插⼊,可以达到5到10w条每秒,这⽅法是先定义⼀定格式的json⽂件,然后再⽤curl命令去执⾏Elasticsearch的_bulk来批量插⼊,所以得把数据写进json⽂件,然后再通过批处理,执⾏⽂件插⼊数据,另外在⽣成json⽂件,⽂件不能过⼤,过⼤会报错,所以建议⽣成10M⼀个⽂件,然后分别去执⾏这些⼩⽂件就可以了
json数据⽂件内容的定义
{"index":{"_index":"meterdata","_type":"autoData"}}
{"Mfid ":1,"TData":172170,"TMoney":209,"HTime":"2016-05-17T08:03:00"}
{"index":{"_index":"meterdata","_type":"autoData"}}
{"Mfid ":1,"TData":172170,"TMoney":209,"HTime":"2016-05-17T08:04:00"}
cd E:\curl-7.50.3-win64-mingw\bin
curl 172.17.1.15:9200/_bulk?pretty --data-binary @E:\Bin\Debug\testdata\437714060.json
批处理内容的定义
cd E:\curl-7.50.3-win64-mingw\bin
curl 172.17.1.15:9200/_bulk?pretty --data-binary @E:\Bin\Debug\testdata\437714060.json

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。