基於zookeeper的主備切換方法_PHP教程

來源:互聯網
上載者:User

基於zookeeper的主備切換方法


zookeeper的ZOO_EPHEMERAL節點(如果ZOO_EPHEMERAL滿足不了需求,可以考慮和ZOO_SEQUENCE結合使用),在會話關閉或到期時,會自動刪除,利用這一特性可以實現兩個或多節點間的主備切換。


實現方法:
1)在進程啟動時調用zookeeper_init()初始化:
bool X::init_zookeeper()
{
// 第一次調用時_clientid總是為NULL,
// 狀態為ZOO_EXPIRED_SESSION_STATE時,需要重新調用zookeeper_init,
// 這個時候可傳入的_clientid為前一次zookeeper_init()產生的_clientid


// 請注意zookeeper_init()是一個非同步呼叫,返回非NULL並不表示會話建立成功,
// 只有當zk_watcher中的type為ZOO_SESSION_EVENT和state為ZOO_CONNECTED_STATE時,
// 才真正表示會話建立成功。
_zhandle = zookeeper_init(zk_hosts, zk_watcher, 5000, _clientid, this, 0);
if (NULL == _zhandle)
{
MYLOG_ERROR("init zookeeper failed: %s\n", zerror(errno));
return false;
}


MYLOG_INFO("init zookeeper(%s) successfully\n", zk_hosts);
return true;
}


2)進入工作之前,先嘗試切換成主,只有成功切換成主後才進入work
bool X::run()
{
while (true)
{
int num_items = 0;
// 備機最簡單的方法是每隔一定時間,如1秒就嘗試轉成master,
// 如果不使用輪詢,則可以採用監視_zk_path的方式
mooon::sys::CUtils::millisleep(1000);


// 如果不是master,則嘗試轉成master,如果轉成不成功則繼續下一次嘗試
if (!is_master() && !change_to_master())
continue;


do_work();
}
}


bool X::is_master() const
{
return _is_master;
}


bool X::change_to_master()
{
static uint64_t log_counter = 0; // 打log計數器,備狀態時的日誌輸出


// ZOO_EPHEMERAL|ZOO_SEQUENCE
// _myip為本地IP地址,可以通過它來判斷當前誰是master
// _zk_path值樣本:/master/test,注意需要先保證/master已存在
int errcode = zoo_create(_zhandle, _zk_path.c_str(), _myip.c_str(), _myip.size()+1, &ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL, NULL, 0);


// (-4)connection loss,比如為zookeeper_init()指定了無效的hosts(一個有效host也沒有)
if (errcode != ZOK)
{
_is_master = false;


// 減少為備狀態時的日誌輸出
if (0 == log_counter++ % 600)
{
MYLOG_DEBUG("become master[%s] failed: (%d)%s\n", _zk_path.c_str(), errcode, zerror(errcode));
}


return false;
}
else
{
_is_master = true;
log_counter = 0;
MYLOG_INFO("becase master[%s]\n", _zk_path.c_str());


// sleep一下,以便讓原master進行中的完成
mooon::sys::CUtils::millisleep(2000);
return true;
}
}


3)當zookeeper會話成功建立或到期時均會觸發zk_watcher,可通過type和state來區分
void zk_watcher(zhandle_t *zh, int type, int state, const char *path, void *context)
{
X* x = static_cast(context);
MYLOG_DEBUG("zh=%p, type=%d, state=%d, context=%p, path=%s\n", zh, type, state, context, path);


// zookeeper_init成功時type為ZOO_SESSION_EVENT,state為ZOO_CONNECTED_STATE
if ((ZOO_SESSION_EVENT == type) && (ZOO_CONNECTED_STATE == state))
{
x->on_zookeeper_connected(path);
}
else if ((ZOO_SESSION_EVENT == type) && (ZOO_EXPIRED_SESSION_STATE == state))
{
// 需要重新調用zookeeper_init(),簡單點可以退出當前進程重啟
x->on_zookeeper_expired();
}
}


附: zookeeper日誌
預設情況下zookeeper日誌是輸出到stderr,但可以通過zoo_set_log_stream()來定向到自己的日誌輸出中,還可以使用zoo_set_debug_level()來控制zookeeper的記錄層級。

http://www.bkjia.com/PHPjc/1115820.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1115820.htmlTechArticle基於zookeeper的主備切換方法 zookeeper的ZOO_EPHEMERAL節點(如果ZOO_EPHEMERAL滿足不了需求,可以考慮和ZOO_SEQUENCE結合使用),在會話關閉或到期時...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.