解析Ceph: 恢复与数据一致性
转自:https://www.ustack.com/blog/ceph-internal-recovery-and-consistency/
作为一个面向大规模的分布式存储系统,故障处理是作为一个常态异常处理。Ceph 为了细化和保证故障发生和故障恢复的集群高可用性和一致性,在设计上将故障分为两类:
- 临时性故障: 主机升级维护,重启,掉电等等在一定时间内可以重新上线 OSD 的故障
- 永久性故障: 作为强一致存储系统,状态只跟存储在持久设备的数据有关,因此这类故障主要就是盘损坏或者主机损坏并无法及时转移盘到另外主机。换句话说救是一定时间内无法将原来的 OSD 数据重新加入集群。
Ceph 将所有数据域划分成若干个 PG(Placement Group)管理,每个 PG 都存活在一个 OSD 节点上,因此 PG 是管理、恢复数据的主体。而 Monitor 节点不参与用户数据的任何操作,只提供了 PG 选举的协调作用。PG 所属数据的处理和恢复都由 PG 本身进行协调。
临时性故障
首先这里考虑临时性故障的处理,Ceph 引入了 PGLog 的概念,顾名思义,PGLog 由 PG 维护并且记录了该 PG 所有的操作,其非常类似于关系型数据库领域的 undo log,同时需要将 PGLog 与 Journal 概念划分清楚,Journal 是底层单机存储模块用来维护事务一致性的,它是数据库领域的 redo log。undo log 和 redo log 在数据库的作用与 Ceph 的 PGLog 和 Journal 作用是一致的。PGLog 通常只保存 PG 最近几千条的操作记录,但是在 PG 处于 Degraded 状态时,PGLog 会保存更多的日志条目期望能在故障 PG 重新上线后用来恢复数据。下面来简单描述故障发生导致 OSD 下线的流程:
- 某一个 OSD 下线
- 如果 OSD 主动下线它会通知 Monitor 自己下线,请做好相关通知工作。如果是异常下线,那么其他 OSD 和 Monitor 会通过 Heartbeat 来得知 OSD 下线同样让 Monitor 知晓
- Monitor 重新计算该 OSD 拥有的的 Primary PG,并将结果主动通知这些 PG 所在的 OSD
- PG 将自己设为 Degraded 状态后,将会减小自己的副本数,并增加保存的 PGLog 条目数
故障发生后,如果一定时间后重新上线故障 OSD,那么 PG 会进行以下流程:
1. 故障 OSD 上线,通知 Monitor 并注册,该 OSD 在上线前会读取存在持久设备的 PGLog,
2. Monitor 得知该 OSD 的旧有 id,因此会继续使用以前的 PG 分配,之前该 OSD 下线造成的 Degraded PG 会被通知该 OSD 已重新加入
3. 这时候分为两种情况,注意这个情况下 PG 会标志自己为 Peering 状态并暂时停止处理请求:
3.1 第一种情况是故障 OSD 所拥有的 Primary PG
3.1.1 它作为这部分数据"权责"主体,需要发送查询 PG 元数据请求给所有属于该 PG 的 Replicate 角色节点。
3.1.2 该 PG 的 Replicate 角色节点实际上在故障 OSD 下线时期间成为了 Primary 角色并维护了“权威”的 PGLog,该 PG 在得到故障 OSD 的 Primary PG 的查询请求后会发送回应
3.1.3 Primary PG 通过对比 Replicate PG 发送的元数据和 PG 版本信息后发现处于落后状态,因此它会合并得到的 PGLog并建立“权威” PGLog,同时会建立 missing 列表来标记过时数据
3.1.4 Primary PG 在完成“权威” PGLog 的建立后就可以标志自己处于 Active 状态 3.2 第二种情况是故障 OSD 所拥有的 Replicate PG
3.2.1 这时上线后故障 OSD 的 Replicate PG 会得到 Primary PG 的查询请求,发送自己这份“过时”的元数据和 PGLog
3.2.2 Primary PG 对比数据后发现该 PG 落后并且过时,比通过 PGLog 建立了 missing 列表
3.2.3 Primary PG 标记自己处于 Active 状态
4. PG 开始接受 IO 请求,但是 PG 所属的故障节点仍存在过时数据,故障节点的 Primary PG 会发起 Pull 请求从 Replicate 节点获得最新数据,Replicate PG 会得到其他 OSD 节点上的 Primary PG 的 Push 请求来恢复数据
5. 恢复完成后标记自己 Clean
第三步是 PG 唯一不处理请求的阶段,它通常会在 1s 内完成来减少不可用时间。但是这里仍然有其他问题,比如在恢复期间故障 OSD 会维护 missing 列表,如果 IO 正好是处于 missing 列表的数据,那么 PG 会进行恢复数据的“插队”操作,主动将该 IO 涉及的数据从 Replicate PG 拉过来,提前恢复该部分数据。这个情况造成的延迟大概在几十毫米,通常来说是可接受的。
永久性故障
上面的流程的前提故障 OSD 在 PGLog 保存的最大条目数以内加入集群都会利用 PGLog 恢复,那么如果在 N 天之后或者发生了永久故障需要新盘加入集群时,PGLog 就无法起到恢复数据的作用,这时候就需要 backfill(全量拷贝) 流程介入。backfill 会将所有数据复制到新上线的 PG,这里的流程跟上述过程基本一致,唯一的差异就是在第三步 Primary PG 发现 PGLog 已经不足以恢复数据时,这时候同样分为两种情况:
- 故障 OSD 拥有 Primary PG,该 PG 在对比 PGLog 后发现需要全量拷贝数据,那么毫无疑问 Primary PG 在复制期间已经无法处理请求,它会发送一个特殊请求给 Monitor 告知自己需要全量复制,需要将 Replicate PG 临时性提升为 Primary,等到自己完成了复制过程才会重新接管 Primary 角色
- 故障 OSD 拥有 Replicate PG,该 PG 的 Primary 角色会发起 backfill 流程向该 PG 复制数据,由于故障 OSD 是 Replicate 角色,因此不影响正常 IO 的处理
除此之外,恢复数据还需要涉及到恢复数据的带宽控制、优先级等细节问题,这里就不一一赘述了。
小结
总的来说,Ceph 的恢复模块设计原则是在保证数据强一致性的前提下,尽量细化恢复过程来提高数据可用性(请求能得到及时处理),这个细化过程势必带来了极大的复杂性,因此恢复模块实际上也是 Ceph 最复杂的设计之一,值得存储系统领域的开发者借鉴。
解析Ceph: 恢复与数据一致性的更多相关文章
- 解析Ceph: RBDCache 背后的世界
转自:https://www.ustack.com/blog/ceph-internal-rbdcache/ RBDCache 是Ceph的块存储接口实现库 Librbd 的用来在客户端侧缓存数据的目 ...
- 解析CEPH: 存储引擎实现之一 filestore
Ceph作为一个高可用和强一致性的软件定义存储实现,去使用它非常重要的就是了解其内部的IO路径和存储实现.这篇文章主要介绍在IO路径中最底层的ObjectStore的实现之一FileStore. Ob ...
- 解析 Ceph: FileJournal 的作用
很多的用户在提到 Ceph 性能的时候都会提到“写放大”这点,实际上就是 FileJournal 在起作用.只要使用默认的 FileStore,所有数据包括 metadata 都会在 FileJo ...
- 解析Ceph: Snapshot
经常有开发者在邮件列表中会问到Ceph Snapshot的实现方式,受限于目前有限的实现文档和复杂的代码结构和代码量,弄清楚Ceph Snapshot并不是一件容易的事.正好最近在重构Ceph存储引擎 ...
- 解析Ceph: 数据的端到端正确性和 Scrub 机制
转自:https://www.ustack.com/blog/ceph-internal-scrub/ Ceph 的主要一大特点是强一致性,这里主要指端到端的一致性.众所周知,传统存储路径上从应用层到 ...
- Ceph源码解析:读写流程
转载注明出处,整理也是需要功夫的,http://www.cnblogs.com/chenxianpao/p/5572859.html 一.OSD模块简介 1.1 消息封装:在OSD上发送和接收信息. ...
- ceph 初始化函数解析
global_pre_init 预初始化函数,解析ceph.conf配置文件, 初始化定义global_context 和 config的全局变量. 全局预初始化函数 CINIT_FLAG_UNPRI ...
- 理解 QEMU/KVM 和 Ceph(1):QEMU-KVM 和 Ceph RBD 的 缓存机制总结
本系列文章会总结 QEMU/KVM 和 Ceph 之间的整合: (1)QEMU-KVM 和 Ceph RBD 的 缓存机制总结 (2)QEMU 的 RBD 块驱动(block driver) (3)存 ...
- 深度长文:深入理解Ceph存储架构
点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 本文是一篇Ceph存储架构技术文章,内容深入到每个存储特 ...
随机推荐
- sql语句备份/导入 mysql数据库或表命令
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/qq1355541448/article/details/30049851
- gearman background后台job状态获取
GearmanClient background job有一个方法叫: public array GearmanClient::jobStatus ( string $job_handle ) Get ...
- $ 用python处理Excel文档(1)——用xlrd模块读取xls/xlsx文档
本文主要介绍xlrd模块读取Excel文档的基本用法,并以一个GDP数据的文档为例来进行操作. 1. 准备工作: 1. 安装xlrd:pip install xlrd 2. 准备数据集:从网上找到的1 ...
- FAT和EXFAT文件系统
文件系统 文件系统是操作系统用于明确磁盘或分区上的文件的方法和数据结构:即在磁盘上组织文件的方法.在移动存储设备上比较常用的有FAT文件系统和ExFAT文件系统. FAT分区依据FAT表中每个簇链的所 ...
- Laravel 调试利器 —— Laravel Debugbar 扩展包安装及使用教程
1.简介 Laravel Debugbar 在 Laravel 5 中集成了 PHP Debug Bar ,用于显示调试及错误信息以方便开发.该扩展包包含了一个 ServiceProvider 用于注 ...
- Python编程-网络编程进阶(IO复用、Socketserver)
一.认证客户端的链接合法性 如果你想在分布式系统中实现一个简单的客户端链接认证功能,又不像SSL那么复杂,那么利用hmac+加盐的方式来实现. 服务端 from socket import * imp ...
- python:字典的方法
1.查找字典中的key对应的值和key是否存在(get,has_key)dict.get(key, default = None) :返回字典中key对应的值,若key不存在字典中,则返回defaul ...
- 默认连接电脑的模式为MTP【转】
本文转载自:https://blog.csdn.net/tangzhihai0421/article/details/53487208 Android L后默认的usb连接模式为“仅充电”,而且不会随 ...
- maven项目在打war包时出现非法字符: '\ufeff' 解决方案
问题描述: 开发工具MyEclipse 的总体开发环境,编码格式总体设置为UTF-8,在将web项目打包的时候出现:非法字符:'\ufeff" 错误. 解决方案: 利用notePad++打开 ...
- 最短路径Dijkstra模板
算法思想:把所有的边分成两个集合A,B.集合A表示已经求出最短路径的点,不断扩展集合A,减少集合B.每一扩展就从结合B中找出到源点距离最短的点,加入到A. dis[i]数组代表从出发点到j的距离: m ...