ES的节点角色
- Master Node.
node.master
设置为true。可以参与竞选成为master节点。 - Data Node.
node.data
设置为true。负责存储数据和处理数据相关的操作。 - Ingest Node.
node.ingest
设置为true。负责在文档被索引之前转换和扩展文档。 - Tribe node. 使用
tribe.*
属性配置。它是一种特殊的coordinating node。负责连接多个集群和处理多集群间的操作。
默认情况节点的node.master
和node.data
为true
。
对于小规模的ElasticSearch集群,我们可以采用默认设置,每个ElasticSearch节点都可以客串各种角色。但是对于较大规模的集群,建议为不同的节点设置专门的角色。
Coordinating node
Coordinating node负责处理用户的请求。
用户请求分为两个阶段:分发阶段(scatter phase)和收集阶段(gather phase)。
在分发阶段,coordinating node把请求发送至各个数据节点。每个数据节点在本地处理请求并把结果返回给coordinating node。
在收集阶段,coordinating node把结果reduce成为一个全局的结果集。
每个node默认均为coordinating node。如果把node.master node.data node.ingest都设置为false,则该节点只有协调的功能。协调节点需要有足够的CPU和内存资源,用来收集各个数据节点返回的内容。
可以通过如下方法,设置节点仅有协调功能:
node.master: false
node.data: false
node.ingest: false
cluster.remote.connect: false
Master eligible node
Master eligible node为可被选举为master的节点。同一时刻同一集群内,只有一个master eligible node被选举成为master node。Master node负责创建和删除index,追踪集群节点状态,决定哪个分片分配到哪个节点。
Master node 必须有访问数据目录的权限。节点重启时集群状态会存储在这里。
设置节点为专门的master节点:
node.master: true
node.data: false
node.ingest: false
cluster.remote.connect: false
使用minimum_master_nodes避免脑裂
把discovery.zen.minimum_master_nodes 的值设置为
(master_eligible_nodes / 2) + 1
Ingest Node
Ingest node即预处理节点。我们可以在ES集群中定义pipeline,在数据被index前进行一些转换等预处理操作。Ingest node是专门执行预处理操作的节点。
设置专门的ingest node:
node.master: false
node.data: false
node.ingest: true
cluster.remote.connect: false
数据节点
负责存放数据和处理数据。
设置专门的数据节点:
node.master: false
node.data: true
node.ingest: false
cluster.remote.connect: false
设置数据目录
在配置文件中指定:
path.data: /path/to/data
或者在启动时加入:
./bin/elasticsearch -Epath.data=/var/elasticsearch/data
node.max_local_storage_nodes
在开发环境同一台机器启动多个节点,各个节点的数据是共享的。
默认来说es不允许用户这么做。需要将node.max_local_storage_nodes设置为更大的值。
ES优化
优化index设计
https://www.ebayinc.com/stories/blogs/tech/elasticsearch-performance-tuning-practice-at-ebay/
- 如果字段值可枚举,并且需要根据该字段filter查询,建议把数据分割为多个index。比如数据按照区域来划分。
- 如果字段值不可枚举,并且需要根据该字段filter查询,建议使用routing。
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-routing-field.html
- 对于日志和监控类数据,可以按照时间维度把数据group成indices,方便查找和过期数据的清除。
- 显式设置字段映射。
- 避免shard倾斜(使用自定义ID或routing时)。
- 使各个节点shard分布均匀。
调校index性能
- 使用批量查询
- 使用多线程发送请求
- 增加刷新间隔时间。优点:减少创建和合并索引的消耗,增加吞吐量减小延迟。缺点:文档必须在刷新之后才能被检索到。
- 减少副本数量。优点:加快索引速度。缺点:搜索性能会下降。
- 尽量使用自动生成的ID
调校搜索性能
- 尽可能使用filter查询而不是query。 filter不需要计算score。filter结果可以被缓存。
- 增加刷新时间间隔。
- 增加副本数量。
- 尝试使用不同的shard数量。shard数量过少会导致数据集中在个别节点上,搜索操作性能耗费过于集中。shard数量过多会不利于性能。ES会在所有shard上执行查询,除非用户指定routing。
- 使用节点查询缓存。只有filter才会使用节点缓存。如果节点包含10000或更多的documents(或总documents数的3%),会启用query缓存。
- 使用shard缓存。size设置为0。使用同样的payload JSON,因为shard缓存使用JSON作为cache key。把时间四舍五入。
- 仅查询需要的字段。使用stored_fields。
- 避免搜索stop word。例如a, the等。
- 如果不关心排序,按照_doc排序。ES默认按照_score字段排序。
- 避免查询时使用script进行实时计算。最好索引时把计算值存入字段。
- 避免使用通配符查询。
_routing(路由)字段
官方文档
基本概念
路由字段用来指定document会被存入哪一个分片。分片编号的计算公式为:
shard_num = hash(_routing) % num_primary_shards
默认来说,文档的_id
字段会被用为_routing
。
使用routing
储存数据
curl -X PUT "localhost:9200/my_index/_doc/1?routing=user1&refresh=true" -H 'Content-Type: application/json' -d'
{
"title": "This is a document"
}
'
获取数据
curl -X GET "localhost:9200/my_index/_doc/1?routing=user1"
查询时也可以根据_routing
的值进行查询。
curl -X GET "localhost:9200/my_index/_search?routing=user1,user2" -H 'Content-Type: application/json' -d'
{
"query": {
"match": {
"title": "document"
}
}
}
'
查询时指定_routing
为user1和user2
设置routing值为必填
curl -X PUT "localhost:9200/my_index2" -H 'Content-Type: application/json' -d'
{
"mappings": {
"_doc": {
"_routing": {
"required": true
}
}
}
}
'
// 不设置routing的值,插入数据会报错
curl -X PUT "localhost:9200/my_index2/_doc/1" -H 'Content-Type: application/json' -d'
{
"text": "No routing value provided"
}
'
避免routing导致的数据倾斜的问题
通过配置index.routing_partition_size
,使routing的值用来决定一组shards而不是一个shards。
shard 编号的计算方式为:
shard_num = (hash(_routing) + hash(_id) % routing_partition_size) % num_primary_shards
网友评论