Elasticsearch常见的8种错误及最佳实践题记
Elasticsearch 社区有⼤量关于 Elasticsearch 错误和异常的问题。
深挖这些错误背后的原因,把常见的错误积累为⾃⼰的实战经验甚⾄是⼯具,不仅可以节省
我们的开发和运维时间,⽽且可以帮助确保 Elasticsearch 集的长期健康运⾏。
常见的异常、原因和常规最佳实践拆解如下,这些最佳实践可以帮助我们更有效地识别、最
⼩化定位和处理异常问题。
1、 Mapper_parsing_exception
Elasticsearch 依靠映射(Mapping)定义的数据类型处理数据。
映射定义了⽂档中的字段并指定了它们对应的数据类型,例如⽇期类型 Date、长整数类型long 和字符串类型 text。
如果索引⽂档包含没有定义数据类型的新字段,Elasticsearch将使⽤动态映射来估计字段的
类型,并在必要时将其从⼀种类型转换为另⼀种类型。
如果Elasticsearch⽆法执⾏此转换,它将引发“ mapper_parsing_exception⽆法解析” 异常。如果此类异常太多会降低索引吞吐量。
实战举例如下:
DELETE mytest_0001PUT mytest_0001/_doc/1{ "name":"John"}PUT mytest_0001/_doc/2{ "name": { "firstname": "John", "lastname": "doe" }}
为避免此问题,可以在创建索引时显⽰定义Mapping,明确敲定字段类型。或者可以使⽤
_mapping 动态添加新字段映射。
动态更新索引实战:
PUT mytest_0001/_mapping{ "properties": { "title": { "type": "text" } }}
请注意:虽然可以通过如上命令动态添加字段,但是不能更改现有字段映射。
若想做字段类型的修改,需要重新定义Mapping 结合 reindex 和 alias 别名实现。
2、BulkIndexError
批量索引⼤型数据集通常更有效。
例如,您可以执⾏⼀个批量操作来索引 1,000 个⽂档,⽽不是使⽤ 1,000 个索引操作。
批量操作可以通过 bulk API 完成。
批量操作实战:
PUT my_index_0003/_bulk{"index":{"_id":1}}{"myid":"c12345"}{"index":{"_id":2}} {"myid":"C12456"}{"index":{"_id":3}}{"myid":"C31268"}
但是,此过程容易出错。执⾏批量操作的过程中,你需要仔细检查:数据类型不匹配和空值匹配等问题。
对于批量 API ,你需要格外警惕,因为即使有数百个肯定的响应,批量中的某些索引请求也可能失败。
批量操作捕获错误实战:
@Override public void afterBulk(long executionId, BulkRequest request, BulkResponse re sponse) {
if (response.hasFailures()) { for (int i = 0; i < Items().length; i++) { Bul kItemResponse item = Items()
[i]; if (item.isFailed()) { IndexRequest ireq = (IndexRequest) quests().get(i); ("Failed while indexing to " + Index() + " type " + Type() + " " + "request: [" + ireq + "]: [" + FailureMessage() + "]"); } } } }
除了提前设置具有所有适当条件的批量 API 之外,还要浏览响应列表并检查每个响应,以确保所有数据均按预期索引。
3、搜索超时错误:
ConnectionTimeout,ReadTimeoutError,RequestTimeout 等如果在指定的搜索时间内未收到响应,则请求将失败并返回错误消息。这称为搜索超时。
搜索超时很常见,多种原因都可以导致搜索超时,例如:⼤型数据集或占⽤⼤量内存的查询。
要消除搜索超时,可以通过如下实现解决:
3.1 增加 questTimeout
设置注意:应该在 HTTP 客户端⽽不是 Elasticsearch 中指定 timeout 值,Elasticsearch 端没有请求超时参数。
kibana 请求显⽰超时,优化⽅案如下:
kibana 默认请求等待时间是 30 秒,可以在 l 中调整该值。
3.2 减少每个请求返回的⽂档数量
不要将请求的 size 值设置太⼤,结合:from、size 深度翻页机制实现。
全量遍历借助 scroll 实现。
3.3 缩⼩时间范围
请求时间范围越长(⽐如时间跨度周期 1 年以上的数据),请求数据量越⼤,超时的可能性越⾼。
3.4 调整内存设置
通过配置单个查询的内存断路器来限制单个查询的内存使⽤量。
如:将 quest.limit 限制为 40%,默认是 60%。
集层⾯设置请求熔断内存实战:
PUT /_cluster/settings{ "persistent": { "quest.limit": "40%" }}
通过将search.max_buckets设置为 5000 (默认值:10000)来限制⽤于聚合的存储桶数。PUT _cluster/settings{ "transient": { "search.max_buckets": 5000 }}
3.5 优化查询、索引和分⽚。
3.6 启⽤慢速搜索⽇志
监视搜索运⾏时间,扫描繁重的搜索等等。
慢⽇志开启实战:
PUT /_settings{ "index.search.slowlog.threshold.query.debug": "30s", "index.search.slowlo g.threshold.fetch.debug": "30s", "index.indexing.slowlog.threshold.index.debug": "30s"}
4、 All Shards Failed
在 Elasticsearch 搜索时,可能会遇到 “All Shards Failed” 的错误消息。
发⽣ All Shards Failed 的⼏种情况:
当读取请求⽆法从分⽚获得响应时
当由于集或节点仍处于初始启动过程⽽⽆法搜索数据
当分⽚丢失或处于恢复模式并且集为红⾊时
造成 All Shards Failed 可能的原因:
节点可能已断开连接或重新连接
正在查询的分⽚可能正在恢复中,因此不可⽤
磁盘可能已损坏
搜索query 语句可能写的有问题。例如,引⽤字段类型错误的字段。
配置错误可能导致操作失败。
问题排查实战举例:
GET /_cat/healthGET /_cat/indices?vGET _cluster/health/?
level=shardsGET _cluster/allocation/explain
5、进程内存锁定失败:“memory locking requested for elasticsearch process but memory is not locked”
为了使节点保持健康,必须确保没有将 JVM 内存换出到磁盘。
发⽣系统 swapping (交换)的时候 Elasticsearch 节点的性能会⾮常差,也会影响节点的稳定性。
所以要不惜⼀切代价来避免 swapping 。swapping会导致Java GC的周期延迟从毫秒级恶化到分钟,更严重的是会引起节点响应延迟甚⾄脱离集。
限制 elasticsearch占⽤的内存情况,可选择少⽤swap。⽽:启⽤ _lock 就是限制交换的三种⽅案之⼀。
在 l 中启动 memory_lock 实践:
<_lock: true
报错复现如下:
[,260][INFO ][Node ] [node-1] starting ...[,529][INFO ]
[TransportService ] [node-
1] publish_address {172.17.0.5:9300}, bound_addresses {172.17.0.5:9300}[,537][INFO ] [o.e.b.BootstrapChecks ] [node-1] bound or publishing to a non-
loopback address, enforcing bootstrap checks[,565][ERROR][o.e.b.Bootstrap ] [node-1] node validation exception[1] bootstrap checks failed[1]: memory locking requested for ela sticsearch process but memory is not locked[,575][INFO ][Node ] [node-
1] stopping ...[,596][INFO ][Node ] [node-1] stopped[,597][INFO ]
[Node ] [node-1] closing ...[,615][INFO ][Node ] [node-1] closed
centos 7.x 解决⽅案:在 /etc/f ⽂件中添加如下内容,并保持,然后重启elasticsearch 即可。
elasticsearch soft memlock unlimitedelasticsearch hard memlock unlimited
最佳实践之验证启动是否成功:
GET _nodes?filter_path=**.mlockall
fetch最佳用法正确返回结果如下:
{ "nodes" : { "gJUT-E48u_nUw" : { "process" : { "mlockall" : true } } }}
6、引导检查失败 Bootstrap Checks Failed
Bootstrap 检查会在 Elasticsearch 开始之前检查各种设置和配置,以确保其可以安全运⾏。
如果引导检查失败,则它们可以阻⽌ Elasticsearch 启动(如果处于⽣产模式)或在开发模式下发出警告⽇志。
建议你熟悉引导检查所强制执⾏的设置,并注意它们在开发和⽣产模式上是不同的。通过将系统属性
主要检查内容包含但不限于:
堆的⼤⼩检查
⽂件描述符
最⼤线程数
⽂件⼤⼩限制
最⼤虚拟内存
最⼤映射数
客户端jvm检查
垃圾收集检查
OnError和OnOutOfMemoryError检查 ......
最佳实践:在 jvm.option 中添加如下配置后重启 Elasticsearch。
-force.bootstrap.checks=true
7、TransportError
在Elasticsearch中,传输模块核⼼功能是:集中节点之间的通信。
传输错误Transport errors 经常出现,失败可能是如下的原因引起的:
分⽚丢失
设置冲突
数据建模不合理
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论