介绍下每个组件代码流摘要
Master:
1、获取leadership前2、尝试创建主znode
3、如果通过,则获取leadership
4、连接丢失后,需要检查znode是否存在以及谁拥有它
5、一旦确定他人拥有它,Watch主znode
6、获取leadership后
7、Get workers
8、在worker list上设置一个watcher
9、检查挂掉的worker并重新分配任务
10、遍历各个挂掉的worker
11、获取分配的任务
12、获取任务数据
13、将任务移至未分配的任务列表
14、删除分配
15、恢复任务(分配给死亡工人的任务)
16、获取未分配的任务并分配它们
17、遍历各个未分配的任务
18、获取任务数据
19、选择worker
20、分配给worker
21、从未分配的列表中删除任务
Worker:
1、创建/分配/ worker-xxx znode2、创建/ workers / worker-xxx znode
3、Watches /assign/worker-xxx znode
4、获得任务
5、对于每个任务,获取任务数据
6、执行任务数据
7、创建状态
8、删除分配
Client
1、创建任务2、Watch for status znode
3、在收到状态znode的通知后,获取状态数据
4、删除状态znode
编译:
编译需要依赖zookeeper的多线程c库zookeeper_mt,所以在编译前需要先安装其C API
进入./zookeeper/src/c目录
./configure
make
make install
然后编译当前代码:
gcc master.c -I/usr/local/zookeeper-3.4.8/src/c/include -I/usr/local/zookeeper-3.4.8/src/c/generated -DTHREADED -L/usr/local/lib -l zookeeper_mt
运行
先开启zookeeper:
bin/zkServer.sh start
运行程序:
./a.out 127.0.0.1:2181
master.h
#ifndef _master_h
#define _master_h
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <zookeeper.h>
#include <zookeeper_log.h>
#include <zookeeper.jute.h>
static const char *hostPort;
static zhandle_t *zh;
static int connected = 0;
static int expired = 0;
static int server_id;
static struct String_vector* workers = NULL;
static struct String_vector* tasks = NULL;
/*
* 函数定义
*/
void create_parent();
void run_for_master();
void check_master();
void master_exists();
void get_workers();
void get_tasks();
void task_assignment();
void get_task_data();
void delete_pending_task();
/*
* Master states
*/
enum master_states {
RUNNING,
ELECTED,
NOTELECTED
};
static enum master_states state;
enum master_states get_state () {
return state;
}
/*
* 将此结构的实例分配给worker时使用
*/
struct task_info {
char * name;
char * value;
int value_len;
char * worker;
};
/*
* 以下两种方法分别把事件类型和返回码转换为字符串
*/
static const char * type2string(int type){
if (type == ZOO_CREATED_EVENT)
return "CREATED_EVENT";
if (type == ZOO_DELETED_EVENT)
return "DELETED_EVENT";
if (type == ZOO_CHANGED_EVENT)
return "CHANGED_EVENT";
if (type == ZOO_CHILD_EVENT)
return "CHILD_EVENT";
if (type == ZOO_SESSION_EVENT)
return "SESSION_EVENT";
if (type == ZOO_NOTWATCHING_EVENT)
return "NOTWATCHING_EVENT";
return "UNKNOWN_EVENT_TYPE";
}
static const char * rc2string(int rc){
if (rc == ZOK) {
return "OK";
}
if (rc == ZSYSTEMERROR) {
return "System error";
}
if (rc == ZRUNTIMEINCONSISTENCY) {
return "Runtime inconsistency";
}
if (rc == ZDATAINCONSISTENCY) {
return "Data inconsistency";
}
if (rc == ZCONNECTIONLOSS) {
return "Connection to the server has been lost";
}
if (rc == ZMARSHALLINGERROR) {
return "Error while marshalling or unmarshalling data ";
}
if (rc == ZUNIMPLEMENTED) {
return "Operation not implemented";
}
if (rc == ZOPERATIONTIMEOUT) {
return "Operation timeout";
}
if (rc == ZBADARGUMENTS) {
return "Invalid argument";
}
if (rc == ZINVALIDSTATE) {
return "Invalid zhandle state";
}
if (rc == ZAPIERROR) {