总结最近半年对Elasticsearch开源项目的贡献
自从2019年对Elasticsearch项目提交过一次代码之后,开始逐渐关注社区里的新动态,并且尝试去解决一些看起来容易上手的issue,通过这个过程去理解源码从而可以深入理解Elasticsearch的实现机制,从中受益颇丰。现在把最近半年(2020年1月-2020年6月)对Elasticsearch项目所做的工作进行一次总结,记录遇到的问题和解决办法。
ingest set processor增加ignore_empty_value参数
issue: #54783
PR: #57030
使用ingest set processor时, 如果对于value字段为空字符串或者null的情况不需要进行处理,当前只能通过脚本判断value是否为空字符串或者null。本次提交对set processor增加了ignore_empty_value参数,设置该参数为true后,set processor会自动规避value字段为空字符串或者null的情况, 不对文档进行任何修改,优雅的退出处理逻辑。
修复reindex api bug
issue: #52786
PR: #54901
调用reindex api,当max_docs参数<slices时,会报错max_docs为0,实际上是因为没有提前校验max_docs是否<slices,导致max_docs被设置为0。本次提交修复了这个bug,并且给出比较清晰的错误提示。
当使用date_nanos字段作为过滤条件并且使用now时,无法创建filtered alias
issue: #54315
PR: #54785
PUT date_source/_alias/date_nanos_alias
{
"filter": {
"range": {
"date_nanos": {
"gt": "now-7d/d"
}
}
}
}
如上述操作,创建filtered alias时,以date_nanos字段为过滤条件,并且使用了now,会导致创建别名失败;该提交主要是修改了queryShardContext中的nowInMillis值,设置为当前时间戳。
禁止修改nested字段的include_in_root、include_in_parent参数
issue: #53792
PR: #54386
nested字段的include_in_root、include_in_parent参数,是无法进行修改的,但是当前调用PUT {index}/_mapping API进行修改时却没有报错,本次提交的改动是在修改两个参数时抛出400参数错误。
对所有处理字符串类型的ingest processor,支持字段值为数组
issue: #51087
PR: #53343
对Lowercase Processors、Uppercase Processors、Trim Processors等处理字符串类型的ingest processor, 都支持要处理的字段类型为数组类型。
修复_search/template API返回结果总量不准的bug
issue: #52801
PR: #53155
调用GET _search/template API时,如果设置了rest_total_hits_as_int为true,处理逻辑应该和GET _search API一致,trackTotalHitsUpTo变量会被设置为Integer.MAX_VALUE,因此都能够获取到准确的total hits count。但是在_search/template API的处理逻辑中,虽然rest_total_hits_as_int设置为了true, trackTotalHitsUpTo值却没有被设置,因此只能获取到最多为10000的total hits。
修复ingest pipeline simulate API异常处理bug
issue: #52833
PR: #52937
调用POST
_ingest/pipeline/_simulate API时,如果传入的docs参数是空列表,则什么结果都不会返回。
Bug产生的原因是,在异步请求的ActionListener中没有对docs参数进行判空,导致始终没有响应给客户端。
修复删除enrich policy时的bug
issue: #5122.
PR: #52179
enrich policy关联的索引名称的格式为[policy_name]-*,在调用删除enrich policy的API:DELETE /_enrich/policy/<policy_name>时,需要删除所有的以[policy_name]开头的索引,因为代码直接通过通配符进行删除,如果设置了action.destructive_requires_name
参数为true,则删除enrich policy会报错‘Wildcard expressions or all indices are not allowed’. 本次提交的改动是不直接通过通配符删除索引,获取到所有的索引名称后进行批量删除。
当因磁盘写满而导致ES自动对索引设置read_only_allow_delete block时,对http请求返回429状态码而不是403
issue: #49393
PR: #50166
这个提交有意思了,耗时也非常久,中间经过数次代码调整与优化。这个改动的初衷是因为在磁盘写满的情况下,ES会自动地把对应节点上的索引设置为只读(index.read_only_allow_delete=true), 后续有新的写入请求进来后,会直接返回403状态码拒绝进行写入。实际上,ES对所有类型的block,对应的http状态码都设置为403, 这就会导致一个问题,在部分客户端比如rest client碰到403的状态码,是不会对写入请求进行重试的,直接丢弃掉请求,导致数据丢失。所以该提交就需要针对因为index.read_only_allow_delete为true的情况,返回429状态码(429意思是TOO_MANY_REQUESTS, 请求太多,需要限流)。在提交代码之后,和社区的maintainer针对单元测试代码经过数次讨论,最终才被合并进master分支。讨论的焦点在于,6.8版本之后,如果磁盘空间释放出来,索引的只读的状态会被自动的release,有单独的线程轮询检查磁盘来确定要不要释放只读状态,所以需要对auto release机制是否开启进行随机选择。一方面,auto release开启,因为客户端接收到429状态码,写入请求经过重试后能够成功执行;另一方面,关闭auto release, 写入请求经过数次重试后仍然执行失败而报错。
elasticsearch-croneval工具异常捕获
issue: #49642
PR: #49744
elasticsearch-croneval工具是一个社区提供的用于校验cron表达式是否正确的一个工具,放置在elasticsearch安装目录的bin目录下。该工具的执行实际上调用了项目中的CronEvalTool类的main方法,实际上在执行的过程中,因为没有正确地捕获异常,导致在对非法的cron表达式进行校验时,工具直接把整个stacktrace信息都打印出来了。针对这个issue所做的提交捕获了这个异常,并给出了较为简明的错误信息。第一次提交之后,项目的maintainer表示要对这个改动进行team-discuss, 最终讨论下来的结果是:对该工具增加一个默认关闭的命令行参数,如果用户有需要查看完整的异常信息,添加该参数即可,默认情况下只显示简短的错误信息。
自定义normalizer无法使用bug修复
issue: #48650
PR: #48866
该bug是在7.x版本引入的,因为对自定义analyzer的代码进行了重构,导致所有custom normalizer都无法正常使用。可能因为normalizer的使用者并不是很多,一直到7.5发布后才被发现,该提交在7.6版本已经发布。关于这个bug的修复,有单独一篇文章进行介绍记一次向Elasticsearch开源社区贡献代码的经历.