为什么Ceph运维So Hard?

2023-02-23 10:06





前言

Ceph是分布式存储领域最热门的开源软件,起源于Sage Weil博士在加州大学Santa Cruz分校攻读博士期间的研究课题。Ceph具有极强的Scale-Out横向扩展能力,其CRUSH算法在一致性哈希基础上考虑了容灾域的隔离,能够实现各种副本放置规则,例如跨机房、机架感知等。同时, CRUSH支持副本和EC两种数据冗余方式,在数千磁盘规模下仍然能保证良好的负载平衡,是目前经过实践检验的最好的数据分布算法之一。Ceph功能强大,支持块存储、对象存储、分布式文件存储等协议,为 OpenStack提供了良好的支持,成为了目前最火的OpenStack底层存储系统,并在过去几年已成为软件定义存储 (SDS) 的事实标准。

图片


当下,在构建大型、可扩展的IT架构时,用户选择使用经典NAS或SAN设备的可能性越来越小;而是越来越多地使用Ceph分布式存储。其中一个非常显著的原因是:Ceph通常部署在通用x86服务器上,且由于Ceph是专为可扩展性和寿命而设计的,用户不必按照服务器的五年硬件生命周期来替换Ceph分布式存储,而是仅需在系统中持续更换故障硬件、或者移除整台服务器并添加新服务器而不影响业务正常运行。

图片

然而, Ceph运维极其复杂:如果存储系统运行缓慢,需要排查成百上千的大量组件,如CPU负载、内存使用率、网络工作状态、内核与操作系统、时钟同步、服务器主板、存储扩展备板、HBA卡、磁盘状态、各种连接线等等。Ceph故障排查涉及网络、服务器硬件、存储软件、甚至开发人员等所需要使用的综合性故障排查技能,其难度可想而知。

01

Ceph是如何工作的?

一些资深Linux系统管理员可能对Ceph的运维问题不以为然:仅需花费数周时间,一个新的 Ceph集群就可以顺利地搭建起来,整个搭建过程按照最佳实践设计,同时硬件也毫不逊色,比如通过冗余LACP链路实现2x10Gb甚至25G的高速以太网络,甚至还有一个专用网络,使用独立的以太网硬件用于Ceph存储节点之间的流量,这样客户端数据流量和Ceph内部复制的流量就互不干扰。


出于性价比考虑,Ceph大量使用机械硬盘(HDD),遵循Ceph最佳实践,为HDD提供了一种基于SSD的缓存,用于Ceph中的DB/WAL。美好的假设充满诱惑力:一旦数据在这些缓存中结束,客户端就认为写入已完成。这让用户觉得好像他正在写入一个纯SSD 集群。


但随之而来的是震惊:集群最初好像一切工作正常,上线测试也似乎提供了所需的性能,但突然间,业务的读写速度变得十分缓慢,而且没有人真正知道问题出在哪里。这里产生两个问题:管理员如何找出问题的根源?理想情况下,如何持续监控其集群,以便在潜在问题爆发之前识别它们?回答这两个问题,需要对 Ceph工作原理有一定的了解:


RADOS后端存储:Ceph的核心是分布式对象存储RADOS。RADOS被称为对象存储,因为它始终将写入信息视为二进制文件。如果用户将文件上传到RADOS,客户端在上传之前将其分解为多个4MB的对象,然后RADOS将这些对象分布到集群所有硬盘驱动器上。


从逻辑上讲,Ceph包含两大部分,一是 RADOS后端存储,另一部分称为前端,如RBD、对象网关、CephFS文件系统等存储协议接口。用户可以通过上述多种存储协议接口将数据导入Ceph集群。然而,它们都只有在 RADOS对象存储正常工作时才有效,而RADOS依赖MON和OSD两大组建协调工作。

从OSDs到MONs:RADOS的绝对基本功能需要两个组件,OSD和MON。OSD称为对象存储守护进程 。与任何存储系统一样,Ceph的数据最终必须存储在块存储上的某个位置。Ceph通过将每个OSD进程实例绑定到一个物理存储设备,如机械硬盘HDD或固态硬盘SSD,并通过RADOS协议将用户数据均匀分布在集群中。类似于文件系统,OSD会保留日志, 日志提供了重要的故障信息。


MON:即监控服务进程,作为看门狗来跟踪OSD的状态。这不是关于性能监控,而是关于基本的对象存储功能。与任何分布式系统一样,Ceph必须确保只使用集群中具有法定人数的那些部分信息——即大多数MON。否则,如果集群由于网络问题而崩溃,则可能会在集群上并行发生不一致的写入,导致“裂脑”。避免裂脑是任何分布式存储最重要的任务之一。MON会记录哪些 MON 服务器存在 (MONmap) 以及哪些OSD存在(OSDmap)。客户端需要这两条信息才能将二进制对象数据存入RADOS。

02

数据写入如何工作?

为了确保Ceph中数据写入与客户端独立开来,开发人员选择了分布式算法,即客户端实施 CRUSH算法。CRUSH算法在一致性哈希基础上很好的考虑了容灾域的隔离,能够实现各类负载的副本放置规则,例如跨机房、机架感知等。同时,CRUSH算法支持副本和EC两种数据冗余方式。因为客户端通过MON获得 OSDmap的方式知道所有OSD的列表,客户端根据CRUSH,就可以确定数据所对应的OSD。


换言之,如果一个客户端想要在Ceph中存储一些东西,它首先使用CRUSH将要存储的信息分解成二进制对象。在默认配置中,最大大小为 4MB。客户端使用CRUSH为这些对象中的每一个,计算出负责的Primary对象存储守护进程并上传它。


一旦二进制对象进入,OSD就会自行触发另外一个操作,即使用CRUSH来计算对象的Secondary OSD,然后将其复制到那里。只有当对象的总副本数到达相应的数量(默认设置为3),写入过程的确认才会发送到客户端。只有这样,数据写入才被视为完成。

03

监控

Ceph分布式存储运维工作,应当从传统的服务器基础监控开始。即使Ceph可以 自动识别故障硬盘,管理员也希望了解各个硬盘驱动器的状态。困难在于,HDD或SSD仅出现轻微缺陷的情况占比较多;从表面上看,他们似乎仍然可以工作,但写入操作会似乎永远持续下去,并且不会在合理的时间内以错误消息终止。虽然Ceph本身具有Prometheus 等现代监控软件,但管理员不应忽视对服务器自身状况进行监控。服务器硬件问题,例如有缺陷的RAM 或系统过热,往往会导致Ceph机器出现明显的性能问题。

图片

04

网络故障

客户端和RADOS之间,以及 RADOS 中的各个硬盘之间的网络通信,代表了 Ceph 的一个需要重点关注的故障空间。现代交换机和网卡非常复杂,而Ceph使用 Linux 内核中存在的 TCP/IP 堆栈,依赖于现有的网络基础设施才能正常运行。


这要求管理员必须在网络方面仔细监控网络相关硬件,并熟悉并了解网络涉及的性能参数。这说起来容易做起来难:虽然有一个统一的接口SMNP来获取相关信息,然而,在收集相关数据时,几乎每个网络设备制造商都有自己独特的监控管理办法。


如果 Ceph出现性能下降,管理员的第一步是找出它们发生的位置。如果它们发生在客户端和集群之间,则与OSD之间的通信出现问题的情况相比,其他网络硬件可能要负责。当有疑问时,使用 iperf 等工具进行各种点到点的组合测试,逐一排除会有所帮助。

05

Ceph自身故障

假设排除了服务器硬件故障与网络故障,Ceph 故障还可能源于Ceph自身软件栈。这可能会涉及RADOS本身,但运行Ceph的系统内核也可能是问题根源。


幸运的是,有多种监控选项,尤其是在Ceph 级别。Ceph开发者意识到性能监控的复杂性:如果出现最坏情况,您首先必须确定每个对象的主OSD和辅助OSD,然后查看问题所在。


如果系统有成千上万的OSD,查找故障OSD将变得非常具有挑战性。因此OSD在Ceph中具有各种性能指标的记录,比如,当某个OSD进程注意到写入数据花费的时间过长,它会向集群中的所有OSD发送相应的慢写(Slow request)告警信息。


Ceph还提供了多个接口来访问这些信息。最简单的是在MON的节点上启动ceph-w命令,它概述了系统中当前注意到的所有状态及问题,包括写入速度慢。此外,另一个名为“Mgr”进程,可以收集OSD记录的指标数据,并将其提供给Prometheus等监控工具。

06

基于Grafana的仪表盘

Ceph提供仪表盘来显示Ceph集群状态,以各种图形方式显示Ceph自己识别的问题,给系统管理员提供快速概览的机会。Ceph的Mgr组件提供了一个原生的Prometheus接口,可以将Ceph的指标数据传递给Prometheus。Grafana图形化显示模块被集成到仪表盘上,以其丰富的图形展示方式来表示Ceph中重要的运行参数,从而使管理员能够快速发现问题所在。


无论指标数据是通过Ceph仪表盘,还是通过 Prometheus或Grafana显示,核心问题仍然是管理员应该关注哪些数据。四个值在性能监控中起着核心作用:commit_latency_ms指OSD在所有操作中平均需要的时间。操作包括写入硬盘以及启动对辅助OSD的写入。apply_latency_ms指数据到达OSD所需的平均时间。read_bytes_sec和write_bytes_sec给出了集群中正在发生的事情的第一个概述。

07

实践经验

尽管上述的监控措施,理论上可以检测到 Ceph中的问题,但并不意味着运维变得简单。Ceph Mgr向外界传递的许多参数都是由系统中各个OSD的指标值生成的。这些值成千上万,即使是很有经验的Ceph开发人员,弄清楚这些值之间的关系也是一件费脑的事情:知道集群中存在缓慢的写入是一件事;但是,更紧要的任务是快速查找出故障根源。这个过程需要大量的实践经验,且相当困难。


以下是一个具有多年资深经验的Ceph运维工程师描述的例子,描述了如何使用监控细节来诊断Ceph中的性能问题的思路。遗憾的是,这个故障诊断过程并不能合理地自动化。

这是一个总容量约为2.5PB的Ceph集群,主要用于OpenStack。当用户启动一个使用Ceph 中的RBD映像作为根文件系统硬盘的虚拟机时,一个烦人的状态时常会发生:虚拟机在几分钟内遭受I/O停顿并且在一段时间内不可用,一段时间后情况恢复正常,但问题周期性地再次出现。在问题没有出现时,对VM卷的写入操作可达到1.5GB/每秒。


在监控系统也显示了前面描述的卡顿或缓慢写入,但无法辨别究竟与哪个OSD相关。相反,它们分布在系统中的所有OSD中。进一步排查发现,问题与OpenStack无关,因为不经过Openstack的本地RBD映像,也会出现类似的性能问题。


首先怀疑的是网络。然而,经过使用Iperf和类似工具进行的大量测试后,推翻了这种怀疑。在Ceph集群的clients之间,双25Gbit/s LACP链路在Iperf测试中可以达到25Gbit/s以上,且是可靠的。当所有涉及到的NIC和网络交换机上的错误计数器都保持在0时,事情开始变得毫无头绪。


从这里开始需要更深入的故障排查技巧,即开启OSDdebug来跟踪数据写入过程。一旦监控到缓慢的写入过程,就重点检查OSD的日志。事实上,每个OSD都保存着它执行的许多操作的内部记录,主OSD日志还包含单独的条目,显示该对象到辅助OSD的复制操作的开始和结束。使用dump_ops_in_flight命令可以显示OSD当前在Ceph中执行的所有操作,也可以使用dump_historic_slow_ops挖掘过去的慢操作。dump_historic_ops也可用于显示有关所有先前操作的日志消息。利用这些工具,更深入的监控成为可能:现在可以为单个慢速写入找到主OSD,然后所涉及的OSD揭示它计算了哪些辅助OSD的信息。例如,它们在同一写入过程的日志中的消息适用于提供有关有缺陷的HDD相关信息。

图片

按照上述的排查发现,Primary OSD花在等Secondary   OSD响应的大部分时间里,请求到达Secondary OSD往往需要几分钟时间;一旦写入请求实际到达Secondray OSD,它们就会在几毫秒内完成。


由于已经排除了网络硬件故障的可能性,故障的源头指向Ceph的问题。经过大量试验和试错后,焦点落在了所涉及系统的数据包过滤器上。最后的结果出入意料,CentOS 8默认使用的Nftables(iptables 后继者)被证实是问题的根源。这不是配置错误:而是Linux内核中的一个Bug,导致数据包过滤器在某些情况下会因为不明确的模式阻止了数据的正常通信,几分钟中又能恢复通信。这解释了为什么Ceph中的问题出现的非常不稳定。更新到较新的内核最后解决了这个问题。


这个例子清楚地表明:Ceph中的自动化性能监控虽然很强大。但由于Ceph本身的复杂性,管理员通常会面临漫长的故障定位与排查过程。同时,这个例子也证实,使用专用存储厂商的Ceph发行版本非常重要,可以有效地排除各种软硬件与操作系统内核之前的兼容性问题。目前,市场上主流的Ceph厂家除了传统IT大厂如华为、浪潮、新华三,还有新兴的分布式存储专业厂家如道熵、Xsky、杉岩等。

结束语

运维最重要的工具是监控。而Ceph 具备丰富的性能监控,可以使用其用于记录指标数据的模板轻松实现,最终是通过 Ceph 仪表板还是 Prometheus进行显示并不重要。需要指出的是,对服务器各个硬件部件与底层操作系统的经典监控仍然非常重要。


从Ceph层面监控到问题,真正的运维工作才刚刚开始。Ceph运维中遇到最大的困难,在于如何准确定位那些处于濒临失效的硬件,包含机械硬盘、固态硬盘、HBA卡、网卡、各种连接线、机箱备板、主板、内存、甚至CPU等。处于失效边缘的硬件,具有极强的隐蔽性与迷惑性,不仅让故障定位变得非常困难,更可怕的是还可能会导致隐形数据损坏(Silent Data Corruption)。因此,Ceph的运维变得极具挑战性,且无法完全实现自动化。


在众多的分布式存储中,值得重点提及的是道熵的双重RAID分布式存储技术。该技术将传统磁盘阵列技术与Ceph分布式存储技术相融合,通过节点存储资源池化与虚拟化管理,在IO读写路径中引入实时在线的数据校验与本地数据自修复技术。该技术可帮助用户快速定位各种硬件故障,并自动修复隐形的数据损坏,让复杂的Ceph分布式存储的运维变得相对简单。