7.数据同步&ES集群
将同步类型分为 全量同步和 增量同步。
全量同步即建好 Elasticsearch 索引后一次性导入 MySQL 所有数据。全量同步有很多现成的工具可以用:
go-mysql-elasticsearch 是一项将 MySQL 数据自动同步到 Elasticsearch 的服务,同样支持增量同步。
DataX 是阿里云 DataWorks 数据集成 的开源版本,在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。DataX 实现了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、Hologres、DRDS 等各种异构数据源之间高效的数据同步功能。
另外,除了插件之外,像我们比较熟悉的 Canal 除了支持 binlog 实时增量同步 数据库之外也支持全量同步 。
增量同步即对 MySQL 中新增,修改,删除的数据进行同步:
同步双写 :修改数据时同步到 Elasticsearch。这种方式性能较差、存在丢数据风险且会耦合大量数据同步代码,一般不会使用。
异步双写 :修改数据时,使用 MQ 异步写入 Elasticsearch 提高效率。这种方式引入了新的组件和服务,增加了系统整体复杂性。
定时器 :定时同步数据到 Elasticsearch。这种方式时效性差,通常用于数据实时性不高的场景
binlog 同步组件 Canal(推荐) : 使用 Canal 可以做到业务代码完全解耦,API 完全解耦,零代码实现准实时同步, Canal 通过解析 MySQL 的 binlog 日志文件进行数据同步。
Canal 增量数据同步 Elasticsearch 的原理了解吗?
这个在 Canal 官方文档中有详细介绍到,原理非常简单:
- Canal 模拟 MySQL Slave 节点与 MySQL Master 节点的交互协议,把自己伪装成一个 MySQL Slave 节点,向 MySQL Master 节点请求 binlog;
- MySQL Master 节点接收到请求之后,根据偏移量将新的 binlog 发送给 MySQL Slave 节点;
- Canal 接收到 binlog 之后,就可以对这部分日志进行解析,获取主库的结构及数据变更。
Elasticsearch 集群
Elasticsearch 集群是什么?有什么用?
单台 Elasticsearch 服务器负载能力和存储能力有限,很多时候通过增加服务器配置也没办法满足我们的要求。并且,单个 Elasticsearch 节点会存在单点风险,没有做到高可用。为此,我们需要搭建Elasticsearch 集群。
Elasticsearch 集群说白了就是多个 Elasticsearch 节点的集合,这些节点共同协作,一起提供服务,这样就可以解决单台 Elasticsearch 服务器无法处理的搜索需求和数据存储需求。出于高可用方面的考虑, 集群中节点数量建议 3 个以上,并且其中至少两个节点不是仅投票主节点(后文会介绍到)。
Elasticsearch 集群可以很方便地实现横向扩展,我们可以动态添加或者删除 Elasticsearch 节点。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。
Elasticsearch 集群中的节点角色有哪些?
Elasticsearch 7.9 之前的版本中的节点类型:数据节点、协调节点、候选主节点、ingest 节点。在Elasticsearch 7.9 以及之后,节点类型升级为节点角色(Node roles)。节点角色分的很细:数据节点角色、主节点角色、ingest 节点角色、热节点角色等。
节点角色主要是为了解决基于节点类型配置复杂和用户体验差的问题。
Elasticsearch 集群一般是由多个节点共同组成的分布式集群,节点之间互通,彼此配合,共同对外提供搜索和索引服务(节点之间能够将客户端请求转向到合适的节点)。不同的节点会负责不同的角色,有的负责一个,有的可能负责多个。
在 ES 中我们可以通过配置使一个节点有以下一个或多个角色:
主节点(Master-eligible node):集群层面的管理,例如创建或删除索引、跟踪哪些节点是集群的一部分,以及决定将哪些分片分配给哪些节点。任何不是仅投票主节点的合格主节点都可以通 过主选举过程被选为主节点。
专用备选主节点(Dedicated master-eligible node): Elasticsearch 集群中,设置了只能作为主节点的节点。设置专用主节点主要是为了保障集群增大时的稳定性,建议专用主节点 个数至少为 3 个。
仅投票主节点(Voting-onlymaster-eligiblenode): 仅参与主节点选举投票,不会被选为主节点,硬件配置可以较低。
数据节点(data node):数据存储和数据处理比如 CRUD、搜索、聚合。
预处理节点(ingest node):执行由预处理管道组成的预处理任务。
仅协调节点(coordinating only node):路由分发请求、聚集搜索或聚合结果。
远程节点(Remote-eligible node):跨集群检索或跨集群复制。
高可用性 (HA) 集群需要至少三个符合主节点条件的节点,其中至少两个节点不是仅投票主节点。即使其中一个节点发生故障,这样的集群也能够选举出一个主节点。
分片是什么?有什么用?(直接看简单总结)
类似:Elasticsearch 集群中的数据是如何被分配的?
分片(Shard) 是集群数据的容器,Index(索引)被分为多个文档碎片存储在分片中,分片又被分配到集群内的各个节点里。当需要查询一个文档时,需要先找到其位于的分片。也就是说,分片是Elasticsearch 在集群内分发数据的单位。
每个分片都是一个 Lucene 索引实例,可以将其视作一个独立的搜索引擎,它能够对 Elasticsearch 集群中的数据子集进行索引并处理相关查询。
整个 Elasticsearch 集群的核心就是对所有的分片执行分布存储,索引,负载,路由的工作。
当集群规模扩大或者缩小时, Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。Elasticsearch 在对数据进行再平衡时移动分片的速度取决于分片的大小和数量,以及网络和磁盘性能。
一个分片可以是 主分片(Primary Shard) 或者 副本分片(Replica Shard) 。一个副本分片只是一个主分片的拷贝。副本分片作为硬件故障时保护数据不丢失的冗余备份,并为搜索和返回文档等读操作 提供服务。查询吞吐量可以随着副本分片数量的增加而增长,与此同时,使用分片副本还可以处理查询 的发并量。
当我们写索引数据的时候,只能写在主分片上,然后再同步到副本分片。
当主分片出现问题的时候,会从可用的副本分片中选举一个新的主分片。在默认情况下,ElasticSearch 会为主分片创建一个副本分片。由于副本分片同样会占用资源,因此,不建议为一个主分片分配过多的 副本分片,应该充分结合业务需求来选定副本分片的数量。
从 Elasticsearch 版本 7 开始,每个索引的主分片数量的默认值为 1,默认的副本分片数为 0。在早期版本中,默认值为 5 个主分片。在生产环境中,副本分片数至少为 1。
简单总结一下:
分片是 Elasticsearch 在集群内分发数据的单位。整个 Elasticsearch 集群的核心就是对所有的分片执行分布存储,索引,负载,路由的工作。
副本分片主要是为了提高可用性,由于副本分片同样会占用资源,不建议为一个主分片分配过多的副本分片。
当我们写索引数据的时候,只能写在主分片上,然后再同步到副本分片。当主分片出现问题的时候,会从可用的副本分片中选举一个新的主分片。
查询文档时如何找到对应的分片?
我们需要查询一个文档的时候,需要先找到其位于那一个分片中。
这个过程是根据路由公式来决定的:
shard = hash(routing) % number_of_primary_shards
shard = hash(文档 id) % 索引创建时指定的分片总数
routing 是一个可以配置的变量,默认是使用文档的 id。对 routing 取哈希再除以
number_of_primary_shards (索引创建时指定的分片总数)得到的余数就是对应的分片。
当一个查询请求到达 仅协调节点(coordinating only node) 后,仅协调节点会根据路由公式计算出目标分片,然后再将请求转发到目标分片的主分片节点上。
上面公式也解释了为什么我们要在创建索引的时候就确定好主分片的数量,并且不允许改变索引分片数。因为如果数量变化了, 那么所有之前路由的计算值都会无效,文档也再也找不到了。
自定义路由有什么好处?
默认的路由规则会尽量保证数据会均匀地保存到每一个分片上面。这样做的好处是,一旦某个分片出了 故障,ES 集群里的任何索引都不会出现一个文档都查不到的情况,所有索引都只会丢失故障分片上面存储的文档而已,这个给修复故障分片争取了时间。
不过,这种路由规则也有一个弊端,文档均匀分配到多个分片上面了,所以每次查询索引结果都需要向 多个分片发送请求,然后再将这些分片返回的结果融合到一起返回到终端。很显然这样一来系统的压力 就会增大很多,如果索引数据量不大的情况下,效率会非常差。
如果我们想要让某一类型的文档都被存储到同一分片的话,可以自定义路由规则。所有的文档 API 请求(get,index,delete,bulk,update)都接受一个叫做 routing 的路由参数,通过这个参数我们可以自定义文档到数据分片的映射规则。
如何查看 Elasticsearch 集群健康状态?
在 Kibana 控制台执行以下命令可以查看集群的健康状态:
GET /_cluster/health
正常情况下,返回如下结果。
接口返回参数解释如下:
指标 |
含义 |
cluster_name |
集群的名称 |
status |
集群的运行状况,基于其主要和副本分片的状态。 |
timed_out |
如果 false 响应在 timeout 参数指定的时间段内返回(30s 默认情况下) |
number_of_nodes |
集群中的节点数 |
number_of_data_nodes |
作为专用数据节点的节点数 |
active_primary_shards |
活动主分区的数量 |
active_shards |
活动主分区和副本分区的总数 |
relocating_shards |
正在重定位的分片的数量 |
initializing_shards |
正在初始化的分片数 |
unassigned_shards |
未分配的分片数 |
delayed_unassigned_shards |
其分配因超时设置而延迟的分片数 |
number_of_pending_tasks |
尚未执行的集群级别更改的数量 |
number_of_in_flight_fetch |
未完成的访存数量 |
task_max_waiting_in_queue_millis |
自最早的初始化任务等待执行以来的时间(以毫秒为单位) |
active_shards_percent_as_number |
群集中活动碎片的比率,以百分比表示 |
Elasticsearch 集群健康状态有哪几种?
GREEN (健康状态):最健康的状态,集群中的主分片和副本分片都可用。
YELLOW (预警状态):主分片都可用,但存在副本分片不可用。
RED (异常状态):存在不可用的主分片,搜索结果可能会不完整。
如何分析 Elasticsearch 集群异常问题?
1、找到异常索引
# 查看索引情况并根据返回找到状态异常的索引 GET /_cat/indices?v&health=yellow GET /_cat/indices?v&health=red
2、查看详细的异常信息
GET /_cluster/allocation/explain
GET /_cluster/allocation/explain?pretty
通过异常信息进一步分析问题的原因。