ES出现read-only的解决办法

本文讲述了在使用Elasticsearch 6.5.1时遇到的批量写入失败问题,由于index_read_only_allow_delete策略导致的`FORBIDDEN`异常,提供了解决方案包括临时禁用只读限制。

环境

Elasticsearch 6.5.1

问题

es入库出现如下异常:

Caused by: org.elasticsearch.hadoop.EsHadoopException: Could not write all entries for bulk operation [1000/1000]. Error sample (first [5] error messages):
	org.elasticsearch.hadoop.rest.EsHadoopRemoteException: cluster_block_exception: blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];
	{"index":{}}
{"clients":"221.178.126.22","visitCount":2,"ip":"103.74.193.128","etime":1619329560836,"host":"www.whois.gd","stime":1619329560836,"clientCount":1}

	org.elasticsearch.hadoop.rest.EsHadoopRemoteException: cluster_block_exception: blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];
	{"index":{}}
{"clients":"123.145.32.108","visitCount":1,"ip":"47.91.24.26","etime":1619346287107,"host":"www.01zy.cn","stime":1619346287107,"clientCount":1}

	org.elasticsearch.hadoop.rest.EsHadoopRemoteException: cluster_block_exception: blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];
	{"index":{}}
{"clients":"125.82.28.37","visitCount":1,"ip":"200.0.81.81","etime":1619281692173,"host":"legislacao.anatel.gov.br","stime":1619281692173,"clientCount":1}

	org.elasticsearch.hadoop.rest.EsHadoopRemoteException: cluster_block_exception: blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];
	{"index":{}}
{"clients":"221.178.126.22","visitCount":2,"ip":"45.136.13.65","etime":1619299495362,"host":"www.veestyle.cn","stime":1619299249631,"clientCount":1}

	org.elasticsearch.hadoop.rest.EsHadoopRemoteException: cluster_block_exception: blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];
	{"index":{}}
{"clients":"14.111.48.11","visitCount":1,"ip":"156.250.150.139","etime":1619340198188,"host":"www.747218.com","stime":1619340198188,"clientCount":1}

Bailing out...
	at org.elasticsearch.hadoop.rest.bulk.BulkProcessor.flush(BulkProcessor.java:519) ~[elasticsearch-spark-20_2.11-6.5.1.jar:6.5.1]
	at org.elasticsearch.hadoop.rest.bulk.BulkProcessor.add(BulkProcessor.java:127) ~[elasticsearch-spark-20_2.11-6.5.1.jar:6.5.1]
	at org.elasticsearch.hadoop.rest.RestRepository.doWriteToIndex(RestRepository.java:192) ~[elasticsearch-spark-20_2.11-6.5.1.jar:6.5.1]
	at org.elasticsearch.hadoop.rest.RestRepository.writeToIndex(RestRepository.java:172) ~[elasticsearch-spark-20_2.11-6.5.1.jar:6.5.1]
	at org.elasticsearch.spark.rdd.EsRDDWriter.write(EsRDDWriter.scala:67) ~[elasticsearch-spark-20_2.11-6.5.1.jar:6.5.1]
	at org.elasticsearch.spark.rdd.EsSpark$$anonfun$doSaveToEs$1.apply(EsSpark.scala:107) ~[elasticsearch-spark-20_2.11-6.5.1.jar:6.5.1]
	at org.elasticsearch.spark.rdd.EsSpark$$anonfun$doSaveToEs$1.apply(EsSpark.scala:107) ~[elasticsearch-spark-20_2.11-6.5.1.jar:6.5.1]
	at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:87) ~[spark-core_2.11-2.3.1.jar:2.3.1]
	at org.apache.spark.scheduler.Task.run(Task.scala:109) ~[spark-core_2.11-2.3.1.jar:2.3.1]
	at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:345) ~[spark-core_2.11-2.3.1.jar:2.3.1]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[?:1.8.0_65]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[?:1.8.0_65]
	at java.lang.Thread.run(Thread.java:745) ~[?:1.8.0_65]

解决办法

这里的原因多半是因为部分服务器节点空间不够,造成数据不能正常保存,解决办法就是扩容或者删除部分数据。

下面的语句可以临时解决问题:
curl -XPUT -H “Content-Type: application/json” http://${ip}:9200/_all/_settings?pretty -d ‘{“index.blocks.read_only_allow_delete”: null}’ -u elastic

<think>首先,用户的问题是关于解决Elasticsearch的错误:[Forbidden/12/index read-only/ allow delete(api)]。错误表明索引是只读状态,阻止了写入操作。 我从用户提供的引用中收集信息: - 引用[1]:描述了一个具体场景,Elasticsearch报错FORBIDDEN/12/index read-only / allow delete (api),无法写入。[^1] - 引用[2]:解释了错误是ElasticsearchException,类型为cluster_block_exception,原因是索引被阻止。[^2] - 引用[3]:给出了错误示例,索引被阻塞,状态403。[^3] - 引用[4]:提到这与同步数据到ES时发生的异常相关。[^4] - 引用[5]:显示了一个类似的错误,但原因是TOO_MANY_REQUESTS,状态429。[^5],这说明原因可能不同,但核心是索引只读。 常见原因分析: - 磁盘空间不足:当Elasticsearch节点的磁盘空间低于某个阈值时,它会将索引设为只读模式来防止数据损坏。 - 内存问题:高负载或内存不足也可能导致类似行为。 - 集群设置:集群块设置可能手动或自动触发了只读模式。 解决方案: 1. **检查磁盘空间**:确保所有节点的磁盘空间充足。Elasticsearch默认设置中,当磁盘使用率超过85%时,索引变成只读模式;超过90%时,阻止写入;超过95%时,完全阻止。 2. **解决磁盘空间问题**:清理磁盘,删除不必要的索引数据,扩展磁盘。 3. **修改集群设置**:手动移除只读限制。使用Elasticsearch API设置索引的只读标志。 具体步骤: - 检查集群状态:使用`GET /_cluster/health`查看磁盘使用情况。 - 检查索引设置:使用`GET /<index_name>/_settings`查看索引的只读状态。 - 移除只读块:使用PUT请求更新索引设置: ```json PUT /<index_name>/_settings { "index.blocks.read_only_allow_delete": null } ``` 这将移除只读允许删除块。 4. **调整阈值**:为防止未来发生类似的错误,可以调整磁盘使用阈值。例如: ```json PUT /_cluster/settings { "persistent": { "cluster.routing.allocation.disk.threshold_enabled": false } } ``` 但这不是推荐做法,最好的方法是管理好磁盘空间。 5. **监控和预防**:设置监控系统,如Elasticsearch自己的监控功能或外部工具,来警报磁盘空间问题。 结构化回答: - **解释问题**:简要说明错误的原因是由于索引处于只读模式,通常是磁盘空间不足引起的。 - **提供解决方案**:分步指导如何解决。 - **生成相关问题**:按照系统指令,我需要生成相关问题。基于错误主题,相关问题可以是关于Elasticsearch磁盘管理、预防措施、其他常见错误等。 使用中文回答。 确保LaTeX格式正确:这里似乎没有数学表达式,但如果需要,我会使用$...$或$$...$$。例如,如果有公式,但在这个上下文中不需要。 引用末尾添加引用标识:[^1], [^2], 等。引用来自用户提供的文本。 最终回答结构: 1. 问题解释 2. 原因分析 3. 解决步骤 4. 相关问题 </think>### Elasticsearch 出现 [FORBIDDEN/12/index read-only/ allow delete(api)] 错误的解决方法 该错误表明 Elasticsearch 索引处于只读模式(仅允许删除操作,禁止写入),通常由集群磁盘空间不足或资源限制触发,导致 Elasticsearch 自动保护机制激活[^2][^3][^4]。以下是详细解决步骤,基于常见根本原因(如磁盘空间阈值超标)提供方案: --- ### 一、错误原因分析 - **磁盘空间不足**:Elasticsearch 默认设置当磁盘使用率超过 85% 时,索引变为只读;超过 95% 时,完全禁止写入[^1][^4]。 - **其他因素**:高负载请求(如引用[5]中的 `TOO_MANY_REQUESTS`)、手动配置错误或 JVM 内存压力也可能触发类似行为[^5]。 - **错误表现**:写入操作失败,返回 HTTP 403 状态码和 `cluster_block_exception` 异常日志[^2][^3]。 --- ### 二、解决步骤(分步操作指南) #### 步骤 1:检查磁盘空间状态 通过 Elasticsearch API 确认集群磁盘使用情况: ```bash # 检查所有节点的磁盘空间(替换 <your_host> 为 ES 地址) curl -XGET "http://<your_host>:9200/_cat/allocation?v" ``` - **关键指标**:关注 `disk.percent` 列。若值 ≥ 85%,表明磁盘空间不足是主要诱因[^4]。 #### 步骤 2:释放磁盘空间(若磁盘不足) - **清理旧数据**:删除无用索引或过期文档。 ```bash # 删除指定索引(谨慎操作) curl -XDELETE "http://<your_host>:9200/<index_name>" ``` - **扩展磁盘**:如果是生产环境,考虑增加节点磁盘容量。 #### 步骤 3:手动移除只读限制 使用 API 临时解除索引只读状态(**需管理员权限**): ```bash # 移除索引的只读块(替换 <index_name> 为你的索引名) curl -XPUT "http://<your_host>:9200/<index_name>/_settings" -H 'Content-Type: application/json' -d' { "index.blocks.read_only_allow_delete": null } ' ``` - **说明**:此命令直接覆盖索引设置,强制允许写入[^3][^4]。 - **验证**:执行后检查索引状态: ```bash curl -XGET "http://<your_host>:9200/<index_name>/_settings?include_defaults=true" ``` 确保返回结果中 `index.blocks.read_only_allow_delete` 值为 `null` 或 `false`。 #### 步骤 4:调整磁盘阈值(预防未来错误) 修改集群设置,放宽或禁用磁盘保护机制(**仅推荐临时使用**): ```bash # 提高写入阈值(例如:允许磁盘使用至 90% 才触发只读) curl -XPUT "http://<your_host>:9200/_cluster/settings" -H 'Content-Type: application/json' -d' { "persistent": { "cluster.routing.allocation.disk.watermark.low": "90%", "cluster.routing.allocation.disk.watermark.high": "95%", "cluster.routing.allocation.disk.watermark.flood_stage": "98%" } } ' ``` - **警告**:完全禁用保护(`"cluster.routing.allocation.disk.threshold_enabled": false`)可能导致数据损坏,仅用于紧急恢复[^4]。 #### 步骤 5:监控与预防 - **配置警报**:使用 Elastic Stack 的 Kibana 监控模块,设置磁盘使用率警报。 - **优化写入**:批量写入数据(减少单次请求量),避免触发 `TOO_MANY_REQUESTS` 错误[^5]。 --- ### 三、注意事项 - **测试环境验证**:先在开发环境模拟操作,避免生产环境误操作。 - **版本兼容性**:上述 API 适用于 Elasticsearch 7.x+,旧版本语法可能略有不同。 - **根本解决**:长期方案是定期维护磁盘空间和优化索引设计(如使用 ILM 生命周期管理)[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值