分布式存储 Ceph 介绍及原理架构分享(下)

阅读数:445 2019 年 9 月 18 日 12:26

分布式存储 Ceph 介绍及原理架构分享(下)

本文由于篇幅过长,分文上下两篇,此篇为下篇。

本文主要从架构简介使用场景,以及内部 IO 流程、心跳机制、通信框架、CRUSH 算法、QOS 等多个方面逐渐介绍分布式存储系统 Ceph 的特性。希望对你有所帮助。

3. Ceph 心跳机制

3.1 心跳介绍

心跳是用于节点间检测对方是否故障的,以便及时发现故障节点进入相应的故障处理流程。

问题:

a. 故障检测时间和心跳报文带来的负载之间做权衡。
b. 心跳频率太高则过多的心跳报文会影响系统性能。
c. 心跳频率过低则会延长发现故障节点的时间,从而影响系统的可用性。

故障检测策略应该能够做到:

及时:节点发生异常如宕机或网络中断时,集群可以在可接受的时间范围内感知。

适当的压力:包括对节点的压力,和对网络的压力。

容忍网络抖动:网络偶尔延迟。

扩散机制:节点存活状态改变导致的元信息变化需要通过某种机制扩散到整个集群。

3.2 Ceph 心跳检测

分布式存储 Ceph 介绍及原理架构分享(下)

OSD 节点会监听 public、cluster、front 和 back 四个端口

  • public 端口:监听来自 Monitor 和 Client 的连接。

  • cluster 端口:监听来自 OSD Peer 的连接。

  • front 端口:供客户端连接集群使用的网卡, 这里临时给集群内部之间进行心跳。

  • back 端口:供客集群内部使用的网卡。集群内部之间进行心跳。

  • hbclient:发送 ping 心跳的 messenger。

▍3.3 Ceph OSD 之间相互心跳检测

分布式存储 Ceph 介绍及原理架构分享(下)

步骤:

a. 同一个 PG 内 OSD 互相心跳,他们互相发送 PING/PONG 信息。
b. 每隔 6s 检测一次 (实际会在这个基础上加一个随机时间来避免峰值)。
c. 20s 没有检测到心跳回复,加入 failure 队列。

3.4 Ceph OSD 与 Mon 心跳检测

分布式存储 Ceph 介绍及原理架构分享(下)

OSD 报告给 Monitor:

  • a. OSD 有事件发生时(比如故障、PG 变更)。
  • b. 自身启动 5 秒内。
  • c. OSD 周期性的上报给 Monito
  • d. OSD 检查 failure_queue 中的伙伴 OSD 失败信息。
  • e. 向 Monitor 发送失效报告,并将失败信息加入 failure_pending 队列,然后将其从 failure_queue 移除。
  • f. 收到来自 failure_queue 或者 failure_pending 中的 OSD 的心跳时,将其从两个队列中移除,并告知 Monitor 取消之前的失效报告。
  • g. 当发生与 Monitor 网络重连时,会将 failure_pending 中的错误报告加回到 failure_queue 中,并再次发送给 Monitor。
  • h. Monitor 统计下线 OSD
  • i. Monitor 收集来自 OSD 的伙伴失效报告。
  • j. 当错误报告指向的 OSD 失效超过一定阈值,且有足够多的 OSD 报告其失效时,将该 OSD 下线。

3.5 Ceph 心跳检测总结

Ceph 通过伙伴 OSD 汇报失效节点和 Monitor 统计来自 OSD 的心跳两种方式判定 OSD 节点失效。

及时:

伙伴 OSD 可以在秒级发现节点失效并汇报 Monitor,并在几分钟内由 Monitor 将失效 OSD 下线。

适当的压力:

由于有伙伴 OSD 汇报机制,Monitor 与 OSD 之间的心跳统计更像是一种保险措施,因此 OSD 向 Monitor 发送心跳的间隔可以长达 600 秒,Monitor 的检测阈值也可以长达 900 秒。Ceph 实际上是将故障检测过程中中心节点的压力分散到所有的 OSD 上,以此提高中心节点 Monitor 的可靠性,进而提高整个集群的可扩展性。

容忍网络抖动:

Monitor 收到 OSD 对其伙伴 OSD 的汇报后,并没有马上将目标 OSD 下线,而是周期性的等待几个条件:

  1. 目标 OSD 的失效时间大于通过固定量 osd_heartbeat_grace 和历史网络条件动态确定的阈值。
  2. 来自不同主机的汇报达到 mon_osd_min_down_reporters。
  3. 满足前两个条件前失效汇报没有被源 OSD 取消。

扩散:

作为中心节点的 Monitor 并没有在更新 OSDMap 后尝试广播通知所有的 OSD 和 Client,而是惰性的等待 OSD 和 Client 来获取。以此来减少 Monitor 压力并简化交互逻辑。

4. Ceph 通信框架

4.1 Ceph 通信框架种类介绍

网络通信框架三种不同的实现方式:

Simple 线程模式

特点:每一个网络链接,都会创建两个线程,一个用于接收,一个用于发送。

缺点:大量的链接会产生大量的线程,会消耗 CPU 资源,影响性能。

Async 事件的 I/O 多路复用模式

特点:这种是目前网络通信中广泛采用的方式。k 版默认已经使用 Asnyc 了。

XIO 方式使用了开源的网络通信库 accelio 来实现

特点:这种方式需要依赖第三方的库 accelio 稳定性,目前处于试验阶段。

4.2 Ceph 通信框架设计模式

设计模式 (Subscribe/Publish):

订阅发布模式又名观察者模式,它意图是“定义对象间的一种一对多的依赖关系,

当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新”。

4.3 Ceph 通信框架流程图

分布式存储 Ceph 介绍及原理架构分享(下)

步骤:

  • a. Accepter 监听 peer 的请求, 调用 SimpleMessenger::add_accept_pipe() 创建新的 Pipe 到 SimpleMessenger::pipes 来处理该请求。
  • b. Pipe 用于消息的读取和发送。该类主要有两个组件,Pipe::Reader,Pipe::Writer 用来处理消息读取和发送。
  • c. Messenger 作为消息的发布者, 各个 Dispatcher 子类作为消息的订阅者, Messenger 收到消息之后,通过 Pipe 读取消息,然后转给 Dispatcher 处理。
  • d. Dispatcher 是订阅者的基类,具体的订阅后端继承该类, 初始化的时候通过 Messenger::add_dispatcher_tail/head 注册到 Messenger::dispatchers. 收到消息。
  • e. DispatchQueue 该类用来缓存收到的消息, 然后唤醒 DispatchQueue::dispatch_thread 线程找到后端的 Dispatch 处理消息。

分布式存储 Ceph 介绍及原理架构分享(下)

4.4 Ceph 通信框架类图

分布式存储 Ceph 介绍及原理架构分享(下)

4.5 Ceph 通信数据格式

通信协议格式需要双方约定数据格式。

消息的内容主要分为三部分:

· header // 消息头,类型消息的信封

· user data // 需要发送的实际数据

复制代码
o payload // 操作保存元数据
o middle // 预留字段
o data // 读写数据
o footer // 消息的结束标记
复制代码
class Message : public RefCountedObject {
protected:
ceph_msg_header header; // 消息头
ceph_msg_footer footer; // 消息尾
bufferlist payload; // "front" unaligned blob
bufferlist middle; // "middle" unaligned blob
bufferlist data; // data payload (page-alignment will be preserved where possible)
/* recv_stamp is set when the Messenger starts reading the
* Message off the wire */
utime_t recv_stamp; // 开始接收数据的时间戳
/* dispatch_stamp is set when the Messenger starts calling dispatch() on
* its endpoints */
utime_t dispatch_stamp; //dispatch 的时间戳
/* throttle_stamp is the point at which we got throttle */
utime_t throttle_stamp; // 获取 throttle 的 slot 的时间戳
/* time at which message was fully read */
utime_t recv_complete_stamp; // 接收完成的时间戳
ConnectionRef connection; // 网络连接
uint32_t magic = 0; // 消息的魔术字
bi::list_member_hook<> dispatch_q; //boost::intrusive 成员字段
};
struct ceph_msg_header {
__le64 seq; // 当前 session 内 消息的唯一 序号
__le64 tid; // 消息的全局唯一的 id
__le16 type; // 消息类型
__le16 priority; // 优先级
__le16 version; // 版本号
__le32 front_len; // payload 的长度
__le32 middle_len;// middle 的长度
__le32 data_len; // data 的 长度
__le16 data_off; // 对象的数据偏移量
struct ceph_entity_name src; // 消息源
/* oldest code we think can decode this. unknown if zero. */
__le16 compat_version;
__le16 reserved;
__le32 crc; /* header crc32c */
} __attribute__ ((packed));
struct ceph_msg_footer {
__le32 front_crc, middle_crc, data_crc; //crc 校验码
__le64 sig; // 消息的 64 位 signature
__u8 flags; // 结束标志
} __attribute__ ((packed));

5. Ceph CRUSH 算法

5.1 数据分布算法挑战

数据分布和负载均衡:

  1. 数据分布均衡,使数据能均匀的分布到各个节点上。
  2. 负载均衡,使数据访问读写操作的负载在各个节点和磁盘的负载均衡。

灵活应对集群伸缩:

  1. 系统可以方便的增加或者删除节点设备,并且对节点失效进行处理。
  2. 增加或者删除节点设备后,能自动实现数据的均衡,并且尽可能少的迁移数据。

支持大规模集群:

  1. 要求数据分布算法维护的元数据相对较小,并且计算量不能太大。随着集群规模的增 加,数据分布算法开销相对比较小。

5.2 Ceph CRUSH 算法说明

CRUSH 算法的全称为:Controlled Scalable Decentralized Placement of Replicated Data,可控的、可扩展的、分布式的副本数据放置算法。

PG 到 OSD 的映射的过程算法叫做 CRUSH 算法。(一个 Object 需要保存三个副本,也就是需要保存在三个 osd 上)。

CRUSH 算法是一个伪随机的过程,他可以从所有的 OSD 中,随机性选择一个 OSD 集合,但是同一个 PG 每次随机选择的结果是不变的,也就是映射的 OSD 集合是固定的。

5.3 Ceph CRUSH 算法原理

CRUSH 算法因子:

层次化的 Cluster Map

反映了存储系统层级的物理拓扑结构。定义了 OSD 集群具有层级关系的静态拓扑结构。OSD 层级使得 CRUSH 算法在选择 OSD 时实现了机架感知能力,也就是通过规则定义, 使得副本可以分布在不同的机 架、不同的机房中、提供数据的安全性 。

Placement Rules

决定了一个 PG 的对象副本如何选择的规则,通过这些可以自己设定规则,用户可以自定义设置副本在集群中的分布。

5.3.1 层级化的 Cluster Map

分布式存储 Ceph 介绍及原理架构分享(下)

CRUSH Map 是一个树形结构,OSDMap 更多记录的是 OSDMap 的属性 (epoch/fsid/pool 信息以及 osd 的 ip 等等)。

叶子节点是 device(也就是 osd),其他的节点称为 bucket 节点,这些 bucket 都是虚构的节点,可以根据物理结构进行抽象,当然树形结构只有一个最终的根节点称之为 root 节点,中间虚拟的 bucket 节点可以是数据中心抽象、机房抽象、机架抽象、主机抽象等。

5.3.2 数据分布策略 Placement Rules

数据分布策略 Placement Rules 主要有特点:

  1. 从 CRUSH Map 中的哪个节点开始查找
  2. 使用那个节点作为故障隔离域
  3. 定位副本的搜索模式(广度优先 or 深度优先)
复制代码
rule replicated_ruleset #规则集的命名,创建 pool 时可以指定 rule 集
{
ruleset 0 #rules 集的编号,顺序编即可
type replicated #定义 pool 类型为 replicated(还有 erasure 模式)
min_size 1 #pool 中最小指定的副本数量不能小 1
max_size 10 #pool 中最大指定的副本数量不能大于 10
step take default #查找 bucket 入口点,一般是 root 类型的 bucket
step chooseleaf firstn 0 type host #选择一个 host, 并递归选择叶子节点 osd
step emit #结束
}

5.3.3 Bucket 随机算法类型

分布式存储 Ceph 介绍及原理架构分享(下)

一般的 buckets:适合所有子节点权重相同,而且很少添加删除 item。

list buckets:适用于集群扩展类型。增加 item,产生最优的数据移动,查找 item,时间复杂度 O(n)。

tree buckets:查找负责度是 O (log n), 添加删除叶子节点时,其他节点 node_id 不变。

straw buckets:允许所有项通过类似抽签的方式来与其他项公平“竞争”。定位副本时,bucket 中的每一项都对应一个随机长度的 straw,且拥有最长长度的 straw 会获得胜利(被选中),添加或者重新计算,子树之间的数据移动提供最优的解决方案。

5.4 Ceph CRUSH 算法案例

说明:

集群中有部分 sas 和 ssd 磁盘,现在有个业务线性能及可用性优先级高于其他业务线,能否让这个高优业务线的数据都存放在 ssd 磁盘上。

普通用户:

分布式存储 Ceph 介绍及原理架构分享(下)

高优用户:

分布式存储 Ceph 介绍及原理架构分享(下)

配置规则:

分布式存储 Ceph 介绍及原理架构分享(下)

6. 定制化 Ceph RBD QOS

6.1 QOS 介绍

QoS (Quality of Service,服务质量)起源于网络技术,它用来解决网络延迟和阻塞等问题,能够为指定的网络通信提供更好的服务能力。

问题:

我们总的 Ceph 集群的 IO 能力是有限的,比如带宽,IOPS。如何避免用户争抢资源,如何保证集群所有用户资源的高可用性,以及如何保证高优用户资源的可用性。所以我们需要把有限的 IO 能力合理分配。

6.2 Ceph IO 操作类型

ClientOp:来自客户端的读写 I/O 请求。

SubOp:osd 之间的 I/O 请求。主要包括由客户端 I/O 产生的副本间数据读写请求,以及由数据同步、数据扫描、负载均衡等引起的 I/O 请求。

SnapTrim:快照数据删除。从客户端发送快照删除命令后,删除相关元数据便直接返回,之后由后台线程删除真实的快照数据。通过控制 snaptrim 的速率间接控制删除速率。

Scrub:用于发现对象的静默数据错误,扫描元数据的 Scrub 和对象整体扫描的 deep Scrub。

Recovery:数据恢复和迁移。集群扩 / 缩容、osd 失效 / 从新加入等过程。

6.3 Ceph 官方 QOS 原理

分布式存储 Ceph 介绍及原理架构分享(下)

mClock 是一种基于时间标签的 I/O 调度算法,最先被 Vmware 提出来的用于集中式管理的存储系统。(目前官方 QOS 模块属于半成品)。

基本思想:

  • reservation 预留,表示客户端获得的最低 I/O 资源。
  • weight 权重,表示客户端所占共享 I/O 资源的比重。
  • limit 上限,表示客户端可获得的最高 I/O 资源。

6.4 定制化 QOS 原理

6.4.1 令牌桶算法介绍

分布式存储 Ceph 介绍及原理架构分享(下)

基于令牌桶算法 (TokenBucket) 实现了一套简单有效的 qos 功能,满足了云平台用户的核心需求。

基本思想:

  • 按特定的速率向令牌桶投放令牌。
  • 根据预设的匹配规则先对报文进行分类,不符合匹配规则的报文不需要经过令牌桶的处理,直接发送。
  • 符合匹配规则的报文,则需要令牌桶进行处理。当桶中有足够的令牌则报文可以被继续发送下去,同时令牌桶中的令牌量按报文的长度做相应的减少。
  • 当令牌桶中的令牌不足时,报文将不能被发送,只有等到桶中生成了新的令牌,报文才可以发送。这就可以限制报文的流量只能是小于等于令牌生成的速度,达到限制流量的目的。

6.4.2 RBD 令牌桶算法流程

分布式存储 Ceph 介绍及原理架构分享(下)

步骤:

  • 用户发起请求异步 IO 到达 Image 中。
  • 请求到达 ImageRequestWQ 队列中。
  • 在 ImageRequestWQ 出队列的时候加入令牌桶算法 TokenBucket。
  • 通过令牌桶算法进行限速,然后发送给 ImageRequest 进行处理。

6.4.3 RBD 令牌桶算法框架图

现有框架图:

分布式存储 Ceph 介绍及原理架构分享(下)

令牌图算法框架图:

分布式存储 Ceph 介绍及原理架构分享(下)

本文转载自公众号滴滴技术(ID:didi_tech)。

原文链接:

https://mp.weixin.qq.com/s/6CyQsY06Ny7Fi-jy19fjEA

评论

发布