elasticsearch调优技巧

标签: elasticsearch
836人阅读 评论(0) 收藏 举报
分类:

elasticsearch 性能调优

所有的修改都可以在elasticsearch.yml里面修改,也可以通过api来修改。推荐用api比较灵活
1.不同分片之间的数据同步是一个很大的花费,默认是1s同步,如果我们不要求实时性,我们可以执行如下:
复制代码
$ curl -XPUT 'http://localhost:9200/twitter/' -d '{
    "settings" : {
        "index" : {
         "refresh_interval":"60s"
        }
    }
}'
复制代码

 此处我们是修改为60s 其实可以改为-1s  这样就是不刷新,我们需要在查询的时候进行一次索引刷新然后再查询,这个嘛就得看你们用户能容忍多少时间长度了。

2.选择正确的存储
       一般来说,如果运行的是64位操作系统,你应该选择mmapfs。如果没有运行64位操作系统,为UNIX系统选择niofs,为Windows系统选择simplefs。如果你可以容忍一个易失的存储,但希望它非常快,可以看看memory存储,它会给你最好的索引访问性能,但需要足够的内存来处理所有索引文件、索引和查询。
3.优化es的线程池 
cache:这是无限制的线程池,为每个传入的请求创建一个线程。
fixed:这是一个有着固定大小的线程池,大小由size属性指定,允许你指定一个队列(使用queue_size属性指定)用来保存请求,直到有一个空闲的线程来执行请求。如果Elasticsearch无法把请求放到队列中(队列满了),该请求将被拒绝。有很多线程池(可以使用type属性指定要配置的线程类型),然而,对于性能来说,最重要的是下面几个。
index:此线程池用于索引和删除操作。它的类型默认为fixed,size默认为可用处理器的数量,队列的size默认为300。
search:此线程池用于搜索和计数请求。它的类型默认为fixed,size默认为可用处理器的数量乘以3,队列的size默认为1000。
suggest:此线程池用于建议器请求。它的类型默认为fixed,size默认为可用处理器的数量,队列的size默认为1000。
get:此线程池用于实时的GET请求。它的类型默认为fixed,size默认为可用处理器的数量,队列的size默认为1000。
bulk:你可以猜到,此线程池用于批量操作。它的类型默认为fixed,size默认为可用处理器的数量,队列的size默认为50。
percolate:此线程池用于预匹配器操作。它的类型默认为fixed,size默认为可用处理器的数量,队列的size默认为1000。
elasticsearch.yml中可以设置 :
threadpool.index.type: fixed
threadpool.index.size: 100
threadpool.index.queue_size: 500
当然可以restAPI设置
复制代码
curl -XPUT 'localhost:9200/_cluster/settings' -d '{
    "transient": {
        "threadpool.index.type": "fixed",
        "threadpool.index.size": 100,
        "threadpool.index.queue_size": 500
    }
}'
复制代码

 

4.index过于庞大导致es经常奔溃

    es最近老是挂掉,无缘无故,表现症状为 对于大小超过100g的index(5个分片 1e数据量左右)插入超级慢,由于机器资源有限 ,只能想出 将每一天的数据建立一个index+“yyyy-MM-dd” 这样可以有效缓解我们集群的压力,有人会说如果改成这种方案那么之前写的查询岂不是废了,其实很easy,es支持index通配符 比如你之前是logment  现在是logment2015-05-01和logment2015-05-02  现在只需要将查询的代码中index改为 logment* 就ok了 ,而且此法便于删除过期的index 写一个定时任务就ok了 
    我们日志的架构是这样的 logstash(client1) 采集日志到 redis  然后通过 logstash(client2) 从redis转至 elasticsearch ,logstash写入elasticsearch的时候默认就是按照每天来建立索引的 在其配置文件无需指明 index和type 即可。 

    此处会产生一个问题,就是logstash 自动建立索引的时候是根据格林尼治时间来建立的 正正比我们的时间 迟了8小时,我们需要在logstash的lib里面找到event.rb  然后找到 org.joda.time.DateTimeZone.UTC 格林尼治时间  改成 org.joda.time.DateTimeZone.getDefault() (获取本地时间类型 我这边运行就是中国/上海) 即可  话说logstash用的居然是大名鼎鼎的joda 果然是优秀程序 。

5. 采用G1垃圾回收机制代替默认CMS

    这里我不分析cms和g1的细节区别,大内存(超过8g)下G1还是很给力的,亲测有效,用了G1 一周内一次FULLGC 都没有,哈哈

    elasticsearch.in.sh 内 将

1
2
3
4
5
6
7
8
9
10
# Force the JVM to use IPv4 stack
if "x$ES_USE_IPV4" != "x" ]; then
  JAVA_OPTS="$JAVA_OPTS -Djava.net.preferIPv4Stack=true"
fi
 
JAVA_OPTS="$JAVA_OPTS -XX:+UseParNewGC"
JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC"
 
JAVA_OPTS="$JAVA_OPTS -XX:CMSInitiatingOccupancyFraction=75"
JAVA_OPTS="$JAVA_OPTS -XX:+UseCMSInitiatingOccupancyOnly"

  替换为

1
2
JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC"
JAVA_OPTS="$JAVA_OPTS -XX:MaxGCPauseMillis=200"

  大功告成

      顺便说句JVM调优,调优最主要目标:1.就是降低 GC 次数时间;2.降低FULLGC 几率

      PS:优化代码比优化JVM实在多了

6. 清理掉没用的缓存

   回忆之前的问题发现jvm调优对于老年代的回收并没有很显著的效果,随着时间的推移内存还是不够~后来才发现是es cache的问题

 其实集群建立时我们是可以调整每隔节点的缓存比例、类型、者大小的

   

复制代码
# 锁定内存,不让JVM写入swapping,避免降低ES的性能
bootstrap.mlockall: true
# 缓存类型设置为Soft Reference,只有当内存不够时才会进行回收
index.cache.field.max_size: 50000
index.cache.field.expire: 10m
index.cache.field.type: soft
复制代码

   但是如果你不想重新配置节点并且重启,你可以做一个定时任务来定时清除cache 

http://10.22.2.201:9200/*/_cache/clear  //清除所有索引的cache,如果对查询有实时性要求,慎用!

   到了晚上资源空闲的时候我们还能合并优化一下索引

http://10.22.2.201:9200/*/_optimize

  

   截止现在我们es集群有38亿左右数据量,比较稳定

三、线程池类型

1、cached

无限制的线程池,为每个请求创建一个线程。这种线程池是为了防止请求被阻塞或者拒绝,其中的每个线程都有一个超时时间(keep_alive),默认5分钟,一旦超时就会回收/终止。elasticsearch的generic线程池就是用该类型。最近发现5.0.0-alpha2版本中去掉了该类型的线程池。

[html] view plain copy
  1. threadpool:  
  2.     generic:  
  3.         keep_alive: 2m  

2、fixed

有着固定大小的线程池,大小由size属性指定,默认是5*cores数,允许你指定一个队列(使用queue_size属性指定,默认是-1,即无限制)用来保存请求,直到有一个空闲的线程来执行请求。如果Elasticsearch无法把请求放到队列中(队列满了),该请求将被拒绝。

[html] view plain copy
  1. threadpool:  
  2.     index:  
  3.         size: 30  
  4.         queue_size: 1000  

3、scaling

可变大小的pool,大小根据负载在1到size间,同样keep_alive参数指定了闲置线程被回收的时间。

[html] view plain copy
  1. threadpool:  
  2.     warmer:  
  3.         size: 8  
  4.         keep_alive: 2m  

四、修改线程池配置

1、elasticsearch.yml

[html] view plain copy
  1. threadpool.index.type: fixed  
  2. threadpool.index.size: 100  
  3. threadpool.index.queue_size: 500  

2、Rest API

[html] view plain copy
  1. curl -XPUT 'localhost:9200/_cluster/settings' -d '{  
  2.     "transient": {  
  3.         "threadpool.index.type": "fixed",  
  4.         "threadpool.index.size": 100,  
  5.         "threadpool.index.queue_size": 500  
  6.     }  
  7. }'  


五、bulk异常排查

使用es bulk api时报错如下

[html] view plain copy
  1. EsRejectedExcutionException[rejected execution(queue capacity 50) on.......]  
这个错误明显是默认大小为50的队列(queue)处理不过来了,解决方法是增大bulk队列的长度

elasticsearch.yml

[html] view plain copy
  1. threadpool.bulk.queue_size: 1000  


六、总结

Elasticsearch的线程池其实就是对java自带的进行封装,虽然用户可以更改相关配置,但官方强烈不建议去修改默认值,关于为什么,可以阅读下面第三篇文章。



相关文档

https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-nodes-stats.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-threadpool.html

https://www.elastic.co/guide/en/elasticsearch/guide/current/_don_8217_t_touch_these_settings.html#_threadpools


cluster.name: estest   集群名称
node.name: “testanya”  节点名称

node.master: false  是否主节点
node.data: true   是否存储数据

index.store.type: niofs 读写文件方式 
index.cache.field.type: soft 缓存类型

bootstrap.mlockall: true 禁用swap

gateway.type: local 本地存储

gateway.recover_after_nodes: 3 3个数据节点开始恢复

gateway.recover_after_time: 5m 5分钟后开始恢复数据

gateway.expected_nodes: 4 4个es节点开始恢复

cluster.routing.allocation.node_initial_primaries_recoveries:8 并发恢复分片数 
cluster.routing.allocation.node_concurrent_recoveries:2 同时recovery并发数

indices.recovery.max_bytes_per_sec: 250mb 数据在节点间传输最大带宽 
indices.recovery.concurrent_streams: 8 同时读取数据文件流线程

discovery.zen.ping.multicast.enabled: false 禁用多播 
discovery.zen.ping.unicast.hosts:[“192.168.169.11:9300”, “192.168.169.12:9300”]

discovery.zen.fd.ping_interval: 10s 节点间存活检测间隔 
discovery.zen.fd.ping_timeout: 120s 存活超时时间 
discovery.zen.fd.ping_retries: 6 存活超时重试次数

http.cors.enabled: true 使用监控

index.analysis.analyzer.ik.type:”ik” ik分词

thread pool setting

threadpool.index.type: fixed 写索引线程池类型 
threadpool.index.size: 64 线程池大小(建议2~3倍cpu数) 
threadpool.index.queue_size: 1000 队列大小

threadpool.search.size: 64 搜索线程池大小 
threadpool.search.type: fixed 搜索线程池类型 
threadpool.search.queue_size: 1000 队列大小

threadpool.get.type: fixed 取数据线程池类型 
threadpool.get.size: 32 取数据线程池大小 
threadpool.get.queue_size: 1000 队列大小

threadpool.bulk.type: fixed 批量请求线程池类型 
threadpool.bulk.size: 32 批量请求线程池大小 
threadpool.bulk.queue_size: 1000 队列大小

threadpool.flush.type: fixed 刷磁盘线程池类型 
threadpool.flush.size: 32 刷磁盘线程池大小 
threadpool.flush.queue_size: 1000 队列大小

indices.store.throttle.type: merge 
indices.store.throttle.type: none 写磁盘类型 
indices.store.throttle.max_bytes_per_sec:500mb 写磁盘最大带宽

index.merge.scheduler.max_thread_count: 8 索引merge最大线程数 
index.translog.flush_threshold_size:600MB 刷新translog文件阀值

cluster.routing.allocation.node_initial_primaries_recoveries:8 并发恢复分片数 
cluster.routing.allocation.node_concurrent_recoveries:2 同时recovery并发数

使用bulk API 增加入库速度 
初次索引的时候,把 replica 设置为 0 
增大 threadpool.index.queue_size 1000 
增大 indices.memory.index_buffer_size: 20% 
index.translog.durability: async –这个可以异步写硬盘,增大写的速度 
增大 index.translog.flush_threshold_size: 600MB 
增大 index.translog.flush_threshold_ops: 500000

复制代码
curl -XPOST '127.0.0.1:9200/_cluster/settings' -d '{
    "transient" : 
        {
          "index.indexing.slowlog.threshold.index.warn": "10s",
            "index.indexing.slowlog.threshold.index.info": "5s",
            "index.indexing.slowlog.threshold.index.debug": "2s",
            "index.indexing.slowlog.threshold.index.trace": "500ms",
            "index.indexing.slowlog.level": "info",
            "index.indexing.slowlog.source": "1000",
            "indices.memory.index_buffer_size": "20%"
        }

}'
复制代码
复制代码
curl -XPOST '127.0.0.1:9200/_cluster/settings' -d '{
    "transient" : 
        {
          "index.search.slowlog.threshold.query.warn": "10s",
        "index.search.slowlog.threshold.query.info": "5s",
        "index.search.slowlog.threshold.query.debug": "2s",
        "index.search.slowlog.threshold.query.trace": "500ms",
        "index.search.slowlog.threshold.fetch.warn": "1s",
        "index.search.slowlog.threshold.fetch.info": "800ms",
        "index.search.slowlog.threshold.fetch.debug": "500ms",
        "index.search.slowlog.threshold.fetch.trace": "200ms"
        }

}'
复制代码

–节点下线时,把所有后缀为 -2的从集群中排除

curl -XPUT   http://127.0.0.1:9200/_cluster/settings
{ "transient" : 
      {"cluster.routing.allocation.enable" : "all",            "cluster.routing.allocation.exclude._name":".*-2"}
  }
复制代码
curl -XPUT ip:9200/_cluster/settings -d
'{
    "transient": {
        "logger.discover": "DEBUG" 
    }
    "persistent": {
        "discovery.zen.minimum_master_nodes": 2
    }
}'
复制代码

—批量指定节点下线

curl -XPUT 127.0.0.1:9200/_cluster/settings -d '{
    "transient": {
        "cluster.routing.allocation.exclude._name": "atest11-2,atest12-2,anatest13-2,antest14-2" 
    }

}'
curl -XPUT 127.0.0.1:9200/_cluster/settings -d '{
    "transient": {
        "cluster.routing.allocation.exclude._name": "test_aa73_2,test_aa73" 
    }

}'
curl -XPUT 127.0.0.1:9200/_cluster/settings -d '{
    "transient": {
        "cluster.routing.allocation.exclude._name": "" 
    }

}'
curl -XPUT 127.0.0.1:9200/_cluster/settings -d '{
    "transient": {
        "cluster.routing.allocation.cluster_concurrent_rebalance": 10
    }

}'
复制代码
curl -XPUT 127.0.0.1:9200/_cluster/settings -d '{
    "transient": {
        "indices.store.throttle.type": "none",
         "index.store.type": "niofs",
         "index.cache.field.type": "soft",
         "indices.store.throttle.max_bytes_per_sec": "500mb",
          "index.translog.flush_threshold_size": "600MB",
         "threadpool.flush.type": "fixed",
        "threadpool.flush.size": 32,
       "threadpool.flush.queue_size": 1000
    }

}'
复制代码
curl -XPUT 127.0.0.1:9200/_cluster/settings -d '{
    "transient": {
        "index.indexing.slowlog.level": "warn" 
    }

}'
复制代码
curl -XGET 127.0.0.1:9200/_cluster/health?level=shards

curl -XGET 127.0.0.1:9200/_cluster/settings?pretty

curl -XGET 127.0.0.1:9200/_cluster/pending_tasks?pretty

curl -XGET 127.0.0.1:9200/_cat/aliases

curl -XGET 127.0.0.1:9200/_cat/plugins

curl -XGET 127.0.0.1:9200/_cat/nodes

/_cat/allocation 
/_cat/shards 
/_cat/shards/{index} 
/_cat/master 
/_cat/nodes 
/_cat/indices 
/_cat/indices/{index} 
/_cat/segments 
/_cat/segments/{index} 
/_cat/count 
/_cat/count/{index} 
/_cat/recovery 
/_cat/recovery/{index} 
/_cat/health 
/_cat/pending_tasks 
/_cat/aliases 
/_cat/aliases/{alias} 
/_cat/thread_pool 
/_cat/plugins 
/_cat/fielddata 
/_cat/fielddata/{fields}
复制代码
复制代码
shard的移动
curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
    "commands" : [ {
        "move" :
            {
              "index" : "test_aa_20160529", "shard" : 4,
              "from_node" : "node1", "to_node" : "node2"
            }
        },
        {
          "allocate" : {
              "index" : "test", "shard" : 1, "node" : "node3"
          }
        }
    ]
}'
复制代码
curl -XPUT 127.0.0.1:9200/_cluster/settings -d '
{
  "transient": {
    "logger.indices.recovery": "DEBUG"
  }
}'
curl -XPUT 127.0.0.1:9200/_cluster/settings -d '
{
  "transient": {
    "cluster.routing.allocation.node_initial_primaries_recoveries": "100" 
  }
}'
复制代码
curl -XPOST '127.0.0.1:9200/_cluster/settings' -d '{
    "transient" : 
        {
            "indices.memory.index_buffer_size": "20%"
        }

}'
复制代码
复制代码
curl -XPOST '127.0.0.1:9200/_cluster/settings' -d '{
    "transient" : 
        {
          "index.indexing.slowlog.level" :   "info" 
        }

}'
复制代码


查看评论

ElasticSearch 优化总结

ElasticSearch 优化总结 目录 ElasticSearch 优化总结 目录 OS OS 参数 ES Linux Release: CentOS r...
  • iorichang
  • iorichang
  • 2016年12月26日 10:22
  • 4497

Elasticsearch性能优化官方建议

原文地址:http://www.cnblogs.com/cutd/p/5800795.html 如何提高ES的性能 不要返回较大的结果集 ES是设计成一个搜索引擎的,只擅长返...
  • tanga842428
  • tanga842428
  • 2017年04月12日 11:07
  • 1384

亿级规模的Elasticsearch优化实战

本次分享主要包含两个方面的实战经验:索引性能和查询性能。 一. 索引性能(Index Performance) 首先要考虑的是,索引性能是否有必要做优化? 索引速度提高...
  • opensure
  • opensure
  • 2015年08月13日 19:43
  • 58137

ElasticSearch性能调优

elasticsearch性能调优 集群规划 独立的master节点,不存储数据, 数量不少于2数据节点(Data Node)查询节点(Query Node),起到负载均衡的作用 Lin...
  • u013063153
  • u013063153
  • 2017年03月08日 17:31
  • 364

elasticsearch调优经验

es节点重启注意点:1、暂停数据写入程序  (如果条件允许,正式环境一般不会允许,我们是es写如果有问题数据会落地回头再写入es,所以也可以允许!!!!! 这种情况基本不会出现 需要重启整个es集群)...
  • peng_zhi_hui
  • peng_zhi_hui
  • 2017年11月14日 13:10
  • 128

使用 Elastic Stack 来监控和调优 Golang 应用程序

原文:http://studygolang.com/wr?u=http%3a%2f%2felasticsearch.cn%2farticle%2f138 Golang 因为其语法简单,上手快...
  • shenlanzifa
  • shenlanzifa
  • 2017年03月13日 15:14
  • 351

GC优化

本文是成为Java GC专家系列文章的第三篇。在第一篇《成为JavaGC专家Part I — 深入浅出Java垃圾回收机制》中我们学习了不同GC算法的执行过程,GC是如何工作的,什么是新生代和老年代,...
  • u013408431
  • u013408431
  • 2017年03月29日 19:21
  • 206

Elasticsearch常见问题收集

1 _riverStatus Import_fail  问题描述: http://192.168.1.17:9200/_plugin/head/ 2 EsRejectedExecutionExcept...
  • huwei2003
  • huwei2003
  • 2014年11月17日 19:29
  • 9962

Elasticsearch线程池介绍

每个Elasticsearch节点内部都维护着多个线程池,如index、search、suggest、bulk等,用户可以修改线程池的类型和大小,线程池默认大小跟CPU,本文基于最新的Elastics...
  • opensure
  • opensure
  • 2016年05月24日 17:59
  • 14230

elasticsearch性能调优相关

http://nocf-www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html https...
  • liukuan73
  • liukuan73
  • 2018年02月05日 16:06
  • 2217
    个人资料
    持之以恒
    等级:
    访问量: 4万+
    积分: 1992
    排名: 2万+
    最新评论