Ceph Stretch 集群(第二部分):双站点加仲裁者

Daniel Parkes, Anthony D'Atri (IBM)

Ceph Stretch 集群(第二部分):双站点加仲裁者

简介

第一部分 中,我们介绍了 Ceph 的复制策略背后的概念,强调了 stretch 集群在实现零数据丢失 (RPO=0) 方面的优势。在第二部分中,我们将重点介绍使用 cephadm 部署双站点 stretch 集群以及仲裁器 Monitor 的实际步骤。

网络注意事项。

网络架构

stretch 架构中,网络在维护集群的整体健康和性能方面起着至关重要的作用。

  • Ceph 具有 3 级路由功能,可在每个数据中心/站点的子网和 CIDR 之间实现 Ceph 服务器和组件之间的通信。

  • Ceph 独立或 stretch 集群可以配置两种不同的网络

    • 公网:用于所有 Ceph 客户端和服务之间的通信,包括 Monitor、OSD、RGW 等。
    • 集群网络:如果配置了(可选),集群(也称为复制后端私有网络)仅用于 OSD 之间的心跳、恢复和复制,因此只需要在位于 OSD 的数据站点配置。更微妙的是,此可选复制网络不需要任何默认路由(网关)到更大的互联网。

公网和集群网络注意事项

  • 单个公网必须可访问所有三个站点,包括仲裁器站点,因为所有 Ceph 服务都依赖它。

  • 集群网络只需要在包含 OSD 的两个站点之间,不应在仲裁器站点配置。

网络可靠性

OSD 站点之间的网络不稳定会导致集群出现可用性和性能问题。

  • 网络不仅必须 100% 的时间可访问,还必须提供一致的延迟(低抖动)。

  • 频繁的延迟峰值会导致集群不稳定,影响客户端性能,包括 OSD 闪烁、Monitor 仲裁丢失以及请求缓慢(阻塞)。

延迟要求

  • 数据站点之间 OSD 之间的最大 10 毫秒 RTT(网络数据包往返时间)是可以容忍的。

  • 仲裁器站点最多可接受 100 毫秒 RTT,如果安全策略允许,可以将仲裁器站点部署为 VM 或在云提供商处部署。

如果仲裁器节点位于云端或远程网络(通过 WAN)上,建议

  • 在数据站点和仲裁器站点之间建立 VPN 以用于公网。

  • 启用传输中的加密,使用 Ceph messenger v2 加密,从而保护 Monitor 和其他 Ceph 组件之间的通信。

延迟对性能的影响

  • Ceph 中的每个写操作都采用强一致性。写入的数据必须持久化到配置的所有 OSD 中,才能向客户端确认成功。

  • 这至少会将站点之间的网络 RTT(往返时间)添加到每个客户端写操作的延迟中。请注意,这些复制写入(子操作)从主 OSD 到辅助 OSD 是并行发生的。

[!info] 例如,如果站点之间的 RTT 为 6 毫秒,则每个写操作至少会增加 6 毫秒的延迟,这是由于站点之间的复制造成的。

吞吐量和恢复注意事项

  • 站点间带宽(吞吐量)限制

    • 最大客户端吞吐量。
    • 当 OSD、节点或站点发生故障或随后恢复可用时,恢复速度。
  • 当节点发生故障时,67% 的恢复流量将是远程流量,这意味着它将从另一个站点的 OSD 读取三分之二的数据,消耗共享的站点间带宽以及客户端 IO。

  • Ceph 为每个放置组 (PG) 指定一个 OSD。所有客户端写入都通过此主 OSD 进行,该主 OSD 可能位于与客户端或 RGW 实例不同的数据中心。

使用 read_from_local_replica 优化读取

  • 默认情况下,所有读取都通过主 OSD 进行,这会增加站点间的延迟。

  • read_from_local_replica 功能允许 RGW 和 RBD 客户端从同一站点(本地)的副本读取数据,而不是始终从 OSD 读取数据,后者有 50% 的几率位于另一个站点。

  • 这可最大限度地减少站点间延迟,降低站点间带宽使用率,并提高读取密集型工作负载的性能。

  • 自 Squid 起,适用于块(RBD)和对象(RGW)存储。CephFS 客户端尚未实现本地读取。

硬件要求

stretch 集群的硬件要求与传统(独立、非 stretch)部署的硬件要求相同,但有一些例外,将在下面讨论。

  • Ceph 在 stretch 模式下建议使用全闪存(SSD)配置。不建议在任何 stretch Ceph 集群角色中使用 HDD 介质。请注意。

  • Ceph 在 stretch 模式下需要使用 size=4 的复制数据保护策略。不支持擦除编码或使用较少副本的复制。相应地规划原始和可用存储容量。

  • 集群中包含 type replicated class hdd 的 CRUSH 规则将不起作用。如果任何 CRUSH 规则指定设备类(通常为 ssd,但也可能是 nvme),则所有 CRUSH 规则都必须指定该设备类。

  • 不支持仅本地的非 stretch 池。也就是说,任何站点都不能配置不扩展到另一个站点的池。

组件放置

Ceph 服务,包括 Monitor、OSD 和 RGW,必须放置以消除单点故障,并确保集群在整个站点丢失的情况下仍能访问数据。

  • Monitor:需要至少五个 Monitor,每个数据站点两个,仲裁器站点一个。这种策略通过确保即使整个站点离线,超过 50% 的 Monitor 可用,从而保持仲裁。

  • Manager:我们可以在每个数据站点配置两个或四个 Manager。建议配置四个 Manager,以便在数据站点发生故障时,在幸存站点提供高可用性(主动/被动对)。

  • OSD:均匀分布在数据站点。在配置 stretch 模式时,必须创建自定义 CRUSH 规则,在每个站点放置两个副本,对于双站点 stretch 集群,总共四个副本。

  • RGW:建议至少配置四个 RGW 实例,每个数据站点两个,以确保在站点发生故障时,从剩余站点获得对象存储的高可用性。

  • MDS:CephFS 元数据服务器实例的最小建议数量为四个,每个数据站点两个。如果站点发生故障,我们仍然会在剩余站点有两个 MDS 服务,一个处于活动状态,另一个作为待机状态。

  • NFS:建议至少配置四个 NFS 服务器实例,每个数据站点两个,以确保在站点离线时共享文件系统的高可用性。

动手实践:双数据中心 Stretch 模式部署。

在集群引导过程中,使用 cephadm 部署工具,我们可以使用服务定义 YAML 文件来处理大多数集群配置,一次完成。

下面的 stretched.yaml 文件提供了一个配置 stretch 模式 Ceph 集群的示例模板。这只是一个示例,必须根据部署的详细信息和需求进行自定义。

service_type: host
addr: ceph-node-00.cephlab.com
hostname: ceph-node-00
labels:
  - mon
  - osd
  - rgw
  - mds
location:
  root: default
  datacenter: DC1
---

service_type: host
addr: ceph-node-01.cephlab.com
hostname: ceph-node-01
labels:
  - mon
  - mgr
  - osd
  - mds
location:
  root: default
  datacenter: DC1
---

service_type: host
addr: ceph-node-02.cephlab.com
hostname: ceph-node-02
labels:
  - osd
  - rgw
location:
  root: default
  datacenter: DC1
---

service_type: host
addr: ceph-node-03.cephlab.com
hostname: ceph-node-03
labels:
  - mon
  - osd
location:
  root: default
  datacenter: DC2
---

service_type: host
addr: ceph-node-04.cephlab.com
hostname: ceph-node-04
labels:
  - mon
  - mgr
  - osd
  - mds
location:
  root: default
  datacenter: DC2
---

service_type: host
addr: ceph-node-05.cephlab.com
hostname: ceph-node-05
labels:
  - osd
  - rgw
  - mds
location:
  root: default
  datacenter: DC2
---

service_type: host
addr: ceph-node-06.cephlab.com
hostname: ceph-node-06
labels:
  - mon
---
service_type: mon
service_name: mon
placement:
  label: mon
spec:
  crush_locations:
    ceph-node-00:
    - datacenter=DC1
    ceph-node-01:
    - datacenter=DC1
    ceph-node-03:
    - datacenter=DC2
    ceph-node-04:
    - datacenter=DC2
    ceph-node-06:
    - datacenter=DC3

---
service_type: mgr
service_name: mgr
placement:
  label: mgr
---

service_type: mds
service_id: cephfs
placement:
  label: "mds"

---
service_type: osd
service_id: all-available-devices
service_name: osd.all-available-devices
spec:
  data_devices:
    all: true
placement:
  label: "osd"

使用针对部署自定义的规范文件,运行 cephadm bootstrap 命令。请注意,我们使用 --apply-spec stretched.yml 传递 YAML 规范文件,以便一步部署和配置所有服务。

# cephadm bootstrap --registry-json login.json --dashboard-password-noupdate --mon-ip 192.168.122.12 --apply-spec stretched.yml --allow-fqdn-hostname

完成后,验证集群是否识别所有主机及其适当的标签

# ceph orch host ls
HOST          ADDR             LABELS                  STATUS
ceph-node-00  192.168.122.12   _admin,mon,osd,rgw,mds
ceph-node-01  192.168.122.179  mon,mgr,osd
ceph-node-02  192.168.122.94   osd,rgw,mds
ceph-node-03  192.168.122.180  mon,osd,mds
ceph-node-04  192.168.122.138  mon,mgr,osd
ceph-node-05  192.168.122.175  osd,rgw,mds
ceph-node-06  192.168.122.214  mon

_admin 标签添加到每个数据中心至少一个节点,以便您可以运行 Ceph CLI 命令。这样,即使您丢失了整个数据中心,也可以从幸存主机执行 Ceph 管理命令。将 _admin 标签分配给所有集群节点也很常见。

# ceph orch host label add ceph-node-03 _admin
Added label _admin to host ceph-node-03
# ceph orch host label add ceph-node-06 _admin
Added label _admin to host ceph-node-06
# ssh ceph-node-03 ls /etc/ceph
ceph.client.admin.keyring
ceph.conf

动手实践:Ceph 如何在每个站点写入数据的两个副本?

Ceph 在配置 stretch 模式时,需要所有池都使用 size=4 的复制数据保护策略。这意味着在每个站点有两个副本,确保在整个站点关闭时可用。

Ceph 使用 CRUSH 映射来确定放置数据副本的位置。CRUSH 映射以分层桶类型的形式逻辑地表示物理硬件布局,包括 datacentersrooms 以及通常的 rackshosts。要配置 stretch 模式 CRUSH 映射,我们定义两个 datacenters 在默认 CRUSH 根目录下,然后将主机桶放置在适当的 datacenter CRUSH 桶中。

以下示例显示了一个 stretch 模式 CRUSH 映射,其中包含两个数据中心 DC1 和 DC2,每个数据中心包含三个 Ceph OSD 主机。我们通过在引导期间使用的规范文件获得此拓扑,我们指定 CRUSH 映射中每个主机的位置。

# ceph osd tree
ID  CLASS  WEIGHT   TYPE NAME                  STATUS  REWEIGHT  PRI-AFF
-1         0.58557  root default
-3         0.29279      datacenter DC1
-2         0.09760          host ceph-node-00
 0    hdd  0.04880              osd.0              up   1.00000  1.00000
 1    hdd  0.04880              osd.1              up   1.00000  1.00000
-4         0.09760          host ceph-node-01
 3    hdd  0.04880              osd.3              up   1.00000  1.00000
 7    hdd  0.04880              osd.7              up   1.00000  1.00000
-5         0.09760          host ceph-node-02
 2    hdd  0.04880              osd.2              up   1.00000  1.00000
 5    hdd  0.04880              osd.5              up   1.00000  1.00000
-7         0.29279      datacenter DC2
-6         0.09760          host ceph-node-03
 4    hdd  0.04880              osd.4              up   1.00000  1.00000
 6    hdd  0.04880              osd.6              up   1.00000  1.00000
-8         0.09760          host ceph-node-04
10    hdd  0.04880              osd.10             up   1.00000  1.00000
11    hdd  0.04880              osd.11             up   1.00000  1.00000
-9         0.09760          host ceph-node-05
 8    hdd  0.04880              osd.8              up   1.00000  1.00000
 9    hdd  0.04880              osd.9              up   1.00000  1.00000

这里有两个数据中心,DC1DC2。第三个数据中心 DC3 托管仲裁器 Monitor 在 ceph-node-06 上,但不托管 OSD。

为了实现每个站点有两个副本的目标,我们定义一个 stretch CRUSH 规则分配给我们的 Ceph RADOS 池。

  • 安装 ceph-base 包以获取 crushtool 二进制文件,此处在 RHEL 系统上演示。
# dnf -y install ceph-base
  • 将 CRUSH 映射导出到二进制文件
# ceph osd getcrushmap > crush.map.bin
  • 将 CRUSH 映射反编译为文本文件
# crushtool -d crush.map.bin -o crush.map.txt
  • 编辑 crush.map.txt 文件,在文件末尾添加一个新规则,注意数字规则 id 属性必须是唯一的
rule stretch_rule {
        id 1
        type replicated
        step take default
        step choose firstn 0 type datacenter
        step chooseleaf firstn 2 type host
        step emit
}

  • 注入增强的 CRUSH 映射以使规则在集群中可用
# crushtool -c crush.map.txt -o crush2.map.bin
# ceph osd setcrushmap -i crush2.map.bin
  • 验证新规则是否可用
# ceph osd crush rule ls
replicated_rule
stretch_rule

动手实践:配置 Stretch 模式下的 Monitor

感谢我们的引导规范文件,Monitor 根据其所属的数据中心进行了标记。这种标记确保 Ceph 即使在一个数据中心发生故障也能保持仲裁。在这种情况下,位于 DC 3 中的仲裁器 Monitor 将与幸存数据站点的 Monitor 协同工作,以保持集群的 Monitor 仲裁。

# ceph mon dump | grep location
0: [v2:192.168.122.12:3300/0,v1:192.168.122.12:6789/0] mon.ceph-node-00; crush_location {datacenter=DC1}
1: [v2:192.168.122.214:3300/0,v1:192.168.122.214:6789/0] mon.ceph-node-06; crush_location {datacenter=DC3}
2: [v2:192.168.122.138:3300/0,v1:192.168.122.138:6789/0] mon.ceph-node-04; crush_location {datacenter=DC2}
3: [v2:192.168.122.180:3300/0,v1:192.168.122.180:6789/0] mon.ceph-node-03; crush_location {datacenter=DC2}
4: [v2:192.168.122.179:3300/0,v1:192.168.122.179:6789/0] mon.ceph-node-01; crush_location {datacenter=DC1}

当在三个站点上运行 stretch 集群时,只有当我们在一个站点和另一个站点之间发生不对称网络错误时,通信才会受到影响。这可能会导致无法解决的 Monitor 选举风暴,无法选择 Monitor 作为领导者。

为了避免此问题,我们将选举策略从经典方法更改为基于连接性的方法。连接性模式评估每个 Monitor 为其对等方提供的连接分数,并选举分数最高的 Monitor。此模型专门设计用于处理网络分区,也称为分裂脑。网络分区可能发生在您的集群分布在多个数据中心时,并且连接一个站点到另一个站点的所有链接都丢失时。

# ceph mon dump | grep  election
election_strategy: 1
# ceph mon set election_strategy connectivity
# ceph mon dump | grep  election
election_strategy: 3

您可以使用以下形式的命令检查 Monitor 分数

# ceph daemon mon.{name} connection scores dump

要了解有关 Monitor 连接性选举策略的更多信息,请查看 Greg Farnum 的这个精彩 视频。更多信息也 在此处 提供。

动手实践:启用 Ceph Stretch 模式

要进入 stretch 模式,请运行以下命令

# ceph mon enable_stretch_mode ceph-node-06 stretch_rule datacenter

其中

  • ceph-node-06 是 DC3 中的仲裁器 Monitor。

  • stretch_rule 是强制在每个数据中心有两个副本的 CRUSH 规则。

  • datacenter 是我们的故障域

检查更新后的 MON 配置

# ceph mon dump
epoch 20
fsid 90441880-e868-11ef-b468-52540016bbfa
last_changed 2025-02-11T14:44:10.163933+0000
created 2025-02-11T11:08:51.178952+0000
min_mon_release 19 (squid)
election_strategy: 3
stretch_mode_enabled 1
tiebreaker_mon ceph-node-06
disallowed_leaders ceph-node-06
0: [v2:192.168.122.12:3300/0,v1:192.168.122.12:6789/0] mon.ceph-node-00; crush_location {datacenter=DC1}
1: [v2:192.168.122.214:3300/0,v1:192.168.122.214:6789/0] mon.ceph-node-06; crush_location {datacenter=DC3}
2: [v2:192.168.122.138:3300/0,v1:192.168.122.138:6789/0] mon.ceph-node-04; crush_location {datacenter=DC2}
3: [v2:192.168.122.180:3300/0,v1:192.168.122.180:6789/0] mon.ceph-node-03; crush_location {datacenter=DC2}
4: [v2:192.168.122.179:3300/0,v1:192.168.122.179:6789/0] mon.ceph-node-01; crush_location {datacenter=DC1}

Ceph 特别禁止仲裁器 Monitor 担任领导角色。仲裁器的唯一目的是在其中一个主站点发生故障时提供额外的投票以维持仲裁,防止出现分裂脑场景。通过设计,它位于单独的、通常较小的环境中(可能是在云 VM 中),并且可能具有更高的网络延迟和更少的资源。允许它成为领导者可能会损害性能和一致性。因此,Ceph 将仲裁器 Monitor 标记为 disallowed\leader,确保数据站点保留对集群的主要控制权,同时受益于仲裁器投票。

动手实践:启用 stretch 模式后验证池复制和放置

当启用伸展模式时,对象存储守护进程 (OSD) 仅在它们跨数据中心进行对等连接时才会激活放置组 (PG),前提是两者都可用。以下约束条件适用

  • 每个池的副本数(size 属性)将从默认的 3 增加到 4,预计每个站点有两个副本。

  • OSD 仅允许连接到同一数据中心的监视器。

  • 除非指定了其位置,否则新的监视器无法加入集群。

# ceph osd pool ls detail
pool 1 '.mgr' replicated size 4 min_size 2 crush_rule 1 object_hash rjenkins pg_num 1 pgp_num 1 autoscale_mode on last_change 199 lfor 199/199/199 flags hashpspool stripe_width 0 pg_num_max 32 pg_num_min 1 application mgr read_balance_score 12.12
pool 2 'rbdpool' replicated size 4 min_size 2 crush_rule 1 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 199 lfor 199/199/199 flags hashpspool,selfmanaged_snaps stripe_width 0 application rbd read_balance_score 3.38

检查特定池 ID 的放置组 (PG),并确认哪些 OSD 处于活动集中

# ceph pg dump pgs_brief | grep 2.c
dumped pgs_brief
2.c      active+clean   [2,3,6,9]           2   [2,3,6,9]               2

在此示例中,PG 2.c 具有来自 DC1 的 OSD 2 和 3,以及来自 DC2 的 OSD 6 和 9。

可以使用 ceph osd tree 命令确认这些 OSD 的位置

# ceph osd tree | grep -Ev '(osd.1|osd.7|osd.5|osd.4|osd.0|osd.8)'
ID  CLASS  WEIGHT   TYPE NAME                  STATUS  REWEIGHT  PRI-AFF
-1         0.58557  root default
-3         0.29279      datacenter DC1
-2         0.09760          host ceph-node-00
-4         0.09760          host ceph-node-01
 3    hdd  0.04880              osd.3              up   1.00000  1.00000
-5         0.09760          host ceph-node-02
 2    hdd  0.04880              osd.2              up   1.00000  1.00000
-7         0.29279      datacenter DC2
-6         0.09760          host ceph-node-03
 6    hdd  0.04880              osd.6              up   1.00000  1.00000
-8         0.09760          host ceph-node-04
-9         0.09760          host ceph-node-05
 9    hdd  0.04880              osd.9              up   1.00000  1.00000

这里每个 PG 在 DC1DC2 中都有两个副本,这是伸展模式的核心概念。

结论

通过部署具有第三站点仲裁监视器的双站点伸展集群,即使整个数据中心发生故障,也能确保数据保持高度可用。利用单个规范文件可以实现跨两个站点的自动且一致的服务部署——涵盖监视器、OSD 和其他 Ceph 组件。连接性选举策略也有助于通过优先选择连接良好的监视器来维持稳定的仲裁。将这些元素结合起来:仔细的 CRUSH 配置、正确的标记以及适当的数据保护策略,可以实现一种具有弹性的存储架构,该架构可以处理站点间故障,而不会损害数据的完整性或服务的连续性。

系列文章的最后一部分 中,我们将会在实际故障条件下测试伸展集群。我们将探讨 Ceph 如何在整个站点离线时自动切换到降级状态,故障期间对客户端 I/O 的影响,以及站点恢复后的恢复过程,确保零数据丢失。

作者感谢 IBM 对社区的支持,为我们提供时间来创建这些帖子。