• 一个ES设置操作引发的“血案”


    背景说明

    ES版本 7.1.4
    在ES生产环境中增加字段,一直提示Setting index.mapper.dynamic was removed after version 6.0.0错误。但是我只是加一个字段而已啊。
    详细错误

    curl --request PUT --url http://ca.yorkbbs.elasticsearch:9200/object006_bbs_post/_mapping --header 'content-type: application/json' --data '{"properties": {"property_inWeChat": {"type": "long"}}}'
    
    {
    	"error": {
    		"root_cause": [{
    			"type": "illegal_argument_exception",
    			"reason": "Setting index.mapper.dynamic was removed after version 6.0.0"
    		}],
    		"type": "illegal_argument_exception",
    		"reason": "Setting index.mapper.dynamic was removed after version 6.0.0"
    	},
    	"status": 400
    }
    

    产生原因

    直接先说原因吧
    错误的设置了index.mapper.dynamic属生,导致此问题。
    你也可以理解为是es的一个bug,在设置时并没有提醒,可以设置成功,但是设置后修改时,启动时都会判断。
    甚至ES启动也会失败,如果ES被更改错误后,再次启动将会失败,导致无法启动。
    所以,此错误是非常可怕的。
    而且此错误,在当时不一定能发现,可能过了好久,ES出现异常重启时,发现启动不了,这个时候可能连备份都已经没有了。
    我发现这个问题时,还算是比较及时的,在错误的设置完index.mapper.dynamic后,第二天偶然间需要在index中增加一个字段。

    详细过程

    在某一天,我同事发现我们现在生产用的index的字段是自动创建的,在早期的时候都是设置为手动创建的,这样做是为了防止程序出现错误时,导致ES字段爆炸(比如:原来想写入一个字段值,结果把一个对象赋值上去了,结果ES就创建了大量的字段)。所以,我们都会要求把index的字段改为手动创建,当赋值错误时提示错误,或者创建失败。我以前都是用发HTTP请求来完成了,最近一直在用cerebro,了解到里面可以有一个index setting选项,发现里面有一个dynamic的设置,就直接改成flase了。这个操作正式引爆了核弹。
    第二天需要在index中增加一个字段。才发现增加不了,增加的API语句也是以前用过N次了,而且在测试环境也可以正常增加,只有生产无法增加。回想了一下最近的操作,想想前一天设置过es的设置。当时本意是想把ES设置为字段不可能自动增加,只能人工增加。
    以前呢,我都是用API指令修改,哪天呢,发现公司配置的cerebro集群管理工具,有UI的修改界面,觉得有UI,就直接修改吧,于是感觉一定与此有关。
    我用的cerebro版本是0.9.4

    设置界面

    后来分析可能是cerebro工具版本比较早,早期确实是用的index.mapper.dynamic,但是es6.0.0以后就不用了,但是这个工具呢,并没有修改。设置时仍然设置的是index.mapper.dynamic值,刚好呢,es在设置时也没有校验。
    这里觉得ES责任最大,你要不支持,你设置时就提示不支持,不让设置啊。设置时不判断,设置成功了,修改时又不让修改。造成的后果无法修复。
    同时,以后慎用第三方工具吧,至少在测试环境先多测试测试。

    重新创建了一个新的index,就可以添加成功。

    curl --request GET --url http://ca.yorkbbs.elasticsearch:9200/object006_bbs_post
    

    出现错误的原因就在这里,设置的时候没有提示不能设置,设置后再做变更时,提示数据配置文件错误,不允许设置,也无法再修复。
    此命令一定要谨慎执行,在6.0.0以上版本执行可能会引发此问题
    此命令一定要谨慎执行,在6.0.0以上版本执行可能会引发此问题
    此命令一定要谨慎执行,在6.0.0以上版本执行可能会引发此问题

    ### 此命令一定要谨慎执行,在6.0.0以上版本执行可能会引发此问题
    PUT http://127.0.0.1:9200/zpf001/_settings
    Content-Type: application/json
    
    {
        "index": {
            "mapper": {
                "dynamic": "true"
            }
        }
    }
    
    curl --request PUT --url http://127.0.0.1:9200/zpf001/_settings --header 'content-type: application/json' --data '{"index": {"mapper": {"dynamic": "true"}}}'
    
    

    尝试过的解决办法(都失败了)

    由于分析出来原因是因为index setting中错误的设置了dynamic属性,所以解决办法就是删除它(也曾想过改个名字,让ES不认识它),
    通过HTTP请求无法把设置删除,现在只要是修改setting的,都会有这样提示,查看了源码,在操作前进行了这个判断。

    尝试修改名字,也无效。修改名称后,ES连启动都启动不了了。

    在上面位置,可以找到dynamic字段,修改为其他名字,重启无效。ES直接无法启动了。这个时候发现,其实在设置了dynamic后,你的ES就无法启动,因为在启动时,也有上面的版本判断。
    坑爹不!
    至此,已经过去几天了。仍然没有解决

    最后的解决办法

    尝试好多办法都无法解决,那就只能重建ES了,还好我们ES的数据可以从DB恢复。

    建议

    一定要做好备份,比如快照备份,磁盘备份,数据库备份等等。并且在任何操作前,都要做好可以回退的措施,你真的不知道下一秒会发生什么?

    正式设置ES字段为手动创建的HTTP请求

    ### 设置mapping字段手工同步,不自动创建 true 动态添加新的字段—缺省 false忽略新的字段 strict 如果遇到新字段抛出异常
    PUT {{esHost}}/object006/_mapping
    Content-Type: application/json
    
    {
        "dynamic": "strict"
    }
    
    
  • 相关阅读:
    设计模式之装饰者模式
    每天一点点
    生财有道
    地图的移动和缩放
    钱分割
    位运算
    ref和out
    使用startCoroutine制定倒计时
    静态类和单例类
    Awake和Start
  • 原文地址:https://www.cnblogs.com/zhupengfei/p/16367452.html
Copyright © 2020-2023  润新知