当前位置: 首页 > news >正文

ceph中PGLog处理流程

正文

struct pg_log_entry_t {
    ObjectModDesc mod_desc;                 //用于保存本地回滚的一些信息,用于EC模式下的回滚操作
bufferlist snaps;                       //克隆操作,用于记录当前对象的snap列表hobject_t  soid;                        //操作的对象osd_reqid_t reqid;                      //请求唯一标识(caller + tid)vector<pair<osd_reqid_t, version_t> > extra_reqids;    eversion_t version;                     //本次操作的版本
    eversion_t prior_version;                //前一个操作的版本
    eversion_t reverting_to;                 //本次操作回退的版本(仅用于回滚操作)
version_t user_version;                 //用户的版本号utime_t     mtime;                      //用户的本地时间    __s32      op;                          //操作的类型
    bool invalid_hash;                      // only when decoding sobject_t based entriesbool invalid_pool;                      // only when decoding pool-less hobject based entries...
};
/*** pg_info_t - summary of PG statistics.** some notes: *  - last_complete implies we have all objects that existed as of that*    stamp, OR a newer object, OR have already applied a later delete.*  - if last_complete >= log.bottom, then we know pg contents thru log.head.*    otherwise, we have no idea what the pg is supposed to contain.*/
struct pg_info_t {spg_t pgid;                    //对应的PG ID//PG内最近一次更新的对象的版本,还没有在所有OSD上完成更新。在last_update和last_complete之间的操作表示//该操作已在部分OSD上完成,但是还没有全部完成。eversion_t last_update;        eversion_t last_complete;      //该指针之前的版本都已经在所有的OSD上完成更新(只表示内存更新完成)epoch_t last_epoch_started;    //本PG在启动时候的epoch值version_t last_user_version;   //最后更新的user object的版本号eversion_t log_tail;           //用于记录日志的尾部版本//上一次backfill操作的对象指针。如果该OSD的Backfill操作没有完成,那么[last_bakfill, last_complete)之间的对象可能//处于missing状态hobject_t last_backfill;      bool last_backfill_bitwise;            //true if last_backfill reflects a bitwise (vs nibblewise) sortinterval_set<snapid_t> purged_snaps;   //PG要删除的snap集合pg_stat_t stats;                       //PG的统计信息pg_history_t history;                  //用于保存最近一次PG peering获取到的epoch等相关信息pg_hit_set_history_t hit_set;          //这是Cache Tier用的hit_set
};

下面简单画出三者之间的关系示意图:

其中:

  • last_complete: 在该指针之前的版本都已经在所有的OSD上完成更新(只表示内存更新完成);

  • last_update: PG内最近一次更新的对象的版本,还没有在所有OSD上完成更新。在last_update与last_complete之间的操作表示该操作已在部分OSD上完成,但是还没有全部完成。

  • log_tail: 指向pg log最老的那条记录;

  • head: 最新的pg log记录

  • tail: 指向最老的pg log记录的前一个;

  • log: 存放实际的pglog记录的list

从上面结构可以得知,PGLog里只有对象更新操作相关的内容,没有具体的数据以及偏移大小等,所以后续以PGLog来进行恢复时都是按照整个对象来进行恢复的(默认对象大小是4MB)。

另外,这里再介绍两个概念:

  • epoch是一个单调递增序列,其序列由monitor负责维护,当集群中的配置及OSD状态(up、down、in、out)发生变更时,其数值加1。这一机制等同于时间轴,每次序列变化是时间轴上的点。这里说的epoch是针对OSD的,具体到PG时,即对于每个PG的版本eversion中的epoch的变化并不是跟随集群epoch变化的,而是当前PG所在OSD的状态变化,当前PG的epoch才会发生变化。

如下图所示:

ceph-chapter6-7

  • 根据epoch增长的概念,即引入第二个重要概念interval

因为pg的epoch在其变化的时间轴上并非是完全连续的,所以在每两个变化的pg epoch所经历的时间段我们称之为intervals。

3.1.3 Trim Log

void PrimaryLogPG::execute_ctx(OpContext *ctx)
{......// trim log?if (hard_limit_pglog())calc_trim_to_aggressive();elsecalc_trim_to();......
}

前面说到PGLog的记录数是有限制的,正常情况下默认是3000条(由参数osd_min_pg_log_entries控制),PG降级情况下默认增加到10000条(由参数osd_max_pg_log_entries)。当达到限制时,就会trim log进行截断。

在ReplicatedPG::execute_ctx()里调用ReplicatedPG::calc_trim_to()来进行计算。计算的时候从log的tail(tail指向最老的记录的前一个)开始,需要trim的条数为log.head - log.tail - max_entries。但是trim的时候需要考虑到min_last_complete_ondisk(这个表示各个副本上last_complete的最小版本,是主OSD在收到3个副本都完成时再进行计算的,也就是计算last_complete_ondisk和其他副本OSD上的last_complete_ondisk,即peer_last_complete_ondisk的最小值得到min_last_complete_ondisk),也就是说trim的时候不能超过min_last_complete_ondisk,因为超过了也trim掉的话就会导致没有更新到磁盘上的pg log丢失。所以说可能存在某个时刻,pglog的记录数超过max_entries。例如:

http://www.lryc.cn/news/145475.html

相关文章:

  • macOS使用命令行连接Oracle(SQL*Plus)
  • Mac下使用Homebrew安装MySQL5.7
  • centos安装Nginx配置Nginx
  • Linux环境下搭建使用缓存中间件Redis
  • Oracle 本地客户端连接远程 Oracle 服务端并使用 c# 连接测试
  • java中上传文件先下载到本地再上传还有就是直接通过文件流url地址进行上传优缺点?
  • 华为复合vlan(mux vlan)
  • 第62步 深度学习图像识别:多分类建模(Pytorch)
  • GPT带我学-设计模式-适配器模式
  • Pyecharts教程(七):使用pyecharts创建堆叠柱状图的示例
  • C++中的强制转换的常用类型及应用场景详解
  • ubuntu调整时区
  • mybatis:动态sql【2】+转义符+缓存
  • 2021年09月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • Ansible学习笔记1
  • 解决centos离线安装cmake找不到OpenSSL问题
  • Java 中数据结构ArrayList的用法
  • UDP 多播(组播)
  • 分布式环境集成JWT(Java Web Token)
  • Python实战之数据表提取和下载自动化
  • Midjourney学习(三)6个高级应用
  • C语言:指针类型的意义
  • 如何将 PDF 转换为 Word:前 5 个应用程序
  • AP5192 DC-DC降压恒流LED汽车头灯摩托车电动车大灯电源驱动
  • Python Opencv实践 - Canny边缘检测
  • Python编程练习与解答 练习119:低于和高于平均水平
  • vue中的nextTick的作用
  • 如何通过四个步骤清理网络防火墙规则
  • 打开谷歌浏览器远程调试功能
  • ChatGPT时代的我的博客