点一下关注吧!!!非常感谢!!持续更新!!!
目前已经更新到了:
- Hadoop(已更完)
- HDFS(已更完)
- MapReduce(已更完)
- Hive(已更完)
- Flume(已更完)
- Sqoop(已更完)
- Zookeeper(已更完)
- HBase(已更完)
- Redis (已更完)
- Kafka(已更完)
- Spark(已更完)
- Flink(已更完)
- ClickHouse(已更完)
- Kudu(已更完)
- Druid(已更完)
- Kylin(已更完)
- Elasticsearch(正在更新…)
章节内容
上节我们完成了如下的内容:
- ELK 日志分析实战
- 配置启动 Filebeat
- 配置启动 Logstash
Elasticsearch 集群模式的基本概念
Elasticsearch 是一个分布式搜索引擎,集群模式是指由多个节点(node)组成的一个集群(cluster),它们协同工作以提供更高的性能、扩展性和容错性。每个集群都有唯一的名称,所有属于同一集群的节点使用相同的集群名称相互识别。
在集群中,节点的类型主要分为三类:
- 主节点(Master Node):负责管理集群元数据(如创建或删除索引,跟踪集群中节点的加入或退出等),但不参与具体数据的搜索和存储。
- 数据节点(Data Node):负责存储实际的数据,处理与索引和搜索相关的请求。数据节点存储数据的副本,提供高可用性。
- 协调节点(Coordinating Node):不存储数据,不作为主节点,只负责接收用户的请求并将请求路由到相应的节点。一般情况下,所有节点都可以作为协调节点。
集群规划
在部署 Elasticsearch 集群时,规划是关键步骤,影响性能、可扩展性和可维护性。主要考虑以下几个方面:
- 主节点规划:建议至少配置三个主节点以保证主节点的高可用性。在一个节点故障时,仍然有足够的节点选举新的主节点。主节点不需要处理数据存储,可以使用较小的资源。
- 数据节点规划:数据节点负责存储和搜索数据,通常需要更大的内存和存储空间。规划时应根据业务需求和数据增长量确定节点数量和每个节点的容量。
- 协调节点:在大规模集群中,配置专门的协调节点可以减少数据节点的负载。
规划考虑
我们在业务上需要考虑的是:
- 当前的数据量有多大?数据增长情况如何?
- 你的机器配置如何?CPU?内存?硬盘容量?
推算依据
- Elasticsearch JVM Heap 最大可以设置32G
- 30G heap大概能处理的数据量10T
- 内存很大的话,比如128G的内存,可以考虑一台机器上部署多个Elasticsearch
应用场景
- 用于构建业务搜索功能模块,且多是垂直领域的搜索。数据量级几千万到数十亿级别,一般2-4台机器的规模
- 用于大规模的实时OLAP(联机处理分析),经典的如ELK Stack,数据规模可以达到千亿或更多,几十到上百节点的规模
角色分配
节点角色:
- MasterNode: node.master设置为true,节点可以作为主节点
- DataNode:node.data设置为true,默认是数据节点
- CoordinateNode:协调节点,一个节点只作为接收请求、转发请求到其他的节点、汇总各个节点返回数据等功能的节点,就叫协调节点。(如果仅担任协调节点,需要将MasterNode和DataNode设置为false,一个节点可以充当一个角色,也可以充当多个角色)
节点角色如何分配:
- 小规模集群,不需要严格区分
- 中大规模集群(十个节点以上),应考虑单独的角色充当。特别并发查询量大,查询的合并量大,可以增加独立的协调节点。角色分开的好处是分工分开,互不影响。如不会因协调角色负载过高而影响数据节点的能力。
设置分片
- 说明:分片数指定后不可变,除非索引重建。
- 分片设置的可参考原则:
Elasticsearch推荐的JVM最大的堆空间是:30-32G,所以把分片的最大容量限制在30G,然后对分片数量做合理估算。
在开始阶段,一个好的方案是根据节点的数量按照 1.5-3倍的原则来创建分片。例如:如果你有三个节点,则推荐你创建的分片数量不超过9个(3*3)个。
当性能开始下降时,增加节点,ES会平衡分片的放置。
对于基于日期的索引需求,并且对索引数据的搜索场景非常少,也许这些索引量会成百上千,但是每个索引的大小缺只有1GB甚至更小。对于这种场景,建议只需要为索引分配1个分片。
对于日志管理的需求,就是类似于日期索引需求,日期索引会很多,但是每个索引存放的数据量缺很少。
设置副本
分片应该设置几个副本呢?
- 为了保证高可用,副本数设置为2即可。但是要求集群至少有3个节点,来分开存放主分片、副本。
- 如果并发量大时,查询性能下降,则增加副本数,提高并发查询的能力。
- 注意:新增副本时主节点会自动协调,然后拷贝数据到新增的副本节点,副本数是随时都可以调整的。
PUT /wzk_temp_index/_settings
{"number_of_replicas": 1
}
集群调优
Index调优
在业务场景中,很多时候数据都是从MySQL集群,再抽取到ES的Index中。
如果你的场景的数据是不断变化的,那就要求ES中的数据也要有一个快速变化的要求,这样才可以保证MySQL和Elasticsearch中的数据保持一致。
副本数0
如果集群是首次写入数据,那么可以先设置为0,后续写完再根据业务要求设置为2(比如高可用),节约集群生成索引的过程。
PUT /wzk_temp_index/_settings
{"number_of_replicas": 0
}
自动生成ID
自动生成DocID,通过Elasticsearch写入流程可以看出,如果写入Doc时外部指定了id,那么Elasticsearch会先尝试读取原来的Doc的版本号,以判断是否需要更新数据,这个操作涉及到了磁盘,如果是自动生成DocID则可以避免这个问题。
mappings
合理设置mappings:
- 将不需要建立索引的字段index属性设置为not_analyzed或no。对字段不分词,或者不索引,可以减少很多CPU的计算。尤其是Binary类型,默认情况下CPU会很高,而且这种分词通过没有任何意义。
- 减少字段的内容长度,如果原始数据的大段内容不用全部建立索引,则可以尽量减少不必要的内容
- 使用不同的分析器(analyzer),不同的分词器在建立索引的过程中,运算的复杂度也有较大的差异。
source字段
调整 _source 字段,source字段用于存储原数的doc数据,对于部分不需要存储的数据,可以通过index excludes过滤,或者将source禁用,一般用于索引和数据分离,这样可以降低I/O的压力,不过业务场景中大多数都不会禁用Source。
analyzed禁用norms
norms用于在搜索中计算doc的评分,如果不需要评分,则可以将其禁用。
"title": {"type": "string","norms": {"enabled": false}
}
刷新间隔
调整索引的刷新间隔,该参数缺省是1秒,强制ES每秒创建一个新的Segment,从而保证新写入的数据近实时可见,可以被搜索到。比如该参数被调整为30秒,降低了刷新的次数,把刷新操作消耗的资源给释放出来给index操作使用。
PUT /wzk_temp_index/_settings
{"index" : {"refresh_interval": "30s"}
}
这种方式是牺牲可见性的方式,提高了index操作的性能。
批处理
批处理把多个index操作请求合并到一个batch中去处理,和MySQL的JDBC的Batch有类似之处。
如下图所示:
比如每批10000个Document是一个性能比较好的大小,每批中多少Document条数合适,受到很多因素影响而不同。
Search调优
在存储的Document超过10亿条后,需要进行搜索调优。
数组分组
ES用来存储日志,日志的索引管理方式一般都是基于日期,基于天、周、月、年建立索引,如下图,基于天建立索引:
当搜索丹单天的数据,只要要查询一个索引的Shards就可以。当需要查询多天的数据时,需要查询多个索引的Shards。这种方案其实和数据库分表、分库、分区查询方案相比思路是类似的,小数据范围检索而不是大海捞针。
Filter
使用Filter替代Query
在搜索的过程中使用Query,需要对Document的相关度进行打分,使用Filter的话,就不会有过滤了,做的事情更少,而且Filter理论上更快一些。
如果搜索不需要打分,可以直接使用Filter查询,如果部分搜索需要打分,建议使用Bool查询,这种方式可以把打分和不打分的放到一起:
GET /_search
{"query": {"bool": {"must": {"term": {"user": "kimchy"}},"filter": {"term": {"tag": "tech"}}}}
}
ID字段
将ID字段定义为Keyword,一般情况,如果ID字段不会被用作Range类型搜索字段,都可以定义成Keyword类型。
这是因为Keyword会被优化,以便进行terms查询,Integers等数字类的mapping类型,会被优化来进行range类型搜索。
将Integers改成Keyword类型之后,搜索性能提升了30%(有案例)。