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);
// 设置RW、log线程参数,注意W和log都是单线程的
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这块。