背景
公司采用ELK架构来搭建公司的日志系统
某天早上来公司查看某个系统日志时,一直没有数据,感觉应该是ELK架构出现了问题;
打开es后台查看日志,没有明显的价值信息;
然后打开logstash,发现后台系统一直在报错
bash
{:status=>403, :action=>["index", {...xxx}message: "blocked by: [FORBIDDEN/8/index write (api)];: [cluster_block_exception] blocked by: [FORBIDDEN/8/index write (api)];"
产生原因
出现这种问题一般情况是ES服务主动阻止写入,以保护群集不会达到红色或黄色状态。它使用index.blocks.write
完成此操作。
其中主要原因如下:
内存不足
当JVMMory压力指标在30分钟内超过92%时,Amazon ES会触发保护机制并阻止所有写操作,以防止集群进入红色状态。当保护开启时,写入操作失败,并出现ClusterBlockException错误,无法创建新索引,并引发IndexCreateBlockException错误。
当JVMM一带压指标在5分钟内恢复到88%或更低时,保护被禁用,对集群的写操作被解锁。
磁盘空间不足
ElasticSearch的默认"低水位线"为85%,这意味着一旦磁盘使用率超过85%,Elasticearch就不再为该节点分配碎片。ElasticSearch的默认"高水位线"为90%,此时它会尝试将碎片重新定位到其他节点。
索引权限问题
这个问题主要发生在主动请求写入或者删除文档的时候会出现
如果按照一定的规则进行索引归档,或者将索引设置为只读,那么也会出现上述问题的
比如我目前是按照日期来定义索引生命周期的,索引一旦过了2天,就会变为只读,那么这个时候我主动请求删除索引里面的数据时,是会报上述错误的!
解决方案
内存不足
如果是内存问题,首要找的什么原因导致内存不足,是业务量突然变大很多还是其他原因,可以按照如下方向进行排查:
- segment memory
- filter cache
- field data cache
- bulk queue
- indexing buffer
- state buffer
- 超大搜索聚合结果集的fetch
- 对高cardinality字段做terms aggregation
- 业务量是否突然增多
针对不同的问题,进行针对性的优化
如果对ES做了监控,可以直接去监控面板进行查看,看内存是否充足;
如果没有,可以使用下列命令来进行简单查看
查看集群状态(可以清楚的知道各个node节点的内存cpu使用情况,比如jvm、os、segment、translog等等信息)
bash
# -u 代表用户名密码,如果没有权限认证,可以忽略
curl -u elastic:xxx -X GET "http://127.0.0.1:9200/_nodes/stats?pretty"
磁盘不足
磁盘不足的话,可以查看是哪些索引占用较大,是否可以删除,然后进行扩容或者清洗步骤
查看磁盘使用情况
bash
curl -u elastic:xxx -s 'localhost:9200/_cat/allocation?v'
权限问题
修改权限即可,执行下列命令
更改所有索引权限
bash
PUT /_all/_settings
{
"index.blocks.write": null
}
更改指定索引权限
bash
PUT /索引名称/_settings
{
"index.blocks.write": null
}
扩展
对于index.blocks.write究竟有什么用,为什么要有这个参数,我们可以了解一下
在日常管理 Elasticsearch 时,我们经常需要对索引进行保护,以防止数据被意外修改或删除,特别是在进行系统维护或者需要优化资源使用时。
Elasticsearch提供了一种名为"索引阻塞(Index blocks)"的功能,让我们能够限制对某个索引的操作类型。
大白话------"索引阻塞"就是给我们的索引加把锁,防止别人随意修改。
索引阻塞的种类
Elasticsearch中的索引阻塞可以根据需要,限制对索引的读取、写入或元数据操作。
所谓的元数据,可以理解为索引的基本信息和设置,比如索引包含哪些字段,这些字段是什么类型的等等。
以下是一些动态索引设置,用于确定索引上存在的阻塞类型:
- index.blocks.read_only:设置为 true 使索引及索引元数据只读,设置为false则允许写入和元数据更改。
- index.blocks.read_only_allow_delete:类似于index.blocks.read_only,但也允许删除索引以释放更多资源。
- index.blocks.read:设置为 true 以禁用对索引的读取操作。
- index.blocks.write:设置为 true 以禁用对索引的数据写入操作。与read_only不同,这个设置不影响元数据。例如,你可以调整带有写入阻塞的索引的设置,但不能调整带有read_only阻塞的索引的设置。
- index.blocks.metadata:设置为true以禁用索引元数据的读写操作。
什么时候使用索引阻塞
场景1:进行系统维护场景。
比如,当你需要升级系统或者做一些关键的维护工作时,可能不希望在这期间有任何索引结构的变化。
通过阻止别人修改索引的元数据,确保索引的设置保持不变,维护索引设置的稳定性。
场景2:保护数据不被随意更改场景。
举例:如果咱们的业务数据是非常关键的,比如已经归档的日志或者历史记录,这些数据通常是不允许被更改的。
防止关键数据被随意更改或删除,确保数据的完整性和准确性。
场景3:优化资源使用的场景。
举例:有时候某个索引可能占用了太多资源,你可能暂时不想让它继续增长。
通过控制索引的读写操作,帮助管理系统资源,避免因为资源过度使用而导致系统变慢或崩溃。
场景4:遵守安全规则场景。
举例:对于一些敏感数据,可能要求严格的访问控制,不希望随便被读取或更改。
对于需要严格控制的敏感数据,通过设置阻塞来限制数据的访问和修改,保障数据安全。
参考文献
Elasticsearch 通过索引阻塞实现数据保护深入解析
[es删除报错 blocked by FORBIDDEN8index write (api)]_java es 删除数据报错