解析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存储架构技术文章,内容深入到每个存储特 ...
随机推荐
- python函数回顾:dir()
描述 dir() 函数不带参数时,返回当前范围内的变量.方法和定义的类型列表: 带参数时,返回参数的属性.方法列表.如果参数包含方法__dir__(),该方法将被调用. 如果参数不包含__dir__( ...
- Android系统移植与调试之------->如何修改Android系统默认显示【开发者选项】并默认打开【USB调试】和【未知来源】开关
今天有个用户对[设置]有个特殊的要求,即: 1.开机的时候默认显示[开发者选项]并打开[USB调试]开关 ([Developer options]-->[USB debugging]) 2 ...
- [置顶] 我的Android进阶之旅------>Android解决异常: startRecording() called on an uninitialized AudioRecord.
今天使用AudioRecord进行录音操作时候,报了下面的异常. E/AndroidRuntime(22775): java.lang.IllegalStateException: startReco ...
- hbase中清空整张表的数据
hbase(main):005:0> truncate 'fr:test' Truncating 'FaceBase' table (it may take a while): - Disabl ...
- virt-viewer的简单使用
virt-viewer 简介: virt-viewer是一个用于显示虚拟机的图形控制台的最小工具. 控制台使用VNC或SPICE访问协议. 可以基于其名称,ID或UUID来引用guest虚拟机.如果 ...
- CSRF(Cross Site Request Forgery, 跨站请求伪造)
一.CSRF 背景与介绍 CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一.其他安全隐患, ...
- Java - 在控制台中执行一个可执行jar
1.Maven打包一个可执行jar: <build> <plugins> <plugin> <groupId>org.apache.maven.plug ...
- Vimium~让您的Chrome起飞
工欲善其事,必先利其器!撸起Vimium,我的Chrome就这么起飞了. 学起(了解几个快捷键即可)And撸起Vimium,想黑客一般在Chrome上飞起.Vimium常用快捷键(注:区分大小写)j, ...
- yii框架模型操作
命令行自动生成model模型类 php yii gii/model --ns=app\\modules\\v1\\models --tableName=SCM_tbInvBalance_new --m ...
- VSCode隐藏node_modules目录
使用VSCode,打开一个工程时,发现node_modules目录包含到工程中了,问题: settings.json配置如下,可以自己定制忽略的文件夹: search.exclude 用来忽略搜索的文 ...