oceanbase之RootServer(二)

4 類ObRootWorker

這是個大傢伙,它繼承自前面講過的ObBaseServer這個簡單框架類。自此已經很接近底層了。

4.1 成員變量

ObRootWorker本身引用了很多類,有關於log系統的,有關於Packet的,有關於client manage的,還有關於rpc的,等等;ObRootWorker正是集合了這些資源,完成了Root Server的功能。其成員變量如下:

  ObRootServer2 root_server_;

  common::ObPacketQueueThreadread_thread_queue_;

  common::ObPacketQueueThreadwrite_thread_queue_;

  common::ObPacketQueueThreadlog_thread_queue_;

  common::ObClientManager client_manager;

  common::ObServer rt_master_;

  common::ObServer self_addr_;

  common::ObRoleMgr role_mgr_;

  common::ObSlaveMgr slave_mgr_;

  common::ObCheckRunnable check_thread_;

  ObRootFetchThread fetch_thread_;

  ObRootRpcStub rt_rpc_stub_;

  ObRootLogReplay log_replay_thread_;

  ObRootLogManager log_manager_;

  ObRootStatManager stat_manager_;

如前所述,它是ObBaseServer的子類,這裏重載了initialize和start_service方法;它還繼承自tbnet::IPacketQueueHandler,所以還需要重載handlePacket的兩個方法;爲了實現admin的merge指令,它還定義了public start_merge接口。

此外,還需要實現tbnet::IPacketQueueHandler定義的handlePacketQueue這個接口,此接口將被上面定義的幾個thread queue調用。

其private的rt_xxx函數族,從命名來看就是和heart beat、get update server info等方法相對應的。

先掃掉兩個小嘍羅,首先是common::ObServer,這其實就是個ipv4/v6的封裝而已,提供一個比較功能和to string操作;其次是common::ObRoleMgr,就是一個狀態enum,可以根據enum轉換成對應的string。

4.2 初始化和服務啓動

先來看看初始化函數initialize()的基本邏輯,無外乎是完成各成員變量的初始化。

client_manager.initialize(get_transport(),get_packet_streamer());

rt_rpc_stub_.init(&client_manager,&my_thread_buffer);

// 設置並獲取本機IP

int32_tlocal_ip = tbsys::CNetUtil::getLocalAddr(dev_name_);

self_addr_.set_ipv4_addr(local_ip,port_);

slave_mgr_.init(vip,&rt_rpc_stub_, log_sync_timeout, lease_interval, lease_reserv);

// 設置RWlog線程參數,注意Wlog都是單線程的

thread_count= TBSYS_CONFIG.getInt(STR_ROOT_SECTION, STR_THREAD_COUNT, 20);

read_thread_queue_.setThreadParameter(thread_count,this, NULL);

void*args = reinterpret_cast<void*>(WRITE_THREAD_FLAG);

write_thread_queue_.setThreadParameter(1,this, args);

 

args =reinterpret_cast<void*>(LOG_THREAD_FLAG);

log_thread_queue_.setThreadParameter(1,this, args);

// 如果本機是vip,就以master角色啓動,否則就是slave

// vip從配置中讀取

if(tbsys::CNetUtil::isLocalAddr(vip))

    role_mgr_.set_role(ObRoleMgr::MASTER);

else

    role_mgr_.set_role(ObRoleMgr::SLAVE);

rt_master_.set_ipv4_addr(vip,port_);

 

check_thread_.init(&role_mgr_,vip, vip_check_period_us,

&rt_rpc_stub_,&rt_master_, &self_addr_);

root_server_.init(config_file_name_,now, this);

具體成員的初始化,暫且放到後面再看吧,現在先了解worker初始化的基本邏輯。

接下來是啓動服務,start_service這個函數很簡單,如上面的代碼,需要根據vip決定是以master還是以slave啓動。

ObRoleMgr::Role role =role_mgr_.get_role();

if (role == ObRoleMgr::MASTER)

    ret = start_as_master();

else if (role ==ObRoleMgr::SLAVE)

    ret = start_as_slave();

先買先看master角色的邏輯吧。

4.3 以master角色啓動

以master啓動,就進入到start_as_master()函數中。第一件事就是初始化log manager並replay log。

ret =log_manager_.init(&root_server_, &slave_mgr_);

ret =log_manager_.replay_log();

log_manager_.get_log_worker()->reset_cs_hb_time();

其後轉移到ACTIVE狀態,並啓動RW、LOG線程

role_mgr_.set_state(ObRoleMgr::ACTIVE);

read_thread_queue_.start();

write_thread_queue_.start();

check_thread_.start();

最後是循環等待結束,並檢查是否有狀態遷移發生

for(;;){

     if (ObRoleMgr::STOP ==role_mgr_.get_state()

              || ObRoleMgr::ERROR ==role_mgr_.get_state()){

         TBSYS_LOG(INFO, "role managerchange state, stat=%d", role_mgr_.get_state());

         break;

     }

     usleep(10 * 1000); // 10 ms

}

還是沿着該函數的軌跡來吧,接下來先來看看log manager這塊。

發佈了90 篇原創文章 · 獲贊 99 · 訪問量 164萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章