线程池队列满导致错误

在这种场景下ES抛出的异常是

rejected execution of org.elasticsearch.transport.TransportService$4@c8998f4 
on EsThreadPoolExecutor[bulk, queue capacity = 50, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@553aee29
[Running, pool size = 4, active threads = 4, queued tasks = 50, completed tasks = 0]]

ES内部有很多线程池,比如index,search,bulk是我们能够看到的3个典型的线程池,如果系统的压力特别大,后台线程处理不过来的时候,用户发起的任务会在线程池的队列里堆积,如果达到队列的上限就会抛出对应的异常,遇到这种错误需要做以下两步:

  • 检查系统的CPU和IO的利用情况,如果系统的IO和CPU的利用率比较高,这说明系统遇到资源瓶颈了,已经不能通过优化系统的参数来避免这种错误发生了,云上的用户可以在ES的控制台查看ES的CPU利用率,也可以通过ES自带的命令来查看,通过下面这个命令可以看到ES各个节点的CPU利用率以及负载:

    GET /_cat/nodes?v
    
  • 如果资源没有问题,那么检查当先线程池的配置,比如上面这个错误就需要检查bulk的线程池的配置,在sense里执行以下命令:

    GET /_cluster/settings
    

    结果如下

    "threadpool": {
         "bulk": {
            "type": "fixed",
            "size": "4",
            "queue_size": "50"
         }
      }
    

    这个结果表示处理bulk任务的线程池有4个执行线程,队列数为50. 根据我们的经验看,这个值还是比较小的,所以可以直接用以下操作处理:

    PUT /_cluster/settings
    {
        "persistent": {
            "threadpool.bulk.size": 32,
            "threadpool.bulk.queue_size": 300
        }
    }