zoukankan      html  css  js  c++  java
  • 【osd】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 entries
        bool 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) sort
        
        interval_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();
      else
        calc_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。例如:

    参考资料

    1. ceph中PGLog处理流程

  • 相关阅读:
    BFS visit tree
    Kth Largest Element in an Array 解答
    Merge k Sorted Lists 解答
    Median of Two Sorted Arrays 解答
    Maximal Square 解答
    Best Time to Buy and Sell Stock III 解答
    Best Time to Buy and Sell Stock II 解答
    Best Time to Buy and Sell Stock 解答
    Triangle 解答
    Unique Binary Search Trees II 解答
  • 原文地址:https://www.cnblogs.com/sunbines/p/15629079.html
Copyright © 2011-2022 走看看