场景: 我正在处理一个包含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
我不明白缺少了什么。请指引我正确的方向。询问我是否需要其他任何信息来理解我的问题。预先非常感谢。
答案 0 :(得分:0)
为了确定,我需要执行实体更改的代码,但据我了解:
有三种解决方案:
不幸的是,目前无法提供数字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