低调大师

您现在的位置是:首页>文章详情

文章详情

每日一博 | 详细介绍 Elasticsearch 7 的新特性

2019-10-28 65热度

看了下公司内部用的ElasticSearch集群是 2.3.4 的版本,想升级到新版本,众所周知es这尿性更新速度很快,且有些大版本不向前兼容。

这主要是因为lucene,在大四的时候接触lucene,对它要升级的过程深有感触,除了重建索引,没有别的方法。

所以这次要升级想采用用类似于oracle数据库迁移到mysql的稳妥方法,双写,重建索引是下下策,因为数据量太大,且要保持数据增删查改平稳。

目前我们的问题:

2.3.4 版本及其之前,在并发量高且数据量大的时候,存在数据删除时主分片和副本数据不一致的情况。

所以这几天看了下 ElasticSearch 已经刷版本号到了7了,网上的中文区目前好像也没有对这个版本的一些新特性的详细介绍,所以想着总结一下。(内容来自ElasticSearch官网的更新介绍和官方英文文档)。

感兴趣的朋友也可以参考官方的文档:

https://www.elastic.co/guide/en/elasticsearch/reference/7.4/release-highlights-7.0.0.html

https://www.elastic.co/guide/en/elasticsearch/reference/7.4/release-notes-7.0.0.html

1. 自适应默认副本选择的启用

首先要介绍下什么是自适应默认副本选择,就是说 ElasticSearch 会去记录各个数据节点过去的请求响应时间和在节点上的执行时间,还有节点上的线程池队列大小来得出哪个节点的各项指标好,以后的这种请求就落到这个节点去。

Elasticsearch 6 和之前的版本,对同一分片的一系列搜索请求将以循环方式转发给主分片和每个副本。如果一个节点正好开始了很长时间的垃圾回收(GC),这可能会带来问题,搜索请求仍然可能被转发到这种响应速度会很非常慢的节点,这就会对搜索延迟产生影响。

在6.1版本中,Elasticsearch官方添加了一个实验性的自适应副本选择的特性。每个节点会跟踪和比较搜索请求与其他节点的耗时,并使用这个数据调整向特定节点上的分片发送请求的频率。在官网的基准测试中,这会很显著的提高搜索的吞吐量,官方说这种操作减少了99%的延迟。

这个配置在整个6.x的版本中被默认是禁用的。但是后来官方陆续从用户那里得到反馈,用户和官方都认为这个设置非常有用,所以官方在Elasticsearch 7.0.0中默认打开了它。

PUT /_cluster/settings { "transient": { "cluster.routing.use_adaptive_replica_selection": true } } 

如果关闭这个功能,搜索的操作将会以循环方式发送到所有的索引分片。

Skip shard refreshes if a shard is "search idle

2. 如果该分片是搜索空闲时刻,则跳过碎片刷新

Elasticsearch 6 和之前的版本默认情况下会在后台自动刷新索引数据。这也就是为什么Elasticsearch可以“近乎实时”得到搜索结果,默认情况下,搜索请求添加后一秒内就可以获得结果。然而,如果不需要刷新的时候(例如,如果Elasticsearch没有任何查询搜索的任务),那么这个功能就能对Elasticsearch的性能产生显著的影响。

通过引入这种搜索空闲(search idle)的概念,Elasticsearch 7 在默认情况下,该分片如果在30秒内没有过任何搜索行为,那么这个就会被认为是搜索空闲。 当分片处于这种阶段的时候,所有原计划的刷新任务都会被跳过,直到你有搜索的问题进来的时候才会触发下一次的刷新任务。 这会提高 Elasticsearch 的吞吐量,我们都知道,当如果要大量的写入数据或者重新构建索引的时候,关闭自动刷新进行数据写入或者更新,速度是可以显著提高的,这里同理。

3. 默认一个分片

很多公司在使用 Elasticsearch 的时候很乱来,其中比较多的就是过度分片,而分片数量的默认值可能是个造成这种现象的主要原因。Elasticsearch 6和之前的版本,每个索引默认有5个分片。如果有一个针对10个不同的应用的每日索引(按日建的索引,类似于数据库的按日分表),并且每个应用程序默认有5个分片,那么每天将创建50个分片,即使每天只有几个gb的索引数据,不久之后将会出现数千个分片。

索引生命周期管理是帮助实现这点的第一步: 提供了本地方法按大小来创建索引,而不是仅仅按天来创建索引,并且提供内置的收缩功能来减少每个索引的分片数量。 其次就是减少索引的默认分片数量。 当然,如果创建索引的时候我们依然可以自己设置分片数量,如果不设置就会是默认值1.

4. Lucene 8

这个是重头戏,这里我要插一下,2015年大四还没毕业的时候,对这种索引技术不是非常深入了解,想要升级一个项目的Lucene版本,那时候用的还是3.x的版本,要升级到4.x,简直是噩梦。

与每一个版本一样,官方都是希望支持Lucene的最新的主要版本,以及它带来的所有的特性。Elasticsearch 7.0 底层用的是 Lucene 8 , Lucene 8为Elasticsearch的许多功能的改进奠定了基础,包括对top-k查询的搜索性能的改进(top-k,可以用于在海量数据里查找最大或者最小的K个值,我思考了下方法有很多,比如用默认的前1000个值的最小堆和所有数据进行对比;还可以对数据进行分割然后使用快排。。。),以及在保持速度的同时更好地组合相关信号标识进行搜索,提高性能。

5. 在跨集群搜索中引入耗时最小路径的功能

在Elasticsearch 5.3中,官方引入了跨集群搜索的功能,允许用户跨多个集群进行查询。后面官方对跨集群搜索的这套功能进行了改进,增加了一些特性,最终将其用于弃用和替换tribe节点(tribe 节点,tribe节点是跨多个集群的联合客户端节点,通常用于从多个Elasticsearch集群检索信息,使其看起来像一个组合集群,详情可以去看下官方的跨集群搜索功能,根据官方的文档,tribe 节点在7.0版本被移除废弃。),从而实现联合查询。

在Elasticsearch 7.0中,官方为跨集群搜索添加了一种新的执行模式:在不必要的情况下减少往返的耗时。这种模式(ccs_minimize_roundtrips)可以在跨集群搜索查询避免高延迟(例如,跨网络)从而更快的得到搜索结果。

6. 新的集群协调实现

Elasticsearch 从设计之初就是易于扩展的,且这种设计能很好的应对灾难性的故障。为了更好的支持这类需求,官方创建了一个可插拔的集群协调系统,其默认实现称为Zen Discovery(大致的意思就是这个功能想简单点来实现,你们用户放心使用就好了,这个功能是官方引入的集群发现机制), Elasticsearch使用量的急剧增加暴露了很多问题,例如,Zen的minimum_master_nodes设置经常配置错误,这会使群集更容易出现裂脑和丢失数据的风险。 跨集群(集群是动态的且非常大),因为维护此设置很困难。

在Elasticsearch 7.0,重新设计了集群协调层。 新的实现提供了安全的亚秒级的master选举时间,而Zen可能要花几秒钟来选择一个新的master,这对于关键时候的部署来说,这时间是宝贵的。删除minimum_master_nodes设置后,集群的增长和收缩变得更安全、更容易,减少了因为系统错误配置埋坑。最重要的是,新的集群协调层为Elasticsearch的未来提供了强大的健壮性,确保将来可以为这个模块设计更高级的功能扩展。

7. 对小堆的更好支持(真实内存断路器)

Elasticsearch使用时 7.0加了一个全新的断路器,可以跟踪JVM使用的总内存,如果请求导致预留的内存和实际堆使用量超过95%,则拒绝请求。官方还将更改默认的最大桶数search.max_buckets为10000,这在6及之前的版本中是不受限制的。在Elasticsearch 7这两个改动,可以防止新手菜鸟第一次玩的时候运行大型查询和聚合操作引起的集群故障。

8. 跨集群复制已经可以用于生产环境

官方在Elasticsearch 6.5中引入了一个beta功能,跨集群复制。现在在7.0这个功能已经完善成熟,可以用于生产环境。 以前版本的跨集群复制要求复制只能在新索引上开始,无法复制现有索引。现在,跨集群复制可以开始复制在6.7和7.0中启用了软删除的现有索引,并且新索引默认为启用了软删除。还引入了一些很新的技术防止follower严重落后于leader(没有说明是啥新的技术),官方在特意在Kibana中添加了一个管理UI,用于配置远程集群。

9. 索引生命周期管理已经可以用于生产环境

索引生命周期管理(ILM)是Elasticsearch 6.6中的beta功能。现在已将ILM正式从Beta版迁移到GA版! ILM使得在Elasticsearch中管理数据的生命周期变得更简单,包括数据在hot,warm,cold,delete阶段之间的进度情况。可以通过Elasticsearch中的API来看,或者Kibana中漂亮的UI来创建有关数据如何在这些阶段中移动的情况。

在Elasticsearch 6.7和7.0中,ILM现在可以管理冻结索引。冻结索引对于Elasticsearch中的长期数据存储很有价值,并且相对于节点管理的数据量而言,需要的存储量(堆)更小。在6.7和7.0中,现在可以将冻结的索引作为ILM中cold阶段的一部分进行冻结。此外,ILM现在可以直接与跨集群复制(CCR)一起使用,CCR在Elasticsearch 6.7和7.0版本中也都采用了GA。 ILM是免费使用的,并且是Elasticsearch的默认发行版的一部分。

10. SQL 已经可以用于生产环境

Elasticsearch的SQL接口现在是GA。 SQL界面在6.3中作为Alpha发行版引入,熟悉SQL的可以直接使用Elasticsearch来查询需要的数据,它还允许使用SQL的BI工具轻松访问Elasticsearch中的数据。 不仅仅是这些,使用JDBC和ODBC驱动程序访问也可以了,也就是说目前官方支持四种方法可以访问: Elasticsearch SQL,通过Elasticsearch REST端点、Elasticsearch SQL接口、JDBC、ODBC。

11. 高级REST客户端功能完善

官方为这个功能已经准备了很久很久了:创建用于访问Elasticsearch集群的下一代Java客户端。 这里插一下嘴,其实我一直喜欢用rest访问es,真的简单方便。

12. 支持纳秒时间戳

7.0之前,Elasticsearch只能存储毫秒级的时间戳。 如果要处理发生率较高的情况,例如,如果要在Elasticsearch中存储和分析跟踪网络数据包数据,则可能需要更高的时间精度。 从过去的经验上来看,我们曾使用Joda时间库来处理日期和时间,而Joda缺乏对如此高精度时间戳的支持。 在JDK 8中,引入了正式的Java时间API,该API也可以处理纳秒级的精确时间戳,并且在过去的一年中,官方一直在努力将Joda时间使用情况迁移到本机Java时间,同时试图保持向后兼容性。 从7.0.0版本开始,可以通过专用的date_nanos字段映射器使用这些纳秒级的时间戳。 请注意,此字段的聚合仍处于毫秒级分辨率,以避免发生存储桶爆炸(好担心用这个词会被和谐掉)。

13. 更快的检索热门内容

在搜索方面,查询性能是一项关键功能。对于不需要精确的命中数为结果数设置返回数据的下限就可以了,Elasticsearch 7.0中的搜索性能有了显着提高。例如,如果用户通常只查看网站上结果的第一页,而不在乎匹配的文档有多少,那么可以向他们显示“超过10,000个结果”,然后为他们提供分页结果。 用户在查询中输入频繁出现的词(例如“ the”和“ a”)是很常见的,从过去经验来上看,即使这些频繁出现的词条可能并没有太大意义,但是Elasticsearch也会为它们打分。 在这种情况下,Elasticsearch现在可以跳过这些分值很高却无太大意义的词。这样可以大大提高查询速度。 得分最高的实际结果的实际数量是可配置的,但默认值为10,000。结果集小于此阈值的查询的行为不会改变,也就是说结果数是准确的,但是对于少量匹配结果的查询,性能没有改善。 由于改进是基于跳过低排名的记录,因此不适用于聚合操作。

14. 支持TLS 1.3

Elasticsearch一直是支持加密通信的,官方最近开始支持JDK 11(关于JDK11的介绍可以看我以前的博客 https://my.oschina.net/110NotFound/blog/3046749 ),它提供了很多新功能。 JDK 11现在支持TLSv1.3,因此从7.0开始,在Elasticsearch中为运行JDK 11的用户提供TLSv1.3的支持。为了帮助新用户避免无意中以低安全性运行,所以删除了TLSv1 .0(默认值)。 对于运行旧版Java的用户,官方提供了具有TLSv1.2和TLSv1.1的默认选项。

15. 将JDK捆绑在Elasticsearch

官方说很多用户最突出的入门障碍是不知道Elasticsearch是Java应用程序(如果用户群体不是熟悉java的开发人员,这的确会是一个很大的问题,话说回来,开发人员本身不应该局限于某种语言)。 在7.0中,Elasticsearch捆绑了一个OpenJDK发行版,以帮助用户更快地开始使用Elasticsearch。 同时也支持用户自己配置JDK。 如果想使用自己机器环境的JDK,仍然可以通过在启动Elasticsearch之前设置JAVA_HOME来实现。

16. Rank features

Elasticsearch 7.0有几种新的字段类型,可以最大程度地利用数据。 两个核心的可以有助于搜索的用例方法是 rank_featurerank_features 。 它们可用于增强基于数值或分类值的文档。

rank_feature 与分数负相关的排序特性应该将positive_score_impact设置为false(默认为true)。rank_feature 查询将使用它来修改评分公式,使评分随特性值的增加而减少,而不是增加。例如在网络搜索中,url长度是一个常用的与分数负相关的特征。

PUT my_index { "mappings": { "properties": { "pagerank": { "type": "rank_feature" }, "url_length": { "type": "rank_feature", "positive_score_impact": false } } } } PUT my_index/_doc/1 { "pagerank": 8, "url_length": 22 } GET my_index/_search { "query": { "rank_feature": { "field": "pagerank" } } } 

rank_features 字段可以在索引数值特征向量,以便以后可以使用rank_feature查询来增强查询中的文档。 它类似于rank_feature数据类型,但更适合特性列表稀疏的情况,因此不太可能为每个映射添加一个字段。

PUT my_index { "mappings": { "properties": { "topics": { "type": "rank_features" } } } } PUT my_index/_doc/1 { "topics": { "politics": 20, "economics": 50.8 } } PUT my_index/_doc/2 { "topics": { "politics": 5.2, "sports": 80.1 } } GET my_index/_search { "query": { "rank_feature": { "field": "topics.politics" } } } 

17. JSON日志

除了纯文本日志外,官方在Elasticsearch中启用了JSON日志记录。 从7.0开始,可以在日志目录中找到扩展名为.json的新文件。 这意味着现在可以使用 jq 之类的过滤工具以更加结构化的方式漂亮地打印和处理日志。

18. 脚本评分查询(又叫做函数评分2.0)

在7.0中,出现了下一代功能评分功能。 这个新的 script_score 查询提供了一种新的,更简单且更灵活的方式来为每条记录生成排名分数。 script_score 查询由一组函数构成,其中包括算术和距离函数,用户可以任意搭配这些函数来构造任意的函数进行得分计算。 模块化结构更易于使用,所以向用户开放这个重要的功能。

这个功能是实验性的,在将来的版本中可能会完全改变或删除。

总结(吐槽)

不得不说 Elasticsearch 的更新进步是非常快的,从我大学最后一个学期知道这个组件的时候到现在,版本已经飙升到了7,很多特性也在发生变化,使用群体也增长很快,在检索方面真的非常非常的强,当然缺点也有,比如低版本的升级很麻烦,很费资源等等。。。 很多公司在用 Elasticsearch 的时候好像对这个东西本身并不是很了解,觉得要快速检索,所以就用了,更甚至有用它做数据库,可能是使用场景比较特殊所以敢这么大胆。没有数据一致性的保障,如果出现主分片和副本不一致的时候,哭都没地哭,重建索引?

收藏 (1)

相关文章

    文章评论

    共有0条评论来说两句吧...