基本概念
运维角度物理概念
- 分片(shard):一个索引所占用的物理空间分配
- primary shard:解决数据水平扩展问题,分片数据量过大时,可以通过增加DataNode节点扩容。一个主分片等于一个lucene实例。创建索引时指定,不能动态修改。
- replica shard:副本节点保障数据高可用性。增加副本数,可以提高服务的查询吞吐。可以动态修改
- 节点(node):一个Es实例
- Master eligible:参数node.master=true,负责集群状态(cluster status)的管理
- Data Node : 参数node.data=true,负责数据存储及处理客户端请求节点
- ingest node:参数node.ingest=true,负责数据处理
- Coordinating Node:参数node.master/data/ingest均为false,负载均衡,降低master/data节点负载,搜索结果的gather/reduce
- Machine Learning Node:参数node.ml=true,负责跑机器学习任务,用来做异常检测,自动发现数据异常发出警告
- Tribe Node: (5.3开始使用Cross Cluster Search)支持连接不同集群
- Hot & Warm Node:不同硬件配置的data node,用来实现Hot & Warm架构,降低集群部署的成本
https://www.elastic.co/guide/en/elasticsearch/reference/8.5/modules-node.html
开发角度逻辑概念
- 索引(index):一类文档的集合
- 文档(document):可以搜索的最小单位
类比数据库
RDBMS | Elasticsearch |
---|---|
Table | Index(Type) |
Row | Document |
Column | Filed |
Schema | Mapping |
SQL | DSL |
倒排索引
- 倒排索引采用Immutable Design,一旦生成,不可更改
- Elasticsearch的每个文档是基于JSON格式,每个文档都会建立自己的倒排索引
- 可以手工指定某些Field字段不做索引
Term | Count | DocumentId:Position |
---|---|---|
World | 3 | 1:1,2:0,3:0 |
Hello | 1 | 1:0 |
Bank | 1 | 2:1 |
Class | 1 | 3:1 |
正排索引
DocId | DocContent |
---|---|
1 | Hello World |
2 | World Bank |
3 | World Class |
写
流程图
translog写入在处理index buffer之后,处理index buffer ACK之前:https://www.elastic.co/guide/en/elasticsearch/reference/8.6/index-modules-translog.html
读
查询Segment缓存中的数据,因此ES是一个近实时数据,默认写入的数据1S内进入Segment
参考官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/search-request-search-type.html
query then fetch
参数值: query_then_fetch(默认类型)
分两个阶段处理查询请求。第一阶段,请求被转发至所有涉及的shard分片。每个shard执行搜索并生成一个排序结果列表,该列表在shard本地。每个shard向cooridinating节点返回足够的信息,以允许它合并与重排序shard级别的结果至一个全局排序的结果集,结果集最大长度为请求需求的size。
第二阶段,coordinating节点仅向相关shard请求文档内容(以及高亮片段,如果有的话)。
dfs,query then fetch
参数值:dfs_query_then_fetch
与"Query Then Fetch"相似,区别是初始分发阶段,它会去计算分布式TF值,以获取更准确的评分
query and fetch
参数值: query_and_fetch
与query_then_fetch区别在于,只有一个阶段,第一阶段就返回文档内容,即将两个阶段合二为一了
5.3版本后已废弃:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/release-notes-5.3.0.html
dfs, query and fetch
参数值:dfs_query_then_fetch
5.3版本后已废弃:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/release-notes-5.3.0.html
深度分页
es分页取大于10000条之后的数据会报错,追加大于上一页最大的id的条件过滤数据避免溢出报错
集群部署
单一职责
- Dedicated master eligible nodes:负责集群状态管理
- 使用低配置的CPU,RAM,磁盘
- 一个集群一般配置3台,只有1台活跃主节点
- 负责分片管理,索引创建,集群管理等操作
- Dedicated data nodes:负责数据存储及处理客户端请求
- 使用高配置的CPU,RAM,磁盘
- Dedicated ingest nodes:负责数据处理(pipeline流式数据处理)
- 使用高配置的CPU,中等配置RAM;低配置磁盘
- Dedicated Coordinating Only Nodes(Client Node)
- 使用中/高配置CPU,中/高配置RAM,低配置磁盘
- 生产环境大集群建议配置Coordinating Only Nodes
Coordinating
读写分离
异地多活
Hot & Warm Architecture
- Hot节点:通常使用SSD,索引有不断的新数据写入,存在大量的数据查询
- Warm节点:通常使用HDD,索引不存在新数据写入,同时不存在大量的数据查询,例如归档日志,历史订单等
标记节点
- 节点的attribute可以是任何的key/value,比如:my_node_type=hot
- 通过elasticsearch.yml或命令参数指定
-E node.attr.my_node_type=hot
-E node.attr.my_node_type=warm
配置hot数据
创建索引指定hot节点
PUT log-2022
{
"setting":{
"number_of_shards":2,
"number_of_replicas":1,
"index.routing.allocation.require.my_node_type":"hot"
}
}
hot数据迁移至warm节点
PUT log-2022/_settings
{
"index.routing.allocation.require.my_node_type":"warm"
}
Rack Awareness
避免主副分片分布在同一个机架上,当一个机架断电时导致数据丢失
标记rack
-E node.attr.my_rack_id=rack1
-E node.attr.my_rack_id=rack2
配置集群
PUT _cluster/settings
{
"persistent":{
"cluster.routing.allocation.awareness.attributes":"my_rack_id"
}
}
主副分片会自动分配至不同rack上
shard管理
一个索引配置多个分片,可以动态水平扩展,重新分配时,系统不会有downtime
默认配置
https://www.elastic.co/guide/en/elasticsearch/reference/current/misc-cluster-settings.html
1000 shards/per data node
3000 shards/per frozen data node
案例1
- 每天1GB数据,一个索引一个主分片,一个副本分片
- 保留半年的数据,接近360GB数据量
案例2
- 5个不同的日志,每天创建一个日志索引。每个日志索引创建10个主分片
- 保留半年数据
- 51030*6=9000个分片
官方推荐
https://www.elastic.co/guide/en/elasticsearch/reference/8.6/size-your-shards.html
存储设计
- 日志类应用,单个分片不要大于50GB
- 搜索类应用,单个分片不要超过20GB
为什么要控制大小
- 提高update性能
- merge时,减少所需的资源
- 丢失节点后,具备更快的恢复速度/便于分片在集群内rebalancing
集群容量规划
- 数据节点尽量使用SSD
- 搜索性能要求高的场景,建议SSD
- 按照1:10的比例配置内存和硬盘
- 日志类和查询并发低的场景,可以考虑机械硬盘
- 按照1:50的比例配置内存和硬盘
- 单个数据节点建议控制在2TB以内,最大不建议超过5TB
- JVM配置机器内存1半,JVM内存配置不建议超过32G