当前位置: 首页 > 科技观察

Elasticsearch从基本概念到整个策略的产生和使用

时间:2023-03-14 19:58:38 科技观察

目前无论是在全文搜索领域还是大数据实时处理领域,ELK都是一枝独秀,ELK的核心在于Elasticsearch,而ELK之美来自于Elasticsearch之大。许多人可能使用过ELK,但对其核心Elasticsearch知之甚少。在这篇文章中,我们将一起学习Elasticsearch,从基本概念到生产和使用。基本概念对于Elasticsearch(ES)的新手来说,首先需要学习一些基本概念。Elasticsearch项目起源于Java优秀的分布式搜索引擎ApacheLucene,Luncene还衍生出另一个非常优秀的搜索项目Solor。不管是Elasticsearch还是Solor,底层的数据存储和搜索引擎都是Lucene。ES是一个更加优秀的基于Lucene内核的分布式实时搜索引擎,尤其在分布式集群和横向扩展方面,可以轻松运行和管理上千个Lucene实例。ES架构中的最高层单元是集群(Cluster)。集群是ES节点和索引的集合。节点(Node)是ES的一个实例。它们可以是单个服务器,也可以只是在服务器上运行的ES进程。注意:服务器不等同于节点。无论是VM虚拟机还是物理服务器都可以容纳很多ES进程,每个ES进程就是一个节点。节点可以完全加入集群。有不同类型的节点。最重要的两个节点是DataNode和Master-EligibleNode。一个节点可以同时拥有多个属性。数据节点运行所有数据操作。即存储、索引和搜索数据。候选主节点用于投票选出运行集群和索引管理的主机。索引(Index)是数据的高级抽象。索引本身不保存数据。它们只是对实际存储数据的另一种抽象。任何对数据进行的插入、删除、索引、查找等操作都会对索引产生影响。一个索引可以完全属于一个集群,由分片组成。分片是ApacheLucene的实例。一个分片可以容纳很多文档。分片是存储、索引和搜索实际数据的对象。一个分片恰好属于一个节点和索引。分片有两种类型:主分片和副本分片。两者基本上是等价的,它们持有相同的数据,所有分片都是并行搜索的。在所有具有相同数据的分片中,一个是主分片,并且是唯一可以接受索引请求的分片。如果主分片所在节点挂掉,副本分片会自动接替主分片。然后ES将创建一个新的副本分片并复制数据。一般来说,可以用一个简单的图来表示:深入理解要想运行一个系统,首先要理解这个系统。了解了基本概念后,让我们看看Elasticsearch的各个部分在实践中的应用。了解Elasticsearch组织是一种民主机制对Quorum来说很重要。节点通过投票决定谁是老大Master,即主节点。主节点运行着很多集群管理进程,在集群中拥有最终的发言权。ES的选举是有条件的,即只有候选节点才能参与选举成为主节点。EligibleforMaster是所有配置为以下条件的节点:node.master:true当集群启动或主节点退出集群时,所有满足主节点条件的节点将开始选举新的主节点。因此,需要有2n+1个节点符合宿主条件。否则,可能会出现选举间隔55分钟的脑裂情况。Node加入ES进程启动时,独立自由存在。它怎么知道它在哪个集群中?有不同的方法可以做到这一点。但是通常使用称为种子宿主的方法来完成此过程。Elasticsearch节点不断地与它见过的每个其他节点对话。因此,一个节点最初只需要咨询其他几个节点就可以了解整个集群。整个过程并不是一成不变的:当节点不属于集群时,它们只共享它们发现的其他节点的信息。Oncejoinedtothecluster,thenodeceasestodosoandreliesontheelectedclustermastertoshareinformationaboutchangesthathaveoccurred.这节省了很多不必要的互联网聊天。在ES7.x中,节点只与它们认为是候选主机节点的对象进行通信,发现过程会忽略候选主机节点。以三节点集群为例:初始状态:节点A和C只知道B,B是种子主机。种子主机要么以配置文件的形式提供给ES,要么直接放在elasticsearch.yml中。节点A与B连接并交换信息:一旦节点A连接到B,B现在就知道A的存在。A没有变化。节点C连接并与B共享信息现在C已连接,C将与B通信。B将告诉CA存在。C和B现在都知道集群中的所有节点。下次A重新连接到B时,它也会知道C存在。SegmentMerging前面我们说过,数据是分片存储的。数据将作为..文件存储在文件系统中。在Lucene和Elasticsearch中,这些文件称为段。一个分片可以有一个到数千个片段。Segments是物理存在的文件,可以在ES安装的data目录下看到。所以结束文件的操作是一个开销。如果你想查看它,你必须找到相应的文件并打开它。如果要打开的文件很多,那么开销就会很大。由于Lucene中的段是不可变的,因此只能写入而不能更改。放入ES的每个文档都将创建一个仅包含单个文档的段。那么,如果集群中有十亿个文档,是否会有十亿个段文件?其实并不是。在Lucene的后台,Segments会被合并。这个操作不会改变段,但是可以合并两个更小的段的数据创建一个新的段,合并后的两个小段会被清理:Lucene会继续合并段,保持段的数量不会太多大的。消息路由在Elasticsearch中,任何命令都可以针对集群中的任何节点运行,并且保持结果将是相同的。但是,在最低级别,文档将仅存在于一个主分片及其副本中,并且ES没有映射该文档在特定分片中的位置。如果搜索,请求入口点ES节点将其广播到索引中查看该文档所有段的所有分片。如果插入,ES节点随机选择一个主分片并??将文档放在那里,然后将其写入该主分片及其所有副本。生产实践的最后一部分讲了如何在生产中部署和管理Elasticsearch。Elasticsearch实践中最常见的问题之一是估计所需的集群大小,包括节点数、所需的硬件资源等。内存首先考虑内存使用,内存大小将限制所有其他资源。JavaHeapES是用Java开发的。Java使用堆,可以认为是Java保留内存。堆中有一些重要的东西使该文档的大小增加了三倍。关于尽量多用,但heapsize不要超过30G。堆有一个很多人不知道的秘密:堆中的每一个对象都需要一个唯一的地址,也就是对象指针。这个地址的长度是固定的,所以可以寻址的对象数量是有限的。简而言之,在某些时候Java将需要使用压缩对象指针而不是未压缩对象指针。这样每次内存访问都将涉及额外的步骤并且会慢得多。请不要超过这个阈值(大约32G)。根据社区对Elasticsearch不同文件系统、堆大小、FS和BIOS组合的基准测试,结果如下:如上图所示,从32G堆大小开始,性能突然开始变差(50%访问延迟,越小越好)。吞吐量结果(越大越好)都差不多:简而言之,使用29G或30G内存,使用XFS,并尽可能使用hardwareprefetch和llc-prefetch。文件缓存大多数人会在Linux上运行Elasticsearch,它使用RAM作为文件系统缓存。一个常见的建议是ES服务器使用64G,缓存和堆各占一半。大型ES集群(例如用于日志记录)可以从拥有大型FS缓存中受益。如果您的所有索引都适合堆,则不需要那么多。Elasticsearch7.x会要求其堆上有一定数量的直接内存,并且有其他开销,这就是为什么建议堆大小不超过物理内存的50%。这是一个上限,64GB主机上的32GB堆可能不会为文件系统缓存保留太多空间。文件系统缓存是Elasticsearch/Lucene性能的关键,较小的堆有时可以产生更好的性能(它们为文件系统缓存留出更多空间,并且对GC来说也更便宜)。CPU这取决于在集群上执行的操作。如果你正在做大量的索引工作,你将需要比仅仅做日志记录更多更快的CPU。对于日志记录来说,一般来说8核CPU绰绰有余,但是有更多不同的用途,看具体实践。磁盘如果索引分配给合适的内存,则磁盘仅在节点冷时才重要。实际可以存储的数据量取决于索引布局。每个分片都是一个Lucene实例,它们都有内存需求。这允许在堆中容纳最大数量的分片。通常,所有数据盘都可以放入RAID0。复制应该在Elasticsearch级别完成,因此丢失一个节点并不重要。请不要将LVM与多个磁盘一起使用,因为LVM一次只能写入一个磁盘,根本不会带来多个磁盘的好处。关于文件系统和RAID设置:调度程序:cfq和deadline优于noop。如果你有nvme,Kyber可能没问题(未经过严格测试)QueueDepth:尽可能高预读:是的,使用Raid块大小:无影响FS块大小:无影响FS类型:XFS优于ext4更大的索引布局很大程度上取决于在用例上。以日志集群后台为例。分片简而言之:对于写入繁重的工作负载,主分片=节点数vs对于读取繁重的工作负载,主分片*复制=节点数更多副本=更高的搜索性能可以使用公式计算写入性能:节点吞吐量*主分片数道理很简单:如果只有一个primaryshard,那么数据只能以一个节点写入数据的速度写入,因为一个shard只能在一个节点上。如果你真的想优化写入性能,你应该确保每个节点(主节点或副本)上只有一个分片,因为副本显然获得与主节点相同的写入,并且写入严重依赖于磁盘IO。注意:如果有很多索引,这可能不是真的,瓶颈可能是其他原因。如果要优化搜索性能,搜索性能可以由以下公式给出:节点吞吐量*(主分片数+副本数)对于搜索,主分片和副本分片基本相等。因此,如果要提高搜索性能,只需增加副本数即可。规模有很多关于索引大小的信息。我们这里的经验是:30Gheap=upto140shardspernode使用超过140个分片可能会导致Elasticsearch进程崩溃并导致内存不足错误。因为每个分片都是一个Lucene实例,而每个实例都需要一定的内存。那么,每个节点可以有多少个分片。如果你有节点数,分片数和索引大小,可以容纳多少个索引:分片数=(140*节点数)/(主分片数*拷贝比例)这样需要的大小可以这样计算:索引大小=(节点数*磁盘大小)/索引数注意:索引越大速度相对越慢。对于日志记录,它在一定程度上是可以的,但对于真正搜索繁重的应用程序,应该根据您拥有的内存量增加大小。段合并请记住,每个段都是文件系统上的一个实际文件。基本上,对于每个搜索查询,它会转到索引中的所有分片,然后从那里转到分片中的所有段。拥有太多段文件会显着增加集群的读取IOPS到无法使用的程度。因此,最好保持段数尽可能少。有一个force_mergeAPI允许将段合并到一定数量,比如1。如果您进行索引轮换,例如因为您使用Elasticsearch进行日志记录,那么在您经常使用时进行强制合并是个好主意没有使用集群。强制合并是资源密集型的,会大大降低集群的速度,如果你有很多索引,这是必要的。集群布局对于除最小设置之外的所有设置,最好使用专用的主节点。保持2n+1个候选节点以确保法定人数。但是对于数据节点,你只是希望能够随时添加一个新节点而不用担心它。此外,您不希望数据节点上的高负载影响主节点。最后,主节点是种子节点的理想候选者。请记住,种子节点是在Elasticsearch中执行节点发现的最简单方法。由于主节点很少变化,它们是最好的选择,并且它们已经知道集群中的所有其他节点。主节点可能很小,一个核心甚至4G的内存就可以满足大部分集群的需求。一如既往,密切关注实际使用情况并进行相应调整。监控监控是个好东西,Elasticsearch也是如此。ES提供了大量的指标,为了方便,支持JSON形式的调用。在监控工具中添加这些指标非常简单。以下是一些有用的监控指标包括:Segment数、堆使用率、堆GC时间、平均搜索、索引、合并时间、IOPS、磁盘利用率等。总结这篇文章,我们从简单到深入介绍Elasticsearchpractice使用的所有信息。主要是分享干货,没有其他详细的描述和内容,希望对大家有所帮助。