1、EsRejectedExecutionException异常示例
java.util.concurrent.ExecutionException: RemoteTransportException[[node-client10][10.93.21.21:9300][indices:data/write/update]]; nested: RemoteTransportException[[node-client 09][10.93.18.35:9300][indices:data/write/update[s]]]; nested: EsRejectedExecutionException[rejected execution of org.elasticsearch.transport.netty.MessageChannelHandler$Reque stHandler@661fbe1d on EsThreadPoolExecutor[index, queue capacity = 200, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@637f6431[Running, pool size = 12, active threads = 12, queued tasks = 200, completed tasks = 15656095]]];
2、EsRejectedExecutionException异常解释
EsRejectedExecutionException异常,从字面意思上看是ES拒绝执行请求。这个异常的触发场景如下。
使用Elasticsearch的时候,在并发查询量大的情况下,访问流量超过了集群中单个Elasticsearch实例的处理能力,Elasticsearch服务端会触发保护性的机制,拒绝执行新的访问,并且抛出EsRejectedExecutionException异常。
这个保护机制与异常触发是由Elasticsearch API实现中的thread pool与配套的queue决定的。
在示例中,Elasticsearch为index操作分配的线程池,pool size=12, queue capacity=200,当12个线程处理不过来,并且队列中缓冲的tasks超过200个,那么新的task就会被简单的丢弃掉,并且抛出EsRejectedExecutionException异常。
官方的详细解释链接在这里:
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-threadpool.html
这里是几个重要线程池的默认配置,其中很多配置都与processors(cpu core)有关。
1)processors
processors指的是cpu的core数,这个核数可以被自动的探知并且在线程池的配置中自动引入,processors不必在elasitcsearch.yml中配置,当然你可以重写配置。
重写方法:
processor: 8
若在一台机器上部署多个Elasticsearch node,可以将cpu cores平均分配给不同的node,例如2nodes部署在12个core的机器上,可以配置processors = 6。
2)线程池与队列
一个Elasticsearch节点会有多个线程池,但重要的是下面四个:
索引(index):主要是索引数据和删除数据操作(默认是cached类型)
搜索(search):主要是获取,统计和搜索操作(默认是cached类型)
批量操作(bulk):主要是对索引的批量操作(默认是cached类型)
更新(refresh):主要是更新操作(默认是cached类型)
generic For generic operations (e.g., background node discovery). Thread pool type is scaling. index For index/delete operations. Thread pool type is fixed with a size of # of available processors, queue_size of 200. The maximum size for this pool is 1 + # of available processors. search For count/search/suggest operations. Thread pool type is fixed with a size of int((# of available_processors * 3) / 2) + 1, queue_size of 1000. get For get operations. Thread pool type is fixed with a size of # of available processors, queue_size of 1000. bulk For bulk operations. Thread pool type is fixed with a size of # of available processors, queue_size of 200. The maximum size for this pool is 1 + # of available processors. snapshot For snapshot/restore operations. Thread pool type is scaling with a keep-alive of 5m and a max of min(5, (# of available processors)/2). warmer For segment warm-up operations. Thread pool type is scaling with a keep-alive of 5m and a max of min(5, (# of available processors)/2). refresh For refresh operations. Thread pool type is scaling with a keep-alive of 5m and a max of min(10, (# of available processors)/2). listener Mainly for java client executing of action when listener threaded is set to true. Thread pool type is scaling with a default max of min(10, (# of available processors)/2).
3)线程池类型
fixed
The fixed thread pool holds a fixed size of threads to handle the requests with a queue (optionally bounded) for pending requests that have no threads to service them.
The size parameter controls the number of threads, and defaults to the number of cores times 5.
The queue_size allows to control the size of the queue of pending requests that have no threads to execute them. By default, it is set to -1 which means its unbounded. When a request comes in and the queue is full, it will abort the request.
fixed线程池保持固定个数的线程来处理请求队列。
size参数设置线程的个数,默认设置是cpu核心数的5倍。
queue_size可以控制待处理请求队列的大小。默认是设置为-1,意味着无限制。当一个请求到来但队列满了的时候,reject_policy参数可以控制它的行为。默认是abort,会使那个请求失败。设置成caller会使该请求在io线程中执行。
threadpool:
index:
type: fixed
size: 30
queue: 1000
reject_policy: caller
scaling
The scaling thread pool holds a dynamic number of threads. This number is proportional to the workload and varies between the value of the core and max parameters.
The keep_alive parameter determines how long a thread should be kept around in the thread pool without it doing any work.
scaling线程池保持着动态数量的线程。在core和max数量之间的动态变化,keep_alive配置的时间,维持了线程长时间未被调用。
thread_pool:
warmer:
core: 1
max: 8
keep_alive: 2m
blocking
在不同的版本有不同的类型。blocking类型的线程池特征是
blocking线程池允许设置一个最小值(min,默认为1)和线程池大小(size,默认为cpu核心数的5倍)。它也有一个等待队列,队列的大小(queue_size )默认是1000,当这队列满了的时候。它会根据定好的等待时间(wait_time,默认是60秒)来调用io线程,如果没有执行就会报错。