【分析】Ceph数据一致性检查
来源:互联网 发布:腾讯股票数据接口 编辑:程序博客网 时间:2024/04/25 04:28
Scrub的过程大致如下:通过比较对象各个OSD上副本的元数据和数据,来完成源数据和数据的校验。
1.1.1 数据结构
Scrub操作相关的主要数据结构有两个,一个是Scrub控制结构——相当于一次Scrub曹组的上下文,控制一次PG的操作过程。另外是ScrubMap保存需要比较对象的各个副本的元数据和数据的摘要信息。
1.1.1.1 Scrubber
Scrubber结构体用于控制一个PG的Scrub过程
// -- scrub --
struct Scrubber {
// metadata
set<pg_shard_t>reserved_peers; // 资源预约的shard
bool reserved,reserve_failed; //是否预约资源,预约是否失败
epoch_tepoch_start;//开始Scrub操作的epoch
// commonto both scrubs
bool active;//Scrub是否开始
//当PG有snap_trim操作时,如果检查Scrubber处于active状态,说明正在进行Scrub操作,那么snap_trim操作暂停,设置queue_snap_trim的值为true。当PG完成Scrub任务后,如果queue_snap_trim的值为true,就把PG添加到相应的工作队列里,继续完成snap_trim操作
bool queue_snap_trim;
int waiting_on;//等待的副本计数
set<pg_shard_t>waiting_on_whom;//得带的副本
int shallow_errors;//轻度扫描的错误数
int deep_errors;//深度扫描的错误数
int fixed;//已经修复的对象数
ScrubMapprimary_scrubmap;//主副本的ScrubMap
map<pg_shard_t,ScrubMap> received_maps;//接收到的从副本的ScrubMap
OpRequestRefactive_rep_scrub;
utime_tscrub_reg_stamp; // stamp we registered for
…
// thisflag indicates whether we would like to do auto-repair of the PG or not
bool auto_repair;//是否自动恢复
// Mapsfrom objects with errors to missing/inconsistent peers
map<hobject_t, set<pg_shard_t>>missing; //扫描出的缺失对象
map<hobject_t, set<pg_shard_t>>inconsistent;//扫描出的不一致对象
// Map fromobject with errors to good peers
//如果所有副本对象中有不一致的对象,记录正确对象所在的osd
map<hobject_t, list<pair<ScrubMap::object,pg_shard_t> >> authoritative;
// Cleanedmap pending snap metadata scrub
ScrubMapcleaned_meta_map;
// digestupdates which we are waiting on
int num_digest_updates_pending;
// chunkyscrub
hobject_tstart, end;
eversion_tsubset_last_update;
// chunkyscrub state
enum State {
INACTIVE,
NEW_CHUNK,
WAIT_PUSHES,
WAIT_LAST_UPDATE,
BUILD_MAP,
WAIT_REPLICAS,
COMPARE_MAPS,
WAIT_DIGEST_UPDATES,
FINISH,
} state;
std::unique_ptr<Scrub::Store>store;
// deepscrub
bool deep;//是否为深度扫描
uint32_tseed;//计算CRC32校验码的种子
list<Context*>callbacks;
…
} scrubber;
1.1.1.2 ScrubMap
ScrubMap结构体保存准备校验的对象以及相应的校验信息
/*
* summarizepg contents for purposes of a scrub
*/
struct ScrubMap {
struct object {
map<string,bufferptr>attrs;//对象的属性
uint64_t size;//该对象的大小
__u32omap_digest; ///< omapcrc32c
__u32digest; ///< datacrc32c
bool negative:1;
bool digest_present:1;//是否计算了数据的校验码
bool omap_digest_present:1;//是否有omap的校验码标志
bool read_error:1;//读对象数据的错误标志
bool stat_error:1;//调用stat获取对象元数据时的出错标志
bool ec_hash_mismatch:1;//
bool ec_size_mismatch:1;
…
};
内部类object是用来保存对象需要的校验信息。
1.1.2 Scrub的控制流程的状态机
Scrub任务的由OSD的工作队列OpWq来完成,调用对应的处理函数pg->scrub(handle)来执行。最终调用PG::chunky_scrub函数控制scrub操作的状态转换和核心处理。
1. Scrubber的初始状态为INACTIVE。
(1) 设置scrubber的参数epoch_start
(2) 设置scrubber.active= true说明已经激活scrub
(3) 设置状态scrubber.status为NEW_CHUNK
(4) 设置scrubber.seed的类型,初始为-1
2. Scrubber的状态为NEW_CHUNK的处理。
(1) 通过函数objects_list_partial函数计算对象的边界,方便划界。
(2) 调用函数_range_available_for_scrub检查列表中的对象,是否存在被阻塞的对象,如果存在,则退出本次Scrub
(3) 根据pg_log计算start和end区间对象最大的更新版本号,更新至scrubber.subset_last_update
(4) 调用函数_request_scrub_map()向所有的副本发送消息,获取相应的ScrubMap的校验信息。
(5) 设置状态为WAIT_PUSHES
3. Scrubber的状态为WAIT_PUSHES的处理。
(1) 如果active_pushes的值为0,设置状态为WAIT_LAST_UPDATE进入下一个状态处理。
(2) 如果active_pushes的值不为0,说明该PG正在进行Recovery操作,设置done的值为true。在进入chunk_scrub时,PG应该处于CLEAN状态,不可能有Recovery操作(这里的Recovery应该是上次进行的chunky_scrub的修复操作)
4. Scrubber的状态为BUILD_MAP的处理。
(1) 调用函数build_scrub_map_chunk构造主OSD上对象的ScrubMap结构
(2) 如果构造成功,计数scrubber.waiting_on的值减1,并从队列中删除scrubber.waiting_on_whom,则相应的状态设置为WAIT_REPLICAS
4. Scrubber的状态为WAIT_REPLICAS的处理
(1) 若scrubber.waiting_on不为0,说明replica请求没有应答,设置done=true并退出等待;
(2) 否则,设置状态为COMPARE_MAPS
5. Scrubber的状态为COMPARE_MAPS的处理
(1) 调用函数scrub_compare_maps比较各副本的校验信息
(2) 将参数scrubber.start设置为srubber.end
(3) 调用参数requeue_ops,把由于Scrub而阻塞的读写操作重新加入操作队列里执行
(4) 设置状态为WAIT_DIGEST_UPDATES
6. Scrubber的状态为COMPARE_MAPS的处理
(1) 如果有scrubber.num_digest_updates_pending等待,等待更新数据的digest或者omap的digest
(2) 如果scrubber.end小于hobject_t::get_max(),本PG还存在没有完成Scrub操作的对象,设置状态scrubber.stat为NEW_CHUNK,继续把PG加入到osd->scrub_wq中
(3) 否则,设置状态为FINISH
6. Scrubber的状态为FINISH的处理
(1) 调用函数scrub_finish来设置相关的统计信息,并触发修复不一致的对象
(2) 设置状态为INACTIVE
调用函数build_scrub_map_chunk构造主OSD上对象的ScrubMap结构
(2) 如果构造成功,计数scrubber.waiting_on的值减1,并从队列中删除scrubber.waiting_on_whom,则相应的状态设置为WAIT_REPLICAS
1.1.3 构建ScrubMap
构建ScrubMap是由多个函数组成:
1. 调用函数build_scrub_map_chunk构建从start到end之间所有对象的校验信息并保存ScrubMap结构体中;
2. 调用函数_scan_snap扫描head对象保存的snap信息和snapset结构体中保存的该对象的snap信息是否一致,以前者保存的snap信息为准,修复snapset中保存的snap对象;
3. 调用函数be_scan_list构建ScrubMap结构体中对象的校验信息
4. 如果需要deep scrub,则调用be_deep_scrub进行深度扫描,获取omap和data的digest信息。
1.1.4 从副本处理
当从副本接收到主副本发送来的MOSDRepScrub类型消息时,用于获取对象的校验信息时,就调用函数replica_scrub来完成。
1.1.5 副本比较
当对象的主副本和从副本都完成了校验信息的构建,并保存在相应的结构体ScrubMap中,接下来,就是对比各个副本的校验信息来完成数据一致性检查。
首先通过对象自身的信息来选出一个权威的对象,然后用权威对象和其他对象来比较和检验。
1.1.6 结束Scrub
通过函数scrub_finish函数来结束scrub过程,处理流程如下:
1. 设置相关PG的状态和统计信息
2.修复scrubber中标记的missing和inconsistent对象;
3. 触发DoRecovery事件发送给PG的状态机。发起实际对象的修复操作。
2 参考文献
1. 百度百科——CAP原则
2. 摘自机械工业出版社《Ceph源码分析》
- 【分析】Ceph数据一致性检查
- 【分析】Ceph数据一致性检查
- 【分析】Ceph数据一致性检查
- 【分析】Ceph数据一致性检查
- 【分析】Ceph数据一致性检查
- ceph数据一致性机制浅析
- Ceph恢复与数据一致性
- 解析Ceph: 恢复与数据一致性
- MySQL数据一致性检查工具
- Mysql半同步复制、数据一致性检查
- MySQL数据一致性检查的几个工具
- MySQL背后的数据一致性分析
- 数据一致性
- 数据一致性
- 数据一致性
- 数据一致性
- 数据一致性
- 数据一致性
- solr对nested json(多层复杂嵌套json)的文档式处理方式。childDoc&parentDoc _childDocuments_
- 调用线程无法访问此对象,因为另一个线程拥有该对象
- 一些函数、指针、const、结构体、extern零散整理
- Android自定义view-高仿小米视频加载动画效果
- Glide .centerCrop() 和transform圆角图片不能同时存在解决方法
- 【分析】Ceph数据一致性检查
- 前端必备之切图(一、使用PhotoShop测量和取色)
- 默认参数必须指向不变对象!
- 数组方法
- Android学习之Notifications(超详细)
- HDOJ ACMstep 2.1.3 相遇周期
- git config命令和Git配置文件
- 深度学习最全优化方法总结比较(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)
- Kotlin for Android(四)Kotlin控制流