一,写优化
- 批量提交。每次提交的数据量为多大才能达到最优,受文件大小,数据类型,网络情况,集群状态等因素影响,一般来说一次批处理的数据大小应从5M-15M开始逐渐增加直到没有性能提花为止。
- 优化存储设置。尽量使用固态硬盘(solid state disk)
- 合理使用段合并。段合并的计算庞大,会消耗大量的I/O,为了防止因段合并影响搜索性能,我们需要控制合理的合并速度,可通过参考进行配置
- 减少refresh次数。这个需要根据实际情况来看,如果我们对搜索的时效性不高,则可以增加延迟refresh的时间,这样还可以减少段合并的数量。
- 减少flush的次数。这个同样需要结合实际情况来看,当translog的数量达到512M或30分钟时,会触发一次flush,磁盘持久化比较耗资源,我们可以通过参考设置合理的值
- 减少副本数。ES副本数可以保证集群可用性,也可以增加搜索的并发数,但却会严重降低写索引的效率,因为在写索引时需要把整个文档的内容都发给副本节点,而所有的副本节点都需要把索引过程重复进行一遍。所以副本数不可过多。
二,读优化
- 避免大结果集和深翻页。如果有N个分片,协同节点需要收集每个分片的前from+size条数据,然后将收集到的Nx(from+size)条数据合并后再进行一次排序,最后从from+1开始返回size条数据。只要N,from,size其中有个值很大,这样的查询会消耗很多CPU,效率低下。为解决这类问题,ES提供了scroll和scroll-scan这两种方式。
1) scroll方式。 与search请求每次返回一页数据不同,scroll是为检索大量的结果(甚至所有的结果)而设计的,比如,我们有一个批量查询的需求,要查询1~100页的数据,每页有100条数据,如果用search查询,则每次都要在每个分片上查询得分最高的from+size条数据,然后协同节点把收集到的n ×(from+size)条数据合并起来再进行一次排序。接着从from+1开始返回size条数据,并且要重复100次,随着from的增大,查询的速度越来越慢。
但scroll的思路是:在各个分片上一次查询10000条数据,协同节点收集n×10000条数据,然后合并、排序,将排名前10000的结果以快照形式存储,最后使用类似数据库游标的形式逐次获得部分数据。这种做法的好处是减少了查询和排序的次数。scroll在第一次查询时除了返回查询到的结果外,还会返回一个scroll_id,它是下次请求的参数。scroll也分query,fetch两个阶段,第一阶段query先将所有符合条件的doc_id查询并暂存;第二阶段fetch根据doc_id与scroll_id以游标的方式获取文档。需要注意的是scroll会使用快照的形式暂存数据,后续一段时间内数据如果有修改是感知不到的,所以它不适合实时性要求高的场景
2) scroll-scan方式。scroll在初次查询时需要进行文本相似度计算和排序,这个过程也比较耗时,scroll-scan则关闭了这一过程。scroll-scan的特点是不做文本相似度计算;不支持聚合 - 选择合适路由
在多分片的ES集群下,查询大致分如下两种。
1) 查询条件中包含了routing信息。查询时可以根据routing直接定位到其中的一个分片,而不需要查询所有分片,再经过协调节点二次排序。
2) 如果查询条件不包含routing,整个查询过程就分scatter与gather两个过程。
scatter(分发):在请求到达协调节点后,协调节点将查询请求分发到每个分片上
gather(聚合):协调节点搜集在每个分片上完成的搜索结果,再将搜集的结果集进行重新排序,返回给用户。
三,堆大小的设置
ES默认的堆内存大小是1GB,因为ES是比较耗内存的应用,我们可以将这个值调大一点。-Xms与-Xmx设置一样。内存分配还有两个原则:
- 最好不要超过物理内存的50%。ES底层是lucene实现的,由于lucene段的不变性,所以我们不用考虑数据的变化,这对缓存非常友好,操作系统可以将这些文件缓存在操作系统的文件缓存系统(filesystem cache)中而非堆内存中,如果超过物理内存过多,则留给文件缓存系统就不多了
- 堆内存最好不要超过32G。这是因为在64位操作系统中,指针本身会变大,会有更大的空间浪费在指针本身上。
性能调优就写到这里,下面看下ES里的一些特性,比如主节点选举,如何避免脑裂。
- 角色隔离
由于节点默认的是node.master和node.data都为true,所以我们往往会让Master节点也担当了Data节点的角色。Elasticsearch集群中的Data节点负责对数据进行增、删、改、查和聚合等操作,所以对CPU、内存和I/O的消耗很大,有可能会对Master节点造成影响,从而影响整个集群的状态。
在搭建集群时,特别是比较大的集群时,我们应该对Elasticsearch集群中的节点做角色上的划分和隔离。我们通常使用几个配置比较低的虚拟机来搭建一个专门的Master集群。在集群中做角色隔离是一件非常简单的事情,只需在节点的配置文件中添加如下配置信息即可。
候选主节点:
node.master =true
node.data=false
数据节点:
node.master =false
node.data=true
- master选举
前提条件:
1) 只有是候选主节点(master:true)的节点才能成为主节点
2) 最小主节点数(min_master_nodes)的目的是防止脑裂
ES的选举是ZenDiscovery模块负责的,主要包含Ping(节点之间通过这个RPC来发现彼此)和 Unicast(单播模块包含一个主机列表以控制哪些节点需要 ping 通)这两部分。选举流程大致如下:
第一步:确认候选主节点数是否达标
第二步:对所有候选主节点根据nodeId字典排序,每次选举每个节点都将自己所知道节点排一次序,然后选出第一个(第0位)节点,暂且认为它是master节点
第三步:如果对某个节点的投票数达到一定的值(候选主节点数/2+1)并且节点自己也选举自己,那这个节点就是master。否则重新进行直到满足上面条件。 - 避免脑裂
脑裂是因为网络原因导致在集群中选举出了多个master,最后导致一个集群被分裂为多个集群。了为防止脑裂,我们需要在在Master集群节点的配置文件中添加参数discovery.zen.minimum_master_nodes,该参数表示在选举主节点时需要参与选举的候选主节点的节点数(默认值是1)。我们通常应该把这个值设置成(master_ eligible_nodes/2)+1,其中master_eligible_nodes为Master集群中的节点数。这样做既能防止脑裂的现象出现,也能最大限度地提升集群的高可用性,因为只要不少于discovery.zen.minimum_ master_nodes个候选节点存活,选举工作就可以顺利进行。
参考文章:elasticsearch scroll查询的原理没太懂
Elasticsearch之SearchScroll原理剖析和性能及稳定性优化
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。