第三章 集群的大脑 — Monitor
文章目录
- 一、Monitor介绍
- 1. Paxos简介
- 2. Paxos核心原理
- 3. Leader租期时间因子
- 4. Monitor 故障切主流程
- 二、Monitor类型及职责
- 1. AuthMonitor(cephX)
- 2.账户鉴权流程
- 3.HealthMonitor
- 4. MDSMonitor
- 5.MDS 故障切换流程
- 6. MGR介绍
- 三、存储池的管理结构
- 1. min_size与size
- 2. pg与pgp
一、Monitor介绍
Monitor在Ceph集群中扮演管理者的角色,维护了整个集群的状态,集群的状态被抽象成几个Map对象,包括mon map、osd map、pg map、crush map统称为Cluster map,保证集群的相关组件在同一时刻能够达成一致,相当于领导层。一句话总结Monitor的作用就是:负责收集集群信息、更新集群信息以及发布集群信息。
Mon节点之间使用Paxos算法来保持各节点Cluster Map的一致性,Paxos节点与monitor节点绑定,每个mon启动一个Paxos,Paxos为Mon提供服务。各Mon节点的功能总体是一样的,相互间的关系可以被简单理解为主备关系。如果主Mon节点损坏,其他Mon存活节点超过半数时,集群还可以正常运行。当故障Mon节点恢复时,会主动从 其他Mon节点拉取最新的Cluster Map。
Epoch,即版本号。cluster map的epoch是一个单调递增序列。epoch越大,则cluster map版本越新。因此,持有不同版本cluster map的OSD或client可以简单地通过比较epoch决定应该遵从谁手中的版本。而monitor手中必定有epoch最大、版本最新的cluster map。当任意两方在通信时发现彼此epoch值不同时,将默认先将cluster map同步至高版本一方的状态,再进行后续操作。
1. Paxos简介
Paxos 是由美国计算机科学家 Leslie Lamport 于 1989 年提出、1998 年正式发表的分布式一致性算法,用来解决不可靠网络中多节点如何达成一致数据的问题。Lamport 后来因此获得2013 年图灵奖,被公认为分布式系统领域的奠基人之一。他最初用一个虚构的希腊 Paxos 议会故事来讲解算法,风格幽默晦涩,导致业界多年后才真正理解并广泛应用,正如业内戏言:“真正理解 Paxos 的或许只有5个人,但全世界都在用它。”如今已是ZooKeeper、etcd、Ceph Monitor等系统的核心共识基础。
Paxos小岛(希腊语:Παξοί,常拼作Paxos或Paxoi)是希腊伊奥尼亚群岛中最小的岛屿,位于科孚岛以南约14海里处,距离希腊大陆约20海里。该岛由主岛Paxos和附属小岛Antipaxos组成,总面积约19–25平方公里,人口约3,500人。
2. Paxos核心原理
- Ceph对Paxos做了简化,任意时刻只允许某个特定的Monitor统一发起集群表更新,这个特殊的Monitor称为Leader,对之对应的其他Monitor则统称为Peon。Leader通过投票选举产生,一旦某个Monitor赢得超过半数的选票成为Leader,Ceph将保证在接下来的一个特定时间段内不会再有其他Monitor成为新的Leader,这个时间段称为租期(Lease)。
- 在正常运行过程中,Leader可以通过不断续租的方式来延长自身作为Leader的租期,但是一旦集群成员组成情况发生变化,例如Leader自身发生故障、新的Monitor加入或者老的Monitor退出等,这个集群就会重新触发Leader选举。
- 任意一个Peon检测到租期到期后Leader没有发起刷新(续租),就可以认为Leader已经异常,此时将触发集群重新进行Leader选举。反之,如果Leader发送续租请求后超时没有收到某个Peon的应答,则判断该peon已经异常,同样将触发集群重新进行Leader选举。
- 产生Leader之后,可以由其负责串行化集群表更新和发起集群表同步,在此之前,Leader需要先获取最新的集群表,这通过向集群成员表中除自身以外的每个成员发送Probe消息实现。顾名思义,Probe消息带有试探性质,每个收到Probe消息的成员必须在一个**有限的时间间隔内(默认为2s)**决定是否加入集群。如果最终确认加入,则通过Reply消息进行应答,并同步返回本地保存的集群表范围。一旦Leader确认超过半数的成员进行了应答,并成功地将集群表同步至最新版本之后,就可以向所有成员发布租期,开始其Leader生涯。
- 每个租期内活跃的Monitor(包括Leader和Peon)都被自动赋予向客户端或者OSD分发集群表权威副本的权限,但如果Peon收到了集群表更新请求,则需要首先检查其是否为有效的更新请求。最终,所有经过确认的更新请求都被透传至Leader,由其负责串行化、执行合并、分配新的集群表版本号并在集群中发起同步。(一个典型的例子:Peon收到报告,声称某个OSD失联,但是事实上对应OSD的“故障”状态已经体现在最新的集群表中,此时peon可以忽略这个报告,只需要简单向报告者返回最新的集群表即可)
- 由于Leader选举期间Monitor无法正常提供服务,因此工程实现上需要尽可能避免频繁触发Leader选举。
3. Leader租期时间因子
- 基础租期(mon_lease) //默认 5 秒
- 超时因子(mon_lease_ack_timeout_factor) //默认 2.0
- 续租系数(mon_lease_renew_interval_factor) //默认 0.6
- Probe 消息应答超时(mon_probe_timeout) //默认2s
Leader 超时 = mon_lease × mon_lease_ack_timeout_factor //默认 10 秒
Leader 续租间隔 = mon_lease × mon_lease_renew_interval_factor //默认 3 秒
ceph config get mon.$HOSTNAMEmon_lease //基础租期 ceph config get mon.$HOSTNAMEmon_lease_ack_timeout_factor //超时因子 ceph config get mon.$HOSTNAMEmon_lease_renew_interval_factor //续租系数 ceph config get mon.$HOSTNAMEmon_probe_timeout //Probe 消息应答超时4. Monitor 故障切主流程
假设集群中有三台Mon(MonA、MonB、MonC),MonA为主Mon,下面我们模拟MonA故障,看下Monitor的切主流程:
当主节点 MonA 发生故障后,集群会基于 rank 和 classic 策略选举出新的主节点(此处假设 MonB 胜出)。随后,MonB 会向所有节点发起探测请求,并等待 2 秒内收到半数以上节点的回复。一旦满足条件,MonB 与从节点 MonC 开始比较它们各自持有的集群地图版本:
- 如果 MonB 的版本高于 MonC,MonC 会拒绝 MonB 的当选请求,并要求 MonB 先从 MonC 同步数据;
- 如果 MonB 的版本低于 MonC,则 MonB 需要等待并从 MonC 同步数据;
- 如果两者版本一致,则进入 Paxos 选举阶段:MonB 生成提案编号并发送给 MonC,MonC 将该编号与自己历史上接受过的最大提案编号进行比较。若 MonC 的编号更大,则拒绝 MonB 并告知其更大的编号,MonB 需重新生成提案编号;若 MonB 的编号更大,MonC 接受提案,MonB 正式成为 Leader,并向 MonC 发布租约。
此后进入稳定运行阶段:Leader MonB 每 3 秒向从节点续租,从节点 MonC 等待租约。如果 MonC 在 10 秒内未收到续租,则会发起新的选举。发起选举后,若存活节点数未超过半数,集群将不可用;若存活节点数超过半数,则回到选举新主的流程重新开始。
二、Monitor类型及职责
- AuthMonitor
负责鉴权和授权,后者又包括密钥的分发与定时刷新等。 - HealthMonitor
负责监控Monitor 自身状态,产生相关告警,例如:- 每个Monitor 进程驻留的磁盘,其空间使用率是否已达到临界点(例如可用空间小于30%,或者Monitor 数据库大小超过15GB将会产生告警;进一步地,如果可用空间小于5%,会导致Monitor进程直接退出)。
- Monitor 之间时钟是否同步(例如偏差超过50ms将会触发告警)。
- 是否有Monitor宕掉。
- MDSMonitor
负责检测元数据服务器(MetaData Server,MDS)的状态变化;处理文件系统(指CephFS)相关的命令,例如创建文件系统、查看文件系统状态等。 - OSDMonitor
负责监控OSD状态,维护集群表。 - PGMonitor
负责收集PG相关的统计,处理PG相关的命令等,事实上在早期的实现中,PGMonitor主要负责创建PG,现在这一部分工作已被转移至OSDMonitor中,此外,随着Mgr组件的逐步完善,同时也为了给Monitor减负,与统计相关的工作也转移至Mgr组件中。
1. AuthMonitor(cephX)
在 Ceph 存储集群中,cephx 认证机制负责所有访问请求的鉴权和授权。默认情况下,cephx 认证是开启的,任何客户端、OSD 或管理工具在访问集群前都必须提供有效的凭证。管理员也可以在 Monitor 节点上手动关闭认证,但此举将使集群允许任意未经认证的访问,严重威胁数据安全,因此生产环境必须保持认证开启。
- client.admin 拥有最高权限,可对集群执行任意操作,例如查看状态(ceph -s)、管理 OSD(ceph osd)、创建存储池(ceph osd pool create)、生成客户端认证信息(ceph auth get-or-create)等。
- OSD(对象存储守护进程)的核心职责是存储数据、处理数据副本、执行数据同步以及向其他组件报告自身状态。它与集群各组件的交互如下:
- 与 Monitor(MON)的交互:上报自身状态(up/down/in/out)、发送心跳、获取最新的 osdmap、crushmap、monmap;向 Monitor 申请会话密钥(session-key)和服务票据(ticket),完成加入或退出集群的过程。
- 与其他 OSD 的交互:建立点对点连接,用于数据复制、回填(backfill)、恢复(recovery)、重平衡(rebalance)以及 peering 过程;同时处理客户端发来的 I/O 请求(经过权限校验后),读写所有 pool 的数据(因为每个 OSD 都可能承载副本)。
- 与 Manager(MGR)的交互:向 MGR 上报监控指标(如磁盘利用率、操作延迟等),并接收 MGR 下发的部分监控指令。
MGR(Ceph Manager) 负责收集并展示集群的整体监控信息。它汇总 OSD、MON、存储池、PG 等组件的状态,对外提供统一的监控接口,例如通过 Prometheus 暴露指标、提供内置的 Dashboard 图形界面以及 REST API,方便管理员实时掌握集群健康状况。
2.账户鉴权流程
- 首先创建用户时,mon会为用户提供一个secret,并且将该secret与其它ceph组件(mon、mds、osds)共享,客户端收到该secret后一般将其保存在keyring文件中
- 之后客户端通过该用户的身份连接到mon进行认证
- mon返回一个加密的身份验证的数据结构,里边包含session-key
- 客户端通过keyring中保存的secret进行解密得到session-key
- 客户端携带session-key向mon请求一个ticket
- mon返回加密的ticket
- 客户端通过keyring中保存的secret进行解密得到ticket
- 客户端直接向OSD或MDS发起请求时携带此ticket即可验证身份
3.HealthMonitor
HealthMonitor 负责监控 Monitor 自身状态,产生相关告警
- Monitor 进程驻留的磁盘
- mon_data_size_warn > 15G 集群状态变为 HEALTH_WARN
监控器本地数据存储目录(通常位于 /var/lib/ceph/mon/)的大小超过 15 GiB 时触发告警 - mon_data_avail_warn < 30% 集群状态变为 HEALTH_WARN
监控器数据存储所在文件系统的可用磁盘空间百分比低于 30% 时触发告警 - mon_data_avail_crit < 5% 集群状态变为 HEALTH_ERR,且Monitor 进程会直接退出
监控器数据存储所在文件系统的可用磁盘空间百分比低于或等于 5% 时触发告警
- mon_data_size_warn > 15G 集群状态变为 HEALTH_WARN
Monitor 进程一般与系统盘公用一个分区,所以系统盘的容量与性能一定要做监控!
ceph daemon mon.$HOSTNAMEconfig show|grepmon_data_size_warn //查看mon本地数据存储目录的大小 ceph daemon mon.$HOSTNAMEconfig show|grepmon_data_avail_warn //查看mon所在文件系统的可用磁盘空间(百分比) ceph daemon mon.$HOSTNAMEconfig show|grepmon_data_avail_crit //查看mon所在文件系统的可用磁盘空间百分比低于或等于多少时触发告警- Monitor 之间时钟是否同步
- mon_clock_drift_allowed > 50ms 集群状态变为 HEALTH_WARN
Monitor 节点之间系统时间的最大允许差异(即时钟漂移)时钟漂移相差0.05s 时触发告警
- mon_clock_drift_allowed > 50ms 集群状态变为 HEALTH_WARN
ceph daemon mon.$HOSTNAMEconfig get mon_clock_drift_allowed4. MDSMonitor
MDSMonitor 负责检测元数据服务器(MetaData Server,MDS)的状态变化;处理文件系统(指CephFS)相关的命令,例如创建文件系统、查看文件系统状态等。
- MDS向Mon发送心跳时间间隔(mds_beacon_interval) //默认 4 秒
- Mon判断MDS failed的超时时间(mds_beacon_grace) //默认 15 秒
核心参数介绍:
- max_mds:同时处于 active 状态的 MDS 守护进程的最大数量
- active:实际处理客户端的元数据请求的MDS
- Standby MDS: 已启动并正常运行,但不处理客户端请求,而是作为备用资源
5.MDS 故障切换流程
- 当 MDS 正常运行时,它会定期向 Monitor 发送 Beacon 心跳。Monitor 会检查 Beacon 是否超时(默认超时时间为 4 秒)
- 若 Beacon 未超时,MDS 继续保持正常运行状态。
- 若 Beacon 超时,MDS 停止发送 Beacon,Monitor 开始等待 mds_beacon_grace 宽限期(默认 15 秒)。
如果在宽限期内仍未收到该 MDS 的 Beacon,Monitor 判定该 MDS 失效,并更新 FSMap(文件系统地图)。接下来,Monitor 会检查当前活跃 MDS 数量是否小于配置的 max_mds 值:- 如果活跃 MDS 数量已达到 max_mds,则无法直接提升备用 MDS,仅记录异常状态,不进行切换。
- 如果活跃 MDS 数量小于 max_mds,Monitor 将从 Standby 备用 MDS 列表中选择一个,更新 FSMap,将该备用 MDS 提升为活跃状态,并分配故障 MDS 的 rank。
- 随后,更新后的 FSMap 通过 Paxos 提交给所有 Monitor。新晋升的活跃 MDS 会从元数据池中加载并更新元数据,之后开始正常处理客户端请求,完成故障切换。
6. MGR介绍
在 Ceph Luminous 版本之前,所有集群监控和状态上报的任务均由 Monitor 承担。在 CERN 2016 年的“Big Bang II”压力测试中,随着集群规模增长至近万个 OSD,问题逐渐显现:OSD 需要定期向 Monitor 上报负载、利用率等信息。当 OSD 数量极其庞大时,这些高频次、短暂性的“ephemeral”状态数据产生了巨大的网络和 I/O 压力,严重影响了 Monitor 的复制与持久化能力,导致其无法及时处理更关键的、需要达成共识的集群地图(Cluster Map)变更。
为解决这一瓶颈,Sage Weil 教授主导开发了全新的 Ceph Manager(MGR)组件,用于分担 Monitor 的压力。自此,集群的容量、性能、状态等统计数据均由 MGR 组件负责采集和提供。以下是我们常用的一些命令,这些命令输出的信息均由 MGR 负责统计汇总。
ceph health detail //查看集群状态详情 cephdf//查看集群容量 ceph osd pool stats //查看集群IO ceph osd perf //查看OSD时延三、存储池的管理结构
1. min_size与size
size、min_size 分别指存储池的最大副本数和最小副本数,其中最小副本数指示存储池对于灾难的最大容忍程度。
size 由用户在创建存储池时指导,min_size 则由系统根据 size 自动计算。
不同备份策略下的 min_size 计算方式如下:
- 多副本:min_size = (size+1) / 2
- 纠删码:min_size = k(k为编码块数量)
多副本
纠删码
假设以主机为故障域,一份数据按照三副本的冗余策略分别存储在host01、host02和host03上。当host01发生故障宕机后,存活的节点由三台减少为两台,相应的数据副本也从三副本降为两副本。如果此时size设置为3,min_size设置为2,系统仍能正常进行数据读写——只要存活副本数不低于min_size,客户端访问就不会受到影响。
在故障发生后,集群会自动触发数据回填(backfilling)流程,将host01上的数据迁移至其他可用节点(前提是集群中可用主机数量大于3),以最终恢复满足size=3的副本分布。在数据迁移过程中,对应PG的状态将从active+clean变为degraded。若在此期间再次发生节点故障(例如host02也宕机),导致存活副本数小于min_size,则数据写入将被禁止,仅能支持读取操作,PG状态也随之从degraded变为inactive。
由此可见,在故障场景下数据能否正常读写,最终由min_size参数决定。
!【生产环境必看】临时解决方法,将min_size调小,pg状态由inactive变成active,客户端恢复读写。
ceph osd pool get<pool_name>min_size //查看pool的min_size ceph osd poolset<pool_name>min_size1//调小min_size,临时恢复业务,一般生产环境min_size都配成1,但也有风险,如果最后一个副本也丢失了,数据在集群中完全丢失了(可能还存在硬盘上,如果硬盘没坏,将OSD拉起来数据还在,如果硬盘彻底坏了,可以找数据恢复公司复原,很麻烦)调小min_size可以提高客户端访问不中断的概率,但也会降低数据存放的安全性,需要我们的运维同事多多上心,平时有硬件故障的时候要及时更换,老化设备也要趁早替换。2. pg与pgp
在 Ceph 存储集群中,数据是以存储池(Pool)为逻辑单元进行管理的。每个存储池会被进一步划分为多个放置组(Placement Group,简称 PG),PG 是数据分布和故障恢复的基本单位。可以这样理解:PG 决定了数据被切分成多少份小分片,而 PGP(Placement Group for Placement)则决定了这些分片具体如何放置到 OSD 上。PG 与 PGP 在数值上的关系直接影响着数据的均衡状态。当我们需要调整存储池的 PG 数量时,有两个关键参数:pg_num 和 pgp_num。它们的区别和作用如下:
- pg_num:指定存储池应拥有的 PG 数量。增大 pg_num 仅仅是在逻辑上增加分片的数量,不会触发数据在 OSD 间的重新分布(即不改变现有数据的放置位置)。
- pgp_num:控制 PG 在 OSD 上的实际分布策略。只有当 pgp_num 增大时,Ceph 才会重新计算数据的位置,启动数据迁移,使新增的 PG 分散到不同的 OSD 上,从而实现集群的负载均衡。
因此,在扩容 PG 数量时,正确的操作方式是:
- 先调整 pg_num:可以一次性将 pg_num 增大到目标值,这个操作只是增加 PG 的计数,不会引起数据迁移,对集群影响较小。
- 再逐步调整 pgp_num:将 pgp_num 逐步增大,直到与 pg_num 相等。由于 pgp_num 的每次增加都会触发数据重新均衡,为了避免大量数据同时迁移造成集群卡顿,建议以 2 的幂次(例如 2048 → 4096 → 8192 → 16384 → 32768)分多次调大,给数据迁移留出平稳过渡的时间。
!【生产环境必看】 扩容pg_num和pgp_num的正确顺序:
1、先给集群设置标志位flags ceph osdsetnobackfill //禁止回填数据 ceph osdsetnorecover //禁止恢复数据 ceph osdsetnorebalance //禁止均衡数据2、扩容OSD中...... 待OSD扩容完成,扩容pg_num和pg_num ceph osd poolset<pool_name>pg_num32768//pg_num一步到位 ceph osd poolset<pool_name>pgp_num4096ceph osd poolset<pool_name>pgp_num16384ceph osd poolset<pool_name>pg_num32768//pgp_num一点点调大,每次都需要是2的次幂3、OSD扩容完成,取消标志位,待集群完成数据均衡,pg状态变为active+clean ceph osdunsetnobackfill //取消禁止回填数据 ceph osdunsetnorecover //禁止恢复数据 ceph osdunsetnorebalance //禁止均衡数据