百分点大数据技术团队:Elasticsearch多数据中心大规模集群的实战经验

编者按 :Elasticsearch(简称ES)作为一种分布式、高扩展、高实时的搜刮与数据分析引擎,能使数据在生产环境变得更有价值,自ES从诞生以来,其应用越来越广泛,特别是大数据领域,功能也越来越强

编者按 :Elasticsearch(简称ES)作为一种分布式、高扩展、高实时的搜刮与数据分析引擎,能使数据在生产环境变得更有价值,自ES从诞生以来,其应用越来越广泛,特别是大数据领域,功能也越来越强大。但当前,ES多数据中心大规模集群依然面临着数据量大、查问周期长、集群规模大、聚拢分析要求高等诸多挑战。本文针对当前面临的问题,结合百分点大数据技术团队在某海外国家级多数据中心的ES集群建设经验,总结了ES集群规划与本能调优方法,供工程师们参考一、ES集群建设实践1. 集群拆分集群规模过大会导致Master节点压力比较大,造成索引的创建删除、分片分配等操作较慢,严重影响集群稳定性。所以将集群进行拆分,业务上ES集群保存三种业务类型数据A、B、C,数据占比大约A:B:C=8:3:1,根据业务类型,拆分A数据类型6个集群,B数据类型2个集群,C数据类型2个集群,保存在两个中心机房,每一个集群不超过100个节点。(推荐集群节点数不要超过服务器核心数 * 5)利用跨集群搜刮(Cross-cluster search),客户端在查问数据的时候连接Query集群,通过Query集群查问10个数据集群的数据。百分点大数据技术团队:Elasticsearch多数据中心大规模集群的实战经验

2. 角色分离

ES集群中有多种角色,协作(coordinator)节点,主(master)节点,数据(data)节点。一台节点可以设置装备摆设成多种角色,角色分离可以避免各种角色本能互相影响。比如一个节点既是数据节点也是协作节点,可能协作角色聚拢时占用大量资源导致数据角色写入数据出现异常。通过设置装备摆设elasticsearch.yml来使一个节点只承担一种角色。主节点:当有一半主节点下线整个集群也就不可用了,一般一个集群树立3台主节点,可以容许一台主节点下线。不要设置装备摆设偶数台主节点,因为设置装备摆设4台主节点也仅能容许一台主节点下线。node.master: true node.data: false数据节点:根据自己的数据情况设置装备摆设合适的节点数量。数据节点下线会导致数据不完整,集群仍能正常工作。node.master: false node.data: true协作节点:任何一个节点都可以是协作节点,我们通过设置装备摆设几个仅协作节点来单独行使协作功能。node.master: false node.data: false3. 版本选择在当初项目选型的时候,ES刚刚发布7.X,我们选择相对稳定的6.7.2版本,在后期大规模测试过程中发现,6.X版本有些局限性,此时ES已经发布7.8版本了。通过调研最终选用7.6.2版本,原因主要有下面两点:(1)元数据压力在6.7.2版本,集群shard个数达到5w时,更新template或创建index会出现大于30s的情况。详细参考问题页:https://github.com/elastic/elasticsearch/pull/47817在7.6.2版本,集群shard个数达到5w时,更新template或创建index在3s内。我们shard个数最多的集群达到了4.4w。(2)跨集群搜刮(Cross-cluster search)当存在三个集群:Query集群、data1集群、data2集群时,设置装备摆设data1、data2集群为Query集群的远程集群,此时可以通过向Query集群发送哀求来获取data1、data2集群的数据。跨集群搜刮提供了两个处理网络延迟的选项:最小化网络传输您向Query集群发送跨集群搜刮哀求,Query集群中的协作节点接收并解析哀求;协作节点向每一个集群(包括Query集群)发送单个搜刮哀求,每一个集群独立执行搜刮哀求,将其自己的集群级别树立应用于哀求;每一个远程集群将其搜刮结果发送回Query集群的协作节点;从每一个集群收集结果后,Query集群的协作节点在跨集群搜刮响应中前往最终结果。不利用最小化网络传输您向Query集群发送跨集群搜刮哀求,Query集群中的协作节点接收并解析哀求;协作节点向每一个远程集群发送搜刮分片API哀求;每一个远程集群将其响应发送回协作节点,此响应包含有关将在其上执行跨集群搜刮哀求的索引和分片的信息;协作节点向每一个分片发送搜刮哀求,包括其自己集群中的分片,每一个分片独立执行搜刮哀求;每一个分片将其搜刮结果发送回协作节点;从每一个集群收集结果后,协作节点在跨集群搜刮响应中前往最终结果。更详细的说明参考:https://www.elastic.co/guide/en/elasticsearch/reference/7.6/modules-cross-cluster-search.html#ccs-min-roundtrips最小化网络传输会减少与远程集群之间的网络往返次数,这减少了网络延迟对搜刮速度的影响,同时各个远程集群的协作节点会预先将自己集群的数据聚拢一次。即便如此,Query集群协作节点压力还会比较大,因为要聚拢所有集群前往的数据。我们根据最小化网络传输流程图,分析如下聚拢时协作节点的压力:百分点大数据技术团队:Elasticsearch多数据中心大规模集群的实战经验coordinator node2和coordinator node3接收各自数据节点的1w条数据(shard数 * shard_size)并全量前往给coordinator node1,最终在coordinator node1上会有2w条数据,取前10条(size)前往给客户端。当我们查问的集群、索引或者索引的shard更多时,coordinator node1的压力会越来越大。测试过程中总会出现OOM的情况。基于此考虑,我们窜改部分源码,增加了coordinator_size参数,在第3步数据集群将搜刮结果发回coordinator node1时只前往TOP N(前coordinator_size)。对于一个集群,通过shard_size来平衡精度与本能;对于整个跨集群方案,通过coordinator_size来平衡精度与本能。不利用最小化网络传输由于数据不会经过coordinatornode2和coordinator node3,所以不支持这样的窜改。在6.7.2版本,跨集群搜刮只支持不利用最小化网络传输的方式。在7.6.2版本,默许利用最小化网络传输的方式进行跨集群搜刮,可以在哀求中添加ccs_minimize_roundtrips:false参数来选择不利用最小化网络传输。

4. 拆分索引

业务上保存的是日志数据,只有增加,没有变更,按时间累积,天然对索引的拆分友好支持,并且如果按天拆分索引有以下好处:方便数据删除,超过保存周期的数据直接利用定时脚本在夜间删除索引即可;提升搜刮聚拢的效率,业务上对数据的搜刮必须要携带时间范围的参数,根据该时间参数转化为具体的索引这样搜刮的shard就会比较少;方便后期窜改shard个数和mapping,虽然shard个数和mapping一般不窜改,但也会遇到特殊情况,如果需要窜改,我们只需要窜改template,之后新索引都会应用最新的shard树立和mapping树立,等业务滚动数据保存周期天数后所有数据就都会应用最新规则。

5. 副本数量

越多的副本数量会增加搜刮的并发数,但是同时也会影响写入索引的效率,占用磁盘空间。可以根据数据安全性来树立副本的数量,一般一个副本是足够的,同时可以考虑在索引创建时拥有更多的副本,当数据超过一定时间而变得不那么重要后,通过API减少副本个数。二、ES集群设置装备摆设经验1. 内存和CPU(1)内存分配Lucene能很好利用文件系统的缓存,它是通过系统内核管理的。如果没有足够的文件系统缓存空间,本能会受到影响。此外,专用于堆的内存越多意味着其他所有利用doc values 的字段内存越少。参考以下原则:当机器内存小于64G时,遵循通用的原则,50% 给 ES,50% 留给 lucene。当机器内存大于64G时,遵循以下原则:如果主要的利用场景是全文检索,那么建议给ES Heap分配4~32G的内存即可;其它内存留给操作系统,供lucene利用(segments cache),以提供更快的查问本能;如果主要的利用场景是聚拢或排序,并且大多数是numerics,dates,geo_points以及非分词的字符串,建议分配给ES Heap 4~32G的内存即可,其余部分留给操作系统来缓存doc values;如果利用场景是基于分词字符串的聚拢或排序,意味着需要fielddata,这时需要更多的heap size,建议机器上运行多ES实例,每一个实例保持不超过50%的ES heap树立。内存设置装备摆设不要超过32G,如果堆大小小于32GB,JVM可以利用指针压缩,这可以大大降低内存的利用:每一个指针4字节而不是8字节。这里32G可能因为某些因素的影响有些误差,最好设置装备摆设到31G。内存最小值(Xms)与最大值(Xmx)的大小设置装备摆设相等,防止程序在运行时改变堆内存大小,这是一个很耗系统资源的过程。设置装备摆设jvm.options-Xms31g -Xmx31g(2)GC树立保持GC的现有树立,默许树立为:Concurrent-Mark and Sweep(CMS),别换成 G1 GC,因为目前G1还有很多BUG。(3)禁止swap禁止swap,一旦允许内存与磁盘的交换,会引起致命的本能问题,可以通过在 elasticsearch.yml 中设置装备摆设以下参数以保持JVM锁定内存,保证ES的本能。bootstrap.memory_lock: true(4)核心数processors设置装备摆设参数的值决定了节点allocated_processors的参数值,而ES很多线程池的大小都是基于allocated_processors的值来计算的。窜改elasticsearch.ymlelasticsearch.ymlnode.processors: 56在以下情况可以考虑调整该参数:在一台服务器部署多个ES实例,此时调整参数为处理器实际核心数一半;错误地检测处理器的数量,此时调整参数进行修正;实际处理器核心数大于32,ES默许处理器核心数最大限制为32个,如果物理机的处理器核心数超过了32个,为了更充分利用CPU,可以调整参数为实际处理器核心数。如果可以选择CPU,更多的核心数比更快的CPU更有意义。

2. 写入

(1)增加Refresh时间间隔

ES写入数据时先写入memory buffer中,memory buffer会周期性(index.refresh_interval默许1s)或者写满后做refresh操作,将内容写入到一个新的segment中。此时数据可以被搜刮,这就是为什么ES提供的是近实时的搜刮。如果系统对数据延迟要求不高的话,通过延长refresh时间间隔(比如index.refresh_interval树立为30s),可以有效地提高索引速度,同时减少segment个数降低segment合并压力。窜改索引的settings:PUT /my_index/_settings { “index” : { “refresh_interval” : “30s” } }在导入大量数据的时候可以暂时树立index.refresh_interval: -1和index.number_of_replicas:0来提高本能,数据导入完成后还原树立。

(2)窜改index_buffer_size的树立

上一条说memory buffer写满时也会触发refresh操作,为了减少refresh操作,我们同时也要配合增加memory buffer的大小。这是一个全局静态设置装备摆设,会应用于一个节点上所有的分片上。窜改elasticsearch.yml:# 接受百分比或字节大小值。它默许为10%,这意味着10%分配给节点的总堆中的将用作所有分片共享的索引缓冲区大小。 indices.memory.index_buffer_size: 10% # 如果index_buffer_size指定为百分比,则此树立可用于指定绝对最小值。默许为48mb。 indices.memory.min_index_buffer_size: 48mb # 如果index_buffer_size指定为百分比,则此树立可用于指定绝对最大值。默许为无界。 indices.memory.max_index_buffer_size: 10240mb

(3)窜改translog相关的树立

refresh操作后,数据写入segment文件中,此时segment在OS Cache中,以上所有数据都保存在内存里,如果服务器异常重启则数据都不可恢复。所以数据在写入memory buffer的同时,记录当前操作到translog,每30分钟或者当translog中的数据大小达到阈值后,会触发一次flush操作将OS Cache中的segment落盘,同时清理translog。translog默许在每次索引、删除、更新或批量哀求后会提交到磁盘。我们可以通过树立使translog异步提交来提高本能:PUT /my_index/_settings { “index” : { “translog.durability”: “async”, # 刷新方式。默许request 同步, async 异步 “translog.sync_interval”: “10s” # 刷新频率。默许5s,不能低于100ms } }也可以控制translog的阈值来降低flush的频率:PUT /my_index/_settings { “index” : { “translog.flush_threshold_size”: “1024mb” # translog阈值。默许512mb。如果达到则会强制flush,否则需要等待30分钟 } }3. 分配

(1)延迟分配设置装备摆设

当集群中某个节点离开集群时:master节点会将此节点上的主分片对应的副本分片提升为主分片;在其他节点上重建因节点下线而丢失的分片;重建完成后很可能还会触发集群数据平衡;如果节点又重新加入集群,集群数据自动平衡,将一些分片迁移到此节点。节点很可能因为网络原因或硬件原因短暂离开集群,过几分钟又重新加入集群,触发上述操作会导致集群有比较大的开销,是完全没有必要的。当树立了延时分配为5分钟时,节点下线时,只会执行上述第1步操作,此时的集群处于yellow状态,在5分钟内下线的节点重新加入集群则集群直接恢复green。避免了很多分片的迁移。通过API窜改延时分配时间,值为0则表示会立即分配。百分点大数据技术团队:Elasticsearch多数据中心大规模集群的实战经验cluster.routing.allocation.balance.shard:默许0.45f,定义分配在该节点的分片数的因子阈值=因子*(当前节点的分片数-集群的总分片数/节点数,即每一个节点的平均分片数);cluster.routing.allocation.balance.index:默许0.55f,定义分配在该节点某个索引的分片数的因子,阈值=因子*(当前节点的某个索引的分片数-索引的总分片数/节点数,即每一个节点某个索引的平均分片数);cluster.routing.allocation.balance.threshold:默许1.0f,超出这个阈值就会重新分配分片。根据设置装备摆设可以算出,当某一节点超过每一个节点平局分片数2.2(1/0.45)个分片时会触发rebalance。当某个节点my_index的分片数超过每一个节点my_index的平均分片数1.8(1/0.55)个分片时会触发rebalance。4. Mapping(1)字段类型设置装备摆设不需要被分词的字段应利用not_analyzed;不需要被搜刮的字段树立index:false;不需要聚拢的字段树立doc_value:false;仅用于精确匹配而不进行范围查问的数值字段利用keyword类型的效率更高。numeric类型从lucene6.0开始,利用了一种名为block KD tree的保存结构。这种结构比较适用于范围查找,在精确匹配方面没有倒排索引的本能好。

(2)利用自动生成的_id

避免自定义_id,建议用ES的默许ID生成策略,ES在写入对id判断是否存在时对自动生成的id有优化。同时避免利用_id字段进行排序或聚拢,如果有需求建议将该_id字段的内容复制到自定义已启用doc_values 的字段中。

(3)禁用_source

_source保存了原始的document内容,如果没有获取原始文档数据的需求,可通过树立includes、excludes属性来定义放入_source的字段。”mappings”:{  “_source”: {  “excludes”: [   “content”  ]  } }案例:在我们的方案中,考虑在架构上,原始数据保存在分布式文件系统。所以在ES中可以不保存content字段(其他字段仍然保存),只为content字段建立倒排索引用于全文检索,而实际内容从分布式文件系统中获取。收益:降低ES中保存;提高查问本能(OS cache中能装更多的Segment);shard的merge、恢复和迁移成本降低。限制:此字段不能高亮;update、update_by_query、reindex APIs不能利用。下面是我们根据业务数据特点测试不保存content字段对保存空间和查问的影响。(1)测试不保存content字段对磁盘保存的影响数据分布:百分点大数据技术团队:Elasticsearch多数据中心大规模集群的实战经验可以看出,不保存content字段可以加快搜刮,对聚拢影响不大。总的来说,需要根据业务场景考虑益弊,比如是否对数据进行更新、reindex、高亮,或者说通过其他方式实现对数据的更新、reindex、高亮的成本如何。三、ES集群设计经验

1. 批量提交

bulk批量写入的本能比你一条一条写入的本能要好很多,并不是bulk size越大越好,而是根据你的集群等环境具体要测试出来的,因为越大的bulk size会导致内存压力过大,最好不要超过几十m。

2. 多线程写入

单线程发送bulk哀求是无法最大化ES集群写入的吞吐量的。如果要利用集群的所有资源,就需要利用多线程并发将数据bulk写入集群中。为了更好的利用集群的资源,这样多线程并发写入,可以减少每次底层磁盘fsync的次数和开销。3. Merge只读索引合并Segment对ES非常重要,过多的Segment会消耗文件句柄、内存和CPU时间,影响查问速度。Segment的合并会消耗掉大量系统资源,尽量在哀求较少的时候进行,比如在夜里两点ForceMerge前一天的索引。POST my_index/_forcemerge?only_expunge_deletes=false&max_num_segments=1&flush=true4. Filter代替Query如果涉及评分相关业务利用Query,其他场景推荐利用Filter查问。在做聚拢查问时,filter经常发挥更大的作用。因为没有评分ES的处理速度就会提高,提升了整体响应时间,同时filter可以缓存查问结果,而Query则不能缓存。

5. 避免深分页

分页搜刮:每一个分片各自查问的时候先构建from+size的优先队列,然后将所有的文档 ID 和排序值前往给协作节点。协作节点创建size为number_of_shards *(from + size) 的优先队列,对数据节点的前往结果进行合并,取全局的from ~ from+size前往给客户端。什么是深分页?协作节点需要等待所有分片前往结果,然后再全局排序。因此会创建非常大的优先队列。比如一个索引有10个shard,查问哀求from:9990,size:10(查问第1000页),那么每一个shard需要前往1w条数据,协作节点就需要对10w条数据进行排序,仅仅为了获取10条数据而处理的大量的数据。且协作节点中的数据量会被分片的数量和页数所放大,因而一旦利用了深分页,协作节点会需要对大量的数据进行排序,影响查问本能。如何避免深分页?限制页数,限制只能获取前100页数据。翻页操作一般是人为触发的,并且人的行为一般不会翻页太多。ES自身提供了max_result_window参数来限制前往的数据量,默许为1w。每页前往100条数据,获取100页以后的数据就会报错。利用Scroll或search_after代替分页查问,Scroll 和 search_after都可以用于深分页,不支持跳页,适合拉取大量数据,目前官方推荐利用search_after代替 scroll。

6. 硬盘

固态硬盘比机械硬盘本能好很多;利用多盘RAID0,不要以为ES可以设置装备摆设多盘写入就和RAID0是一样的,主要是因为一个shard对应的文件,只会放到其中一块磁盘上,不会跨磁盘保存,只写一个shard的时候其他盘是空闲的,不过RAID0中一块盘出现问题会导致整个RAID0的数据丢失。7. 枚举空间大的字段聚拢方案(1)根据字段路由到固定shard这样在聚拢时每一个shard的bucket少,并且精度几乎不损失,但是会造成数据倾斜。如果字段数据比较平均可以选用,但是我们业务场景不适用。(2)调整字段的保存类型在字段类型设置装备摆设里介绍了精确匹配时keyword比数值类型效率高,我们测试了相同数据keyword和long的聚拢本能。集群创建4个索引(4天数据),每一个索引120个shard,每一个shard大小为30G,总数据量为:3.5T。其数据分布为1k的占比50%、10k的占比30%、100k的占比20%。百分点大数据技术团队:Elasticsearch多数据中心大规模集群的实战经验 结束语实时数据分析和文档搜刮是ES的常用场景之一,结合客户数据特点,百分点大数据技术团队对ES进行了优化和一定的改造,并将这些能力沉淀到了我们的大数据平台上,以更好的满足客户的业务需求。通过调优,在生产环境中ES集群已经稳定运行近两年的时间了。在实际部署前,对集群稳定性和本能进行了多次大规模测试,也模拟了多种可能发生的故障场景,正是不断地测试,发现了一些局限性,对版本升级,对源码窜改,也在不断测试中增加了更多的优化项来满足需求。文中的优化实践总体上非常的通用,希望可以给大家带来一定的参考价值。文章的最后,就以ILM作为彩蛋吧!ILM生命周期管理:索引生命周期的四个阶段Hot:index正在查问和更新,本能好的机器会树立为Hot节点来进行数据的读写。Warm:index不再更新,但是仍然需要查问,节点本能一般可以树立为Warm节点。Cold:index不再被更新,且很少被查问,数据仍然可以搜刮,但是能接受较慢的查问,节点本能较差,但有大量的磁盘空间。Delete:数据不需要了,可以删除。#节点属性可以通过 elasticsearch.yml 进行设置装备摆设 # node.attr.xxx: xxx,hot warm cold node.attr.data: warm这四个阶段按照Hot,Warm,Cold,Delete顺序执行,上一个阶段没有执行完成是不会执行下一个阶段的,对于不存在的阶段,会跳过该阶段进入到下一个阶段。示例:创建索引生命周期策略来管理elasticsearch_metrics-YYYY.MM.dd日志数据。策略如下:在index创建后立即进入hot阶段:当index创建超过1天或者文档数超过3000w或者主分片大小超过50g后,生成新index;旧index进入到warm阶段,segment数量merge为1,index迁移至属性data为warm的节点;warm阶段完成后,进入delete阶段,index rollover时间超过30天后,将index 删除。百分点大数据技术团队:Elasticsearch多数据中心大规模集群的实战经验(4)后续数据读写利用指定的别名elasticsearch_metricsActions各阶段支持的actions参考:Index lifecycle actions选择对应ES版本。(https://www.elastic.co/guide/en/elasticsearch/reference/7.6/ilm-actions.html)不同版本各个阶段支持的action有变化,因此建议手动测试一下,因为7.6版本官方文档说明在hot阶段如果存在rollover则可指定forceMerge,但实际测试7.6所有版本都不支持,7.7.0之后才可以这样树立。参考资料[1] https://www.elastic.co/guide/en/elasticsearch/reference/7.6/index.html[2] https://cloud.tencent.com/developer/article/1661414[3] 《elastic stack实战手册》

原创文章,作者:百分点科技,如若转载,请注明出处:https://www.iaiol.com/news/34000

(0)
上一篇 2022年1月11日 上午9:37
下一篇 2022年1月11日 上午9:43

相关推荐

  • 上海交大团队使用联合深度进修优化代谢组学研讨

    编辑 | 萝卜皮代谢组学是一个主要的组学课题,在代谢特征和生物标志物的临床利用和基础研讨中都占有重要地位。不幸的是,相关研讨受到许多外部因素造成的批次效力的挑战。在过去十年中,深度进修技术已成为数据科

    2022年7月21日
  • “LLM”席卷大数据行业,独角兽Databricks收购以 AI 为中心的大数据平台Okera

    由chat GPT带起的AI浪潮正在席卷全球,影响着所有的行业,也包括数据库领域。据TechCrunch报道,数据库领域独角兽Databricks 宣布收购了专注于 AI 的数据治理平台 Okera。

    2023年5月5日
  • 可信AI的驱动力——隐衷较量争论

    「机器之心2021-2022年度AI趋势大咖说」聚焦「驱动未来的AI技巧」与「重塑产业的AI科技」,推出线上分享,共邀请近40位AI领域知名学者、产业专家及企业高管通过主题分享及多人圆桌等形式,与行业精英、读者、观众共同回顾 2021年中的重要技巧和学术热点,盘点AI产业的年度研究方向以及重大科技突破,展望2022年度AI技巧发展方向、AI技巧与产业科技融合趋势。

    2022年7月21日
  • 清华团队通过监督贝叶斯嵌入,对单细胞染色质可及性数据进行细胞范例解释

    编辑 | 萝卜皮单细胞技术的最新进展使得能够在细胞水平上表征表观基因组异质性。鉴于细胞数量呈指数增长,迫切需要用于自动细胞范例解释的计算方式。特别是,单细胞染色质可及性测序(scCAS)数据的解释,它

    2022年3月22日

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注