zoukankan      html  css  js  c++  java
  • OceanBase中主备Rootserver如何管理切换

    主RootServer会不断给备RootServer发送lease。被RootServer收到该lease后会保存到几个变量中:
    int ObCheckRunnable::renew_lease(const ObLease& lease)
    {
      int err = OB_SUCCESS;
      lease_on_ = true;
      lease_time_ = lease.lease_time;
      lease_interval_ = lease.lease_interval;
      renew_interval_ = lease.renew_interval;
      return err;
    }
    

    然后备RootServer的CheckRunnable::run()线程中会周期性检查是否需要进行lease续约。RS会检查vip是否与自己的本地ip一致,分为几种情况:
    if (rs.ip = vip  && rs.role = slave)
    {
       vip漂移到了备rs(原因可能是主rs挂掉了)
       备rs读取自己的lease状态,如果状态不为invalid则自己进入switching状态。
     (如果被发现自己lease已经超时,则认为自己的lease状态为invalid,此时报警,不做切换)
    }
    if (rs.ip = vip && rs.role = master)
    {
       vip还在主rs上。属于一般正常情况。什么都不用做。
    }
    if (rs.ip != vip && rs.role = slave)
    {
      vip不在备rs上。属于一般正常情况。
      这时候检查一下自己的lease状态,如果lease为invalid状态,则进入state变为init状态,重新注册。
      如果lease为should renew状态,则renew lease(向vip rs发送renew请求)。
    }
    if (rs.ip != vip && rs.role = master)
    {
      异常情况。主rs失去了vip,为了避免损失进一步扩大,主rs立即退出。(思考:这里为什么主rs不把自己切换成备?)
    }
    这里特别需要注意的是renew lease,它始终是向vip rs发送renew lease请求,而不是向某个具体的rs发送请求。所以rs的lease状态严重依赖于HA。

    什么时候需要Renew lease呢?看下面一段代码。仅当lease超过了一个安全区域即将过期的时候才会renew。
    // common/ob_check_runnable.cpp
    
    int64_t ObCheckRunnable::get_lease_status_()
    {
      LeaseStatus status = LEASE_NORMAL;
      timeval time_val;
      gettimeofday(&time_val, NULL);
      int64_t cur_time_us = time_val.tv_sec * 1000 * 1000 + time_val.tv_usec;
      if (lease_time_ + lease_interval_ < cur_time_us)
      {
        TBSYS_LOG(WARN, "Lease expired");
        status = LEASE_INVALID;
      }
      else if (lease_time_ + lease_interval_ < cur_time_us + renew_interval_)
      {
        TBSYS_LOG(DEBUG, "Lease will expire");
        status = LEASE_SHOULD_RENEW;
      }
    
      return status;
    }
    
    


    下面梳理一次主死掉、备切换成主的过程:

    1. 主、备各司其职。主负责具体工作,备通过回放commit log与主保持准同步状态。

    2. 主因为某种原因死掉(运维、异常等),HA检测到该事件,立即进行IP切换(把备的IP设置成VIP)

    3. 备在CheckRunnable::run()中检测到自己的IP与VIP相等,并且自己当前角色是SLAVE,立即把自己的STATE设置成SWITCH状态。

    4. 在run()开始执行之前,主线程(ob_root_worker.cpp)就已经在一个loop里面了:

            while (ObRoleMgr::SWITCHING != role_mgr_.get_state() // lease is valid and vip is mine
                && ObRoleMgr::INIT != role_mgr_.get_state() //  lease is invalid, should reregister to master
                // but now just let it exit.
                && ObRoleMgr::STOP != role_mgr_.get_state() // stop normally
                && ObRoleMgr::ERROR != role_mgr_.get_state())
            {
              usleep(10 * 1000); // 10 ms
            }
    
            if (ObRoleMgr::SWITCHING == role_mgr_.get_state())
            {
                      切换成master:停止log等待线程,停止log重放线程,启动工作线程,等等。
            }


    小结:

    1. 主备切换受HA管理,非异常情况下主备RS不进行切换

    2. 备集群SWITCH状态是进入ACTIVE MASTER状态的准备态




    相关阅读

    OceanBase简史

    OceanBase Join操作

    OceanBase内部表

    OceanBase官网

    推荐几本数据库相关的书籍:

    数据库系统设计、实现与管理(第8版)
    数据库原理与设计
    NoSQL数据库入门/图灵程序设计丛书 (日)佐佐木达也|译
    深入NoSQL /Shashank Tiwari 著 图灵程序设计丛书
    大数据挑战与NoSQL数据库技术(大数据技术的学习指南。突破迷局

    几本架构书:

    网络.4.4BSD操作系统设计与实现(从系统架构师角度出发)
    架构实战(软件架构设计的过程)
    网络.ACE技术内幕:深入解析ACE架构设计与实现原理
    架构之美/斯宾耐立思,(Diomidis Spinellis)



    再来个个性t-shirt:
    NoSQL 非结构化数据库/大数据 程序主题T恤/Tshirt 两件包邮


  • 相关阅读:
    with open 向文件的某一固定行,追加内容
    静态语言 与 动态语言 的区别
    ELK
    matplotlib绘图
    django用户认证
    django+uwsgi+nginx 部署生产环境
    图片验证码+session
    ajax
    form
    middleware中间件
  • 原文地址:https://www.cnblogs.com/pangblog/p/3275407.html
Copyright © 2011-2022 走看看