Ceph入门到精通-OSD 故障排除

OSD 故障排除

在对 OSD 进行故障排除之前,请先检查您的显示器和网络。如果你在命令行上 执行or并且 Ceph 显示,这意味着监视器有法定人数。如果您没有监视器法定人数或者如果监视器状态有错误,请首先解决监视器问题。检查您的网络以确保它们正常运行,因为网络可能会对 OSD 操作和性能产生重大影响。查找主机端丢失的数据包和交换机端的 CRC 错误。ceph healthceph -sHEALTH_OK

获取有关 OSD 的数据

对 OSD 进行故障排除的第一步是获取拓扑信息以及您在监视 OSD时收集的信息 (例如,)。ceph osd tree

日志

如果您没有更改默认路径,您可以在以下位置找到 Ceph 日志文件 /var/log/ceph

ls /var/log/ceph

如果您没有看到足够的日志详细信息,您可以更改日志记录级别。有关详细信息,请参阅 日志记录和调试,以确保 Ceph 在高日志记录量下充分执行。

管理套接字

使用管理套接字工具检索运行时信息。有关详细信息,请列出 Ceph 守护进程的套接字:

ls /var/run/ceph

然后,执行以下命令,替换{daemon-name}为实际的守护进程(例如,osd.0):

ceph daemon osd.0 help

或者,您可以指定一个{socket-file}(例如,某物在/var/run/ceph):

ceph daemon {socket-file} help

管理套接字,除其他外,允许您:

  • 在运行时列出您的配置

  • 转储历史操作

  • 转储操作优先级队列状态

  • 飞行中的转储操作

  • 转储性能计数器

显示自由空间

可能会出现文件系统问题。要显示文件系统的可用空间,请执行 df.

df -h

执行其他用途。df --help

输入/输出统计

使用iostat识别与 I/O 相关的问题。

iostat -x

诊断信息

要从内核检索诊断消息,请使用dmesgwith lessmoregrep 。tail例如:

dmesg | grep scsi

停止不重新平衡

您可能需要定期对集群的一个子集执行维护,或者解决影响故障域(例如机架)的问题。如果您不希望 CRUSH 在您停止 OSD 进行维护时自动重新平衡集群,请将集群设置为noout

ceph osd set noout

在 Luminous 或更新版本上,仅在受影响的 OSD 上设置标志更安全。您可以单独执行此操作

ceph osd add-noout osd.0
ceph osd rm-noout  osd.0

或者一次处理整个 CRUSH 桶。假设您要删除 prod-ceph-data1701以添加 RAM

ceph osd set-group noout prod-ceph-data1701

设置标志后,您可以停止故障域中需要维护工作的 OSD 和任何其他位于同一位置的 Ceph 服务。

systemctl stop ceph\*.service ceph\*.target

笔记

degraded 当您在故障域中解决问题时,您停止的 OSD 中的归置组将变为。

完成维护后,重新启动 OSD 和任何其他守护进程。如果作为维护的一部分重新启动主机,这些应该会自行恢复,无需干预。

sudo systemctl start ceph.target

最后,您必须取消设置集群范围内的``noout`` 标志:

ceph osd unset noout
ceph osd unset-group noout prod-ceph-data1701

请注意,目前 Ceph 支持的大多数 Linux 发行版都用于systemd 服务管理。对于其他或较旧的操作系统,您可能需要发出等效的servicestart/stop命令。

OSD 未运行

在正常情况下,只需重新启动ceph-osd守护进程即可使其重新加入集群并恢复。

OSD 无法启动

如果您启动了您的集群,而 OSD 无法启动,请检查以下内容:

  • 配置文件:如果您无法从新安装中运行 OSD,请检查您的配置文件以确保它符合要求(例如,host不是hostname等)。

  • 检查路径:检查配置中的路径,以及数据和元数据(日志、WAL、DB)的实际路径本身。如果您将 OSD 数据与元数据分开,并且您的配置文件或实际挂载中存在错误,则您可能无法启动 OSD。如果您想将元数据存储在单独的块设备上,您应该对驱动器进行分区或 LVM,并为每个 OSD 分配一个分区。

  • 检查最大线程数:如果您的节点有很多 OSD,您可能会达到默认的最大线程数(例如,通常为 32k),尤其是在恢复期间。您可以增加线程数,sysctl看看将最大线程数增加到允许的最大可能线程数(即 4194303)是否有帮助。例如:

    sysctl -w kernel.pid_max=4194303
    

    如果增加最大线程数可以解决问题,您可以通过在主文件下或主文件内的kernel.pid_max文件中包含一个设置来使其永久化。例如:/etc/sysctl.d/etc/sysctl.conf

    kernel.pid_max = 4194303
    
  • 检查``nf_conntrack``:这个连接跟踪和限制系统是许多生产 Ceph 集群的祸根,并且可能是阴险的,因为一开始一切都很好。随着集群拓扑结构和客户端工作负载的增长,神秘的间歇性连接故障和性能故障出现,随着时间的推移和一天中的某些时间变得更糟。检查syslog表填充事件的历史记录。nf_conntrack_max您可以通过提高到更高的值来减轻这种困扰sysctl。一定要nf_conntrack_buckets相应地提高到 ,这可能需要在例如 之外采取行动nf_conntrack_max / 4sysctl"echo 131072 > /sys/module/nf_conntrack/parameters/hashsize 更禁止但更麻烦的是将相关的内核模块列入黑名单以完全禁用处理。这是脆弱的,因为模块因内核版本而异,它们必须列出的顺序也是如此。即使被列入黑名单,在某些情况下iptables还是docker 可能会激活连接跟踪,因此建议对可调参数采用“设置并忘记”策略。在现代系统上,这不会消耗大量资源。

  • 内核版本:确定您正在使用的内核版本和发行版。Ceph 默认使用一些第三方工具,这些工具可能有问题或可能与某些发行版和/或内核版本(例如,GooglegperftoolsTCMalloc)冲突。检查 每个 Ceph 版本的操作系统建议和发行说明,以确保您已解决与内核相关的任何问题。

  • 段错误:如果存在段错误,请提高日志级别并再次启动有问题的守护进程。如果再次出现段错误,请搜索 Ceph 错误跟踪器https://tracker.ceph/com/projects/ceph 和邮件列表存档https://ceph.io/resources。如果这确实是一个新的和独特的故障,请发布到电子邮件列表并提供正在运行的特定 Ceph 版本(秘密 XXX 已经泄露),您的监视器状态输出和日志文件的摘录。devceph-usersdevceph.conf

OSD 失败

当一个ceph-osd进程死亡时,幸存的ceph-osd守护进程将向 mons 报告它出现故障,这将依次通过以下命令显示新状态:ceph health

ceph health
HEALTH_WARN 1/3 in osds are down

in 具体来说,只要有标记为和 的OSD,您就会收到警告down。您可以确定哪些是down

ceph health detail
HEALTH_WARN 1/3 in osds are down
osd.0 is down since epoch 23, last address 192.168.106.220:6800/11080

或者

ceph osd tree down

如果存在驱动器故障或其他阻止ceph-osd运行或重新启动的故障,则错误消息应出现在其 .log 目录下的日志文件中 /var/log/ceph

如果守护程序因心跳故障或 停止,则底层驱动器或文件系统可能没有响应。检查 驱动器或其他内核错误的 系统日志输出。您可能需要指定诸如获取时间戳之类的内容,否则很容易将旧错误误认为新错误。suicide timeoutdmesgdmesg -T

如果问题是软件错误(断言失败或其他意外错误),请按上述方式搜索档案和跟踪器,如果没有明确的修复或存在错误,请将其报告给ceph-devel电子邮件列表。

没有可用的驱动器空间

Ceph 会阻止您写入完整的 OSD,以免丢失数据。在运行集群中,当集群的 OSD 和池接近满率时,您应该会收到警告。在停止客户端写入数据之前,默认为 ,或容量的 95 % 。 默认为,即 90% 的容量,超过该容量将不会启动回填。OSD nearfull ratio 默认为,即当它生成健康警告时容量的 85%。mon osd full ratio0.95mon osd backfillfull ratio0.900.85

请注意,集群中的各个 OSD 会因 Ceph 分配给它们的数据量而异。可以为每个 OSD 显示此利用率

ceph osd df

可以检查整个集群/池的完整性

ceph df

密切关注最满的OSD,而不是 报告的原始空间使用百分比。只需要一个离群的 OSD 填满就会导致对其池的写入失败。报告的每个池的可用空间 考虑了相对于作为给定池一部分的最满OSD的比率设置。通过使用命令将数据从过满或不足的 OSD 逐步移动,可以使分布变平 。随着 Ceph 的发布以及 Luminous 的后期修订,人们也可以利用该模块自动且相当有效地执行此任务。ceph dfceph dfreweight-by-utilizationceph-mgr balancer

比率可以调整:

ceph osd set-nearfull-ratio <float[0.0-1.0]>
ceph osd set-full-ratio <float[0.0-1.0]>
ceph osd set-backfillfull-ratio <float[0.0-1.0]>

当 OSD 作为测试失败或在小型和/或非常满或不平衡的集群中有机地失败时,可能会出现完整的集群问题。当 OSD 或节点拥有集群数据的超大百分比时, 由于组件故障甚至自然增长,可能会超过nearfull和比率。full如果您在小型集群上测试 Ceph 对 OSD 故障的反应,您应该保留足够的可用磁盘空间并考虑暂时降低 OSD 、 OSD和 OSDfull ratiobackfillfull rationearfull ratio

完整ceph-osds将由以下人员报告:ceph health

ceph health
HEALTH_WARN 1 nearfull osd(s)

或者:

ceph health detail
HEALTH_ERR 1 full osd(s); 1 backfillfull osd(s); 1 nearfull osd(s)
osd.3 is full at 97%
osd.4 is backfill full at 91%
osd.2 is near full at 87%

处理完整集群的最佳方法是通过新的 OSD 增加容量,使集群能够将数据重新分配到新的可用存储。

如果旧版 Filestore OSD 已满而无法启动,您可以回收一些空间,删除完整 OSD 中的一些归置组目录。

重要的

如果您选择删除一个已满 OSD 上的归置组目录, 请不要删除另一个已满 OSD 上的相同归置组目录,否则 您将丢失数据。您必须在至少一个 OSD 上维护至少一份数据副本。这是一次罕见且极端的干预,不能轻率地进行。

有关更多详细信息,请参阅监视器配置参考

OSD 缓慢/无响应

一个常见的问题是 OSD 缓慢或无响应。在深入研究 OSD 性能问题之前,请确保您已排除其他故障排除可能性。例如,确保您的网络正常工作并且您的 OSD 正在运行。检查 OSD 是否限制了恢复流量。

提示

较新版本的 Ceph 通过防止恢复 OSD 耗尽系统资源,从而提供更好的恢复处理,从而使upOSDin 不可用或变慢。

网络问题

Ceph 是一个分布式存储系统,因此它依赖网络进行 OSD 对等和复制、故障恢复和周期性心跳。网络问题可能会导致 OSD 延迟和 OSD 抖动。有关详细信息,请参阅Flapping OSD

确保 Ceph 进程和 Ceph 相关进程已连接和/或侦听。

netstat -a | grep ceph
netstat -l | grep ceph
sudo netstat -p | grep ceph

检查网络统计信息。

netstat -s

驱动配置

一个 SAS 或 SATA 存储驱动器应该只容纳一个 OSD;NVMe 驱动器可轻松处理两个或更多。如果其他进程共享驱动器,包括日志/元数据、操作系统、Ceph 监视器、系统日志、其他 OSD 和非 Ceph 进程,读写吞吐量可能会出现瓶颈 。

Ceph在记录日志确认写入,因此快速 SSD 是加速响应时间的有吸引力的选择——尤其是在将XFSext4文件系统用于遗留 Filestore OSD 时。相比之下,Btrfs 文件系统可以同时写入和记录日志。(但请注意,我们建议不要将其用于Btrfs生产部署。)

笔记

对驱动器进行分区不会改变其总吞吐量或顺序读/写限制。在单独的分区中运行日志可能会有所帮助,但您应该更喜欢单独的物理驱动器。

坏扇区/碎片磁盘

检查您的驱动器是否存在坏块、碎片和其他可能导致性能大幅下降的错误。宝贵的工具包括dmesgsyslog 日志和smartctl(来自smartmontools包)。

共同驻留监视器/OSD

监视器是相对轻量级的进程,但它们会发出大量 fsync()调用,这可能会干扰其他工作负载,尤其是当监视器与 OSD 在同一驱动器上运行时。此外,如果您在与 OSD 相同的主机上运行监视器,您可能会遇到与以下相关的性能问题:

  • 运行较旧的内核(3.0 之前的版本)

  • 运行没有系统调用的内核syncfs(2)

在这些情况下,在同一台主机上运行的多个 OSD 可以通过进行大量提交来相互拖累。这通常会导致突发写入。

共同驻留进程

启动共驻进程(融合),例如基于云的解决方案、虚拟机和其他将数据写入 Ceph 的应用程序,同时在与 OSD 相同的硬件上运行可能会引入显着的 OSD 延迟。通常,我们建议优化主机以用于 Ceph,并将其他主机用于其他进程。将 Ceph 操作与其他应用程序分开的做法可能有助于提高性能,并可能简化故障排除和维护。

记录级别

如果您调高日志级别来跟踪问题,然后忘记调低日志级别,OSD 可能会将大量日志放到磁盘上。如果您打算保持较高的日志记录级别,您可以考虑将驱动器安装到默认路径以进行日志记录(即/var/log/ceph/$cluster-$name.log)。

恢复节流

根据您的配置,Ceph 可能会降低恢复率以保持性能,或者它可能会提高恢复率以达到恢复影响 OSD 性能的程度。检查 OSD 是否正在恢复。

内核版本

检查您正在运行的内核版本。较旧的内核可能无法接收 Ceph 为获得更好性能所依赖的新反向端口。

SYNCFS 的内核问题

尝试为每台主机运行一个 OSD 以查看性能是否有所提高。旧内核可能没有足够新的版本glibc来支持syncfs(2).

文件系统问题

目前,我们建议部署带有 BlueStore 后端的集群。在运行 Luminous 之前的版本时,或者如果您有特定原因要使用以前的 Filestore 后端部署 OSD,我们建议XFS.

我们建议不要使用Btrfsor ext4。文件Btrfs系统有许多吸引人的特性,但错误可能会导致性能问题和虚假的 ENOSPC 错误。我们不推荐 ext4Filestore OSD,因为xattr限制会破坏对长对象名称的支持,而长对象名称是 RGW 所需要的。

有关详细信息,请参阅文件系统建议

内存不足

我们建议每个 OSD 守护进程至少有 4GB 的 RAM,并建议从 6-8GB 取整。您可能会注意到,在正常操作期间,ceph-osd 进程仅使用该数量的一小部分。未使用的 RAM 很容易将多余的 RAM 用于共存应用程序或减少每个节点的内存容量。然而,当 OSD 经历恢复时,它们的内存利用率会出现峰值。如果可用 RAM 不足,OSD 性能将大大降低,守护进程甚至可能崩溃或被 Linux 杀死。OOM Killer

阻塞的请求或缓慢的请求

如果ceph-osd守护进程对请求的响应速度很慢,则会记录消息,指出操作花费的时间太长。警告阈值默认为 30 秒,可通过 设置进行配置。发生这种情况时,集群日志将收到消息。osd op complaint time

Ceph 的旧版本抱怨:old requests

osd.0 192.168.106.220:6800/18813 312 : [WRN] old request osd_op(client.5099.0:790 fatty_26485_object789 [write 0~4096] 2.5e54f643) v4 received at 2012-03-06 15:42:56.054801 currently waiting for sub ops

新版本的 Ceph 抱怨:slow requests

{date} {osd.num} [WRN] 1 slow requests, 1 included below; oldest blocked for > 30.005692 secs
{date} {osd.num}  [WRN] slow request 30.005692 seconds old, received at {date-time}: osd_op(client.4240.0:8 benchmark_data_ceph-1_39426_object7 [write 0~4194304] 0.69848840) v4 currently waiting for subops from [610]

可能的原因包括:

  • 驱动器故障(检查dmesg输出)

  • 内核文件系统中的错误(检查dmesg输出)

  • 过载的集群(检查系统负载、iostat 等)

  • 守护进程中的错误ceph-osd

可能的解决方案:

  • 从 Ceph 主机中移除虚拟机

  • 升级内核

  • 升级 Ceph

  • 重启 OSD

  • 更换故障或故障组件

调试慢速请求

如果运行or ,您将看到一组操作和每个操作经历的事件列表。这些在下面简要描述。ceph daemon osd.<id> dump_historic_opsceph daemon osd.<id> dump_ops_in_flight

Messenger 层的事件:

  • header_read:当信使第一次开始在线上阅读消息时。

  • throttled:当信使试图获取内存限制空间以将消息读入内存时。

  • all_read:当信使读完线下的消息时。

  • dispatched:当信使将消息传递给 OSD 时。

  • initiated: 这与header_read. 两者的存在都是历史上的怪事。

OSD 处理操作时的事件:

  • queued_for_pg: 该op已被放入队列中,等待其PG处理。

  • reached_pg: PG已经开始做op了。

  • waiting for \*:操作正在等待其他一些工作完成,然后才能继续(例如,一个新的 OSDMap;等待它的对象目标被擦除;等待 PG 完成对等;所有这些都在消息中指定)。

  • started: 该操作已被接受为 OSD 应该做的事情,现在正在执行。

  • waiting for subops from: op 已发送到副本 OSD。

活动来自`Filestore`

  • commit_queued_for_journal_write: op 已被提供给 FileStore。

  • write_thread_in_journal_buffer:操作在日志的缓冲区中并等待被持久化(作为下一个磁盘写入)。

  • journaled_completion_queued:操作已记录到磁盘,其回调已排队等待调用。

将数据提供给底层存储后来自 OSD 的事件:

  • op_commit: 该操作已被主 OSD 提交(即写入日志)。

  • op_applied: op 已经被write()'en到主服务器上的支持 FS(即应用在内存中但没有刷新到磁盘)。

  • sub_op_appliedop_applied,但对于副本的“subop”。

  • sub_op_committedop_commit,但对于副本的子操作(仅适用于 EC 池)。

  • sub_op_commit_rec/sub_op_apply_rec from <X>:主要在听到上述内容时标记此,但针对特定副本(即<X>)。

  • commit_sent:我们向客户端(或主 OSD,用于子操作)发回回复。

其中许多事件看似多余,但在内部代码中跨越了重要的边界(例如将数据跨锁传递到新线程中)。

摆动 OSD

当 OSD 对等并检查心跳时,它们会在可用时使用集群(后端)网络。有关详细信息,请参阅监视器/OSD 交互

我们传统上推荐单独的公共(前端)和私有 (集群/后端/复制)网络:

  1. 将心跳和复制/恢复流量(私有)与客户端和 OSD <-> mon 流量(公共)隔离。这有助于防止其中一个对另一个进行 DoS 攻击,而后者又可能导致级联故障。

  2. 公共和私人流量的额外吞吐量。

当常见的网络技术为 100Mb/s 和 1Gb/s 时,这种分离通常很关键。对于今天的 10Gb/s、40Gb/s 和 25/50/100Gb/s 网络,上述容量问题通常会减少甚至消除。例如,如果您的 OSD 节点有两个网络端口,将一个专用于公共网络,另一个专用于专用网络意味着没有路径冗余。这会降低您在不对集群或客户端产生重大影响的情况下应对网络维护和故障的能力。考虑将两条链路仅用于公共网络:通过绑定 (LACP) 或等价路由(例如 FRR),您可以获得增加吞吐量余量、容错和减少 OSD 抖动的好处。

当私有网络(甚至单个主机链路)发生故障或降级而公共网络正常运行时,OSD 可能无法很好地处理这种情况。down发生的事情是 OSD 使用公共网络向监视器相互报告,同时标记自己up。然后监视器再次在公共网络上发送更新的集群图,其中受影响的 OSD 标记为 down。这些 OSD 回复监视器“我还没死!”,然后循环重复。我们称这种情况为“震荡”,它很难隔离和修复。在没有专用网络的情况下,可以避免这种令人讨厌的动态:OSD 通常会updown不会抖动。

如果某些事情确实导致 OSD ‘抖动’(反复被标记down然后up再次被标记),您可以通过暂时冻结它们的状态来强制监视器停止抖动:

ceph osd set noup      # prevent OSDs from getting marked up
ceph osd set nodown    # prevent OSDs from getting marked down

这些标志记录在 osdmap 中:

ceph osd dump | grep flags
flags no-up,no-down

您可以使用以下方法清除标志:

ceph osd unset noup
ceph osd unset nodown

支持另外两个标志,noinnoout,它们防止引导 OSD 被标记in(分配数据)或保护 OSD 最终不被标记out(无论当前值是多少 )。mon osd down out interval

笔记

noupnoout, 和nodown是暂时的,因为一旦标志被清除,他们阻止的动作应该会在不久之后发生。noin另一方面,该标志防止 OSDin在启动时被标记,并且在设置该标志时启动的任何守护进程将保持这种状态。

笔记

mon_osd_down_out_subtree_limit通过仔细调整、 mon_osd_reporter_subtree_level和 ,可以在某种程度上减轻抖动的原因和影响mon_osd_min_down_reporters。最佳设置的推导取决于集群大小、拓扑结构和使用的 Ceph 版本。它们的相互作用很微妙,超出了本文档的范围。

猜你喜欢

转载自blog.csdn.net/wxb880114/article/details/130499468