Hibernate Search:并发超时异常

时间:2019-11-14 13:29:09

标签: java hibernate elasticsearch hibernate-search

场景: 我正在处理一个包含150+列和15000行的Excel文件。该文件转换为List,然后称为repository.saveAll(List)。这项服务方法是由15个用户请求同时调用的。

代码

@Transactional(rollbackFor = Exception.class)
    public BooleanResponse fileProcessing(
            Request req) {


        for (MultipartFile file : req.getMasterSheets()) {
            List<EntityClazz> list = excelParser.processExcelFile(file, EntityClazz.class);
            EntityClazzRepository.saveAll(list);
            list.clear();
        }

        return BooleanResponse.success();

    }

我在Hibernate Search和Elastic Search中面临以下异常。

2019-11-14 12:38:32.567 ERROR 1 --- [eout executor-1] o.h.s.exception.impl.LogErrorHandler     : HSEARCH000058: Exception occurred org.hibernate.search.exception.SearchException: HSEARCH400007: Elasticsearch request failed.
Request: POST /_bulk with parameters {refresh=false}
Response: null
Subsequent failures:
        Entity com.xyz.xyz.domain.entity.epc.EntityClazz  Id 436294  Work Type  org.hibernate.search.backend.AddLuceneWork
        Entity com.xyz.xyz.domain.entity.epc.EntityClazz  Id 436310  Work Type  org.hibernate.search.backend.AddLuceneWork
        Entity com.xyz.xyz.domain.entity.epc.EntityClazz  Id 436326  Work Type  org.hibernate.search.backend.AddLuceneWork
        Entity com.xyz.xyz.domain.entity.epc.EntityClazz  Id 436342  Work Type  org.hibernate.search.backend.AddLuceneWork
.
.
.
.

        Entity com.xyz.xyz.domain.entity.epc.EntityClazz  Id 472620  Work Type  org.hibernate.search.backend.AddLuceneWork
        Entity com.xyz.xyz.domain.entity.epc.EntityClazz  Id 472625  Work Type  org.hibernate.search.backend.AddLuceneWork




org.hibernate.search.exception.SearchException: HSEARCH400007: Elasticsearch request failed.
Request: POST /_bulk with parameters {refresh=false}
Response: null
        at org.hibernate.search.elasticsearch.work.impl.BulkWork.lambda$execute$1(BulkWork.java:77) ~[hibernate-search-elasticsearch-5.10.5.Final.jar!/:5.10.5.Final]
        at org.hibernate.search.util.impl.Futures.lambda$handler$1(Futures.java:57) ~[hibernate-search-engine-5.10.5.Final.jar!/:5.10.5.Final]
        at java.util.concurrent.CompletableFuture.uniExceptionally(CompletableFuture.java:870) ~[na:1.8.0_212]
        at java.util.concurrent.CompletableFuture$UniExceptionally.tryFire(CompletableFuture.java:852) ~[na:1.8.0_212]
        at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474) ~[na:1.8.0_212]
        at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1977) ~[na:1.8.0_212]
        at org.hibernate.search.elasticsearch.client.impl.DefaultElasticsearchClient.lambda$send$3(DefaultElasticsearchClient.java:137) ~[hibernate-search-elasticsearch-5.10.5.Final.jar!/:5.10.5.Final]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_212]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_212]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_212]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[na:1.8.0_212]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_212]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_212]
        at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_212]
Caused by: java.util.concurrent.TimeoutException: null
        ... 8 common frames omitted

此日志就是这样一个示例,其中显示了许多异常...感觉好像有许多线程在工作,而有些线程却失败了。不知道为什么。一次需要索引的数据集几乎为50000。和Hibernate搜索会在事务提交后自动开始异步索引,因为我已将async设置为true。

我正在使用Hibernate Search版本5.10和Elastic Search版本5.6.10。 我的数据库表很大。 Hibernate在此表上执行批量更新/插入操作。

我的弹性搜索服务器处于默认配置。那只有一个节点。黄色的健康。

以下是弹性搜索集群节点的统计信息:

{
   "_nodes":{
      "total":1,
      "successful":1,
      "failed":0
   },
   "cluster_name":"elasticsearch",
   "nodes":{
      "I7fWwFhORhimHRDL6jJTuw":{
         "timestamp":1573740483870,
         "name":"I7fWwFh",
         "transport_address":"",
         "host":"",
         "ip":"",
         "roles":[
            "master",
            "data",
            "ingest"
         ],
         "indices":{
            "docs":{
               "count":7090,
               "deleted":956
            },
            "store":{
               "size_in_bytes":69228643,
               "throttle_time_in_millis":0
            },
            "indexing":{
               "index_total":5091795,
               "index_time_in_millis":60401979,
               "index_current":11,
               "index_failed":7,
               "delete_total":124964,
               "delete_time_in_millis":2232,
               "delete_current":0,
               "noop_update_total":0,
               "is_throttled":true,
               "throttle_time_in_millis":1348474
            },
            "get":{
               "total":4913,
               "time_in_millis":316,
               "exists_total":4913,
               "exists_time_in_millis":316,
               "missing_total":0,
               "missing_time_in_millis":0,
               "current":0
            },
            "search":{
               "open_contexts":0,
               "query_total":232976,
               "query_time_in_millis":79853,
               "query_current":0,
               "fetch_total":183622,
               "fetch_time_in_millis":608420,
               "fetch_current":0,
               "scroll_total":3555,
               "scroll_time_in_millis":192717,
               "scroll_current":0,
               "suggest_total":0,
               "suggest_time_in_millis":0,
               "suggest_current":0
            },
            "merges":{
               "current":0,
               "current_docs":0,
               "current_size_in_bytes":0,
               "total":9867,
               "total_time_in_millis":23061388,
               "total_docs":7412149,
               "total_size_in_bytes":191974966202,
               "total_stopped_time_in_millis":0,
               "total_throttled_time_in_millis":626635,
               "total_auto_throttle_in_bytes":80244256738
            },
            "refresh":{
               "total":200577,
               "total_time_in_millis":32611981,
               "listeners":0
            },
            "flush":{
               "total":7747,
               "total_time_in_millis":67635
            },
            "warmer":{
               "current":0,
               "total":677,
               "total_time_in_millis":21
            },
            "query_cache":{
               "memory_size_in_bytes":0,
               "total_count":0,
               "hit_count":0,
               "miss_count":0,
               "cache_size":0,
               "cache_count":0,
               "evictions":0
            },
            "fielddata":{
               "memory_size_in_bytes":0,
               "evictions":0
            },
            "completion":{
               "size_in_bytes":0
            },
            "segments":{
               "count":48,
               "memory_in_bytes":4551470,
               "terms_memory_in_bytes":3595446,
               "stored_fields_memory_in_bytes":20168,
               "term_vectors_memory_in_bytes":0,
               "norms_memory_in_bytes":913856,
               "points_memory_in_bytes":280,
               "doc_values_memory_in_bytes":21720,
               "index_writer_memory_in_bytes":0,
               "version_map_memory_in_bytes":0,
               "fixed_bit_set_memory_in_bytes":0,
               "max_unsafe_auto_id_timestamp":-1,
               "file_sizes":{

               }
            },
            "translog":{
               "operations":0,
               "size_in_bytes":1290
            },
            "request_cache":{
               "memory_size_in_bytes":21920,
               "evictions":0,
               "hit_count":0,
               "miss_count":30
            },
            "recovery":{
               "current_as_source":0,
               "current_as_target":0,
               "throttle_time_in_millis":0
            }
         },
         "os":{
            "timestamp":1573740483888,
            "cpu":{
               "percent":0,
               "load_average":{
                  "1m":0,
                  "5m":0,
                  "15m":0
               }
            },
            "mem":{
               "total_in_bytes":4134809600,
               "free_in_bytes":115888128,
               "used_in_bytes":4018921472,
               "free_percent":3,
               "used_percent":97
            },
            "swap":{
               "total_in_bytes":0,
               "free_in_bytes":0,
               "used_in_bytes":0
            },
            "cgroup":{
               "cpuacct":{
                  "control_group":"/",
                  "usage_nanos":85077837036370
               },
               "cpu":{
                  "control_group":"/",
                  "cfs_period_micros":100000,
                  "cfs_quota_micros":-1,
                  "stat":{
                     "number_of_elapsed_periods":0,
                     "number_of_times_throttled":0,
                     "time_throttled_nanos":0
                  }
               }
            }
         },
         "process":{
            "timestamp":1573740483888,
            "open_file_descriptors":213,
            "max_file_descriptors":65536,
            "cpu":{
               "percent":0,
               "total_in_millis":82774150
            },
            "mem":{
               "total_virtual_in_bytes":5024968704
            }
         },
         "jvm":{
            "timestamp":1573740483888,
            "uptime_in_millis":2672036639,
            "mem":{
               "heap_used_in_bytes":1155032416,
               "heap_used_percent":54,
               "heap_committed_in_bytes":2130051072,
               "heap_max_in_bytes":2130051072,
               "non_heap_used_in_bytes":146981608,
               "non_heap_committed_in_bytes":154607616,
               "pools":{
                  "young":{
                     "used_in_bytes":135568192,
                     "max_in_bytes":139591680,
                     "peak_used_in_bytes":139591680,
                     "peak_max_in_bytes":139591680
                  },
                  "survivor":{
                     "used_in_bytes":4866896,
                     "max_in_bytes":17432576,
                     "peak_used_in_bytes":17432576,
                     "peak_max_in_bytes":17432576
                  },
                  "old":{
                     "used_in_bytes":1014597328,
                     "max_in_bytes":1973026816,
                     "peak_used_in_bytes":1638372912,
                     "peak_max_in_bytes":1973026816
                  }
               }
            },
            "threads":{
               "count":43,
               "peak_count":50
            },
            "gc":{
               "collectors":{
                  "young":{
                     "collection_count":170449,
                     "collection_time_in_millis":1934820
                  },
                  "old":{
                     "collection_count":847,
                     "collection_time_in_millis":38599
                  }
               }
            },
            "buffer_pools":{
               "direct":{
                  "count":32,
                  "used_in_bytes":67767443,
                  "total_capacity_in_bytes":67767442
               },
               "mapped":{
                  "count":108,
                  "used_in_bytes":68478134,
                  "total_capacity_in_bytes":68478134
               }
            },
            "classes":{
               "current_loaded_count":12473,
               "total_loaded_count":12527,
               "total_unloaded_count":54
            }
         },
         "thread_pool":{
            "bulk":{
               "threads":2,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":2,
               "completed":383422
            },
            "fetch_shard_started":{
               "threads":1,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":4,
               "completed":97
            },
            "fetch_shard_store":{
               "threads":0,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":0,
               "completed":0
            },
            "flush":{
               "threads":1,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":1,
               "completed":12854
            },
            "force_merge":{
               "threads":1,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":1,
               "completed":1240
            },
            "generic":{
               "threads":4,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":8,
               "completed":273461
            },
            "get":{
               "threads":2,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":2,
               "completed":4897
            },
            "index":{
               "threads":2,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":2,
               "completed":16
            },
            "listener":{
               "threads":1,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":1,
               "completed":21
            },
            "management":{
               "threads":3,
               "queue":0,
               "active":1,
               "rejected":0,
               "largest":3,
               "completed":366004
            },
            "refresh":{
               "threads":1,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":1,
               "completed":21459450
            },
            "search":{
               "threads":4,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":4,
               "completed":463814
            },
            "snapshot":{
               "threads":0,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":0,
               "completed":0
            },
            "warmer":{
               "threads":0,
               "queue":0,
               "active":0,
               "rejected":0,
               "largest":0,
               "completed":0
            }
         },
         "fs":{
            "timestamp":1573740483888,
            "total":{
               "total_in_bytes":8577331200,
               "free_in_bytes":20480,
               "available_in_bytes":20480
            },
            "data":[
               {
                  "path":"/var/lib/elasticsearch/nodes/0",
                  "mount":"/ (/dev/xvda1)",
                  "type":"xfs",
                  "total_in_bytes":8577331200,
                  "free_in_bytes":20480,
                  "available_in_bytes":20480,
                  "spins":"false"
               }
            ],
            "io_stats":{
               "devices":[
                  {
                     "device_name":"xvda1",
                     "operations":5857367,
                     "read_operations":171280,
                     "write_operations":5686087,
                     "read_kilobytes":13911088,
                     "write_kilobytes":304080912
                  }
               ],
               "total":{
                  "operations":5857367,
                  "read_operations":171280,
                  "write_operations":5686087,
                  "read_kilobytes":13911088,
                  "write_kilobytes":304080912
               }
            }
         },
         "transport":{
            "server_open":0,
            "rx_count":20,
            "rx_size_in_bytes":7538,
            "tx_count":20,
            "tx_size_in_bytes":7538
         },
         "http":{
            "current_open":20,
            "total_opened":2915
         },
         "breakers":{
            "request":{
               "limit_size_in_bytes":1278030643,
               "limit_size":"1.1gb",
               "estimated_size_in_bytes":0,
               "estimated_size":"0b",
               "overhead":1,
               "tripped":0
            },
            "fielddata":{
               "limit_size_in_bytes":1278030643,
               "limit_size":"1.1gb",
               "estimated_size_in_bytes":0,
               "estimated_size":"0b",
               "overhead":1.03,
               "tripped":0
            },
            "in_flight_requests":{
               "limit_size_in_bytes":2130051072,
               "limit_size":"1.9gb",
               "estimated_size_in_bytes":4396991,
               "estimated_size":"4.1mb",
               "overhead":1,
               "tripped":0
            },
            "parent":{
               "limit_size_in_bytes":1491035750,
               "limit_size":"1.3gb",
               "estimated_size_in_bytes":4396991,
               "estimated_size":"4.1mb",
               "overhead":1,
               "tripped":0
            }
         },
         "script":{
            "compilations":1,
            "cache_evictions":0
         },
         "discovery":{
            "cluster_state_queue":{
               "total":0,
               "pending":0,
               "committed":0
            }
         },
         "ingest":{
            "total":{
               "count":0,
               "time_in_millis":0,
               "current":0,
               "failed":0
            },
            "pipelines":{

            }
         }
      }
   }
}

这是我在Spring boot 2.0应用程序中的Hibernate Search配置。

spring:
  application:
    name: xyz

  servlet:
    multipart:
      max-file-size: 100MB
      max-request-size: 100MB

  datasource:
    username: ${DB_USER:root}
    password: ${DB_PASSWORD:root}
    url: ${DB_URL:jdbc:mysql://localhost:3306/xyz}?serverTimezone=UTC&useLegacyDatetimeCode=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=utf8&connectionCollation=utf8_general_ci&useSSL=false
    hikari:
      maximum-pool-size: 30
      minimum-idle: 10
  jpa:
    show-sql: false
    properties:
      hibernate:
        ejb:
          interceptor: com.xyz.xyz.xyz.util.EntityInterceptor
        jdbc:
          batch_size: 100
          order_inserts: true
          order_update: true
        search:
          autoregister_listeners: true
          fulltext_query: ERROR
          default_null_token: N/A
          error_handler: com.xyz.xyz.xyz.search.exceptions.HibernateSearchErrorHandler
          default:
            indexmanager: elasticsearch
            worker:
              execution: async
            elasticsearch:
              required_index_status: yellow
              index_schema_management_strategy: none
              host: ${ES_HOST:http://127.0.0.1:9200}
              request: ERROR
              log:
                json_pretty_printing: false

我不明白缺少了什么。请指引我正确的方向。询问我是否需要其他任何信息来理解我的问题。预先非常感谢。

1 个答案:

答案 0 :(得分:0)

为了确定,我需要执行实体更改的代码,但据我了解:

  • 您正在数据库中进行大量更改
  • 休眠搜索将相应的索引更改(成千上万个)排入队列
  • Hibernate Search异步处理队列,但是要成批处理,将非常大的索引请求发送到Elasticsearch。
  • Elasticsearch无法跟上,请求最终超时

有三种解决方案:

  1. 一次发送更少的请求到Elasticsearch(较小的批次),以便Elasticsearch获得相同的时间来索引更少的文档。
  2. 让Elasticsearch有更多时间处理每个请求。
  3. 提高Elasticsearch的索引编制速度。

不幸的是,目前无法提供数字1:您无法控制Hibernate Search发送到Elasticsearch的批次的大小。但这仅在您的问题是由罕见的,短暂的“突发”变化引起的时才有用,这似乎不是您的情况。

数字2可能不是一个好主意,因为默认超时时间已经很大:60秒。如果超时,Elasticsearch会非常非常慢,或者存在导致连接超时的网络问题。在这两种情况下,这都很重要,您应该查看一下设置(请参阅下文)。 如果您确实想增加此超时时间,请使用属性hibernate.search.default.elasticsearch.read_timeout(以毫秒为单位)。

我认为第3条路要走。您确实应该查看一下Elasticsearch集群的配置。尝试测试和监视您的群集,以查看是否存在瓶颈。

一个容易解决的瓶颈是从Hibernate Search到Elasticsearch的同时连接数。在Hibernate Search 5.10中,默认情况下,每个Elasticsearch节点最多2个,每个群集最多20个。如果您仅使用一个Elasticsearch节点,则可能会非常有限。尝试提高它:

spring:
  jpa:
    properties:
      hibernate:
        search:
          default:
            elasticsearch:
              max_total_connection_per_route: 10