[sheepdog] [PATCH 1/2] zookeeper: remove master from zookeeper
Liu Yuan
namei.unix at gmail.com
Tue Aug 6 14:34:58 CEST 2013
On Tue, Aug 06, 2013 at 05:18:11AM -0700, Kai Zhang wrote:
> In the old implementation, zookeeper driver needs master to handle join requests
> and avoid errors during concurrent joining.
>
> However, as join requests can be handled by any joined node, we have cheeper
> way to avoid errors during concurrent joining.
>
> In this patch, we use ephemeral znode to simulate distributed lock.
> Before a node send join request, it have to acquire the lock.
> And under the protection of the lock, zk_member_empty() is safe because the
> membership it stable.
>
> Because the znode is ephemeral, the lock will automatically released if the
> node is down.
>
> Signed-off-by: Kai Zhang <kyle at zelin.io>
> ---
> sheep/cluster/zookeeper.c | 218 ++++++++-------------------------------------
> 1 file changed, 37 insertions(+), 181 deletions(-)
>
> diff --git a/sheep/cluster/zookeeper.c b/sheep/cluster/zookeeper.c
> index 6e632fc..357824a 100644
> --- a/sheep/cluster/zookeeper.c
> +++ b/sheep/cluster/zookeeper.c
> @@ -30,7 +30,7 @@
> #define BASE_ZNODE "/sheepdog"
> #define QUEUE_ZNODE BASE_ZNODE "/queue"
> #define MEMBER_ZNODE BASE_ZNODE "/member"
> -#define MASTER_ZNONE BASE_ZNODE "/master"
> +#define JOIN_LOCK_ZNODE BASE_ZNODE "/join_lock"
>
> /* iterate child znodes */
> #define FOR_EACH_ZNODE(parent, path, strs) \
> @@ -72,15 +72,11 @@ static struct sd_node sd_nodes[SD_MAX_NODES];
> static size_t nr_sd_nodes;
> static struct rb_root zk_node_root = RB_ROOT;
> static pthread_rwlock_t zk_tree_lock = PTHREAD_RWLOCK_INITIALIZER;
> -static pthread_rwlock_t zk_compete_master_lock = PTHREAD_RWLOCK_INITIALIZER;
> static LIST_HEAD(zk_block_list);
> -static uatomic_bool is_master;
> static uatomic_bool stop;
> static bool joined;
> static bool first_push = true;
>
> -static void zk_compete_master(void);
> -
> static struct zk_node *zk_tree_insert(struct zk_node *new)
> {
> struct rb_node **p = &zk_node_root.rb_node;
> @@ -496,7 +492,6 @@ static inline void build_node_list(void)
> static int zk_queue_init(void)
> {
> RETURN_IF_ERROR(zk_init_node(BASE_ZNODE), "path %s", BASE_ZNODE);
> - RETURN_IF_ERROR(zk_init_node(MASTER_ZNONE), "path %s", MASTER_ZNONE);
> RETURN_IF_ERROR(zk_init_node(QUEUE_ZNODE), "path %s", QUEUE_ZNODE);
> RETURN_IF_ERROR(zk_init_node(MEMBER_ZNODE), "path %s", MEMBER_ZNODE);
> return ZOK;
> @@ -562,12 +557,6 @@ static void zk_watcher(zhandle_t *zh, int type, int state, const char *path,
> } else if (type == ZOO_DELETED_EVENT) {
> struct zk_node *n;
>
> - ret = sscanf(path, MASTER_ZNONE "/%s", str);
> - if (ret == 1) {
> - zk_compete_master();
> - return;
> - }
> -
> ret = sscanf(path, MEMBER_ZNODE "/%s", str);
> if (ret != 1)
> return;
> @@ -605,186 +594,46 @@ static int add_join_event(void *msg, size_t msg_len)
> return zk_queue_push(&ev);
> }
>
> -static int zk_get_least_seq(const char *parent, char *least_seq_path,
> - int path_len, void *buf, int *buf_len)
> +static int zk_acquire_lock(const char *path)
> {
> - char path[MAX_NODE_STR_LEN], *p, *tmp;
> - struct String_vector strs;
> - int rc, least_seq = INT_MAX , seq;
> -
> + int rc;
> while (true) {
> - RETURN_IF_ERROR(zk_get_children(parent, &strs), "");
> -
> - FOR_EACH_ZNODE(parent, path, &strs) {
> - p = strrchr(path, '/');
> - seq = strtol(++p, &tmp, 10);
> - if (seq < least_seq)
> - least_seq = seq;
> - }
> -
> - snprintf(path, MAX_NODE_STR_LEN, "%s/%010"PRId32,
> - parent, least_seq);
> - rc = zk_get_data(path, buf, buf_len);
> + rc = zk_create_node(path, "", 0, &ZOO_OPEN_ACL_UNSAFE,
> + ZOO_EPHEMERAL, NULL, 0);
> switch (rc) {
> case ZOK:
> - strncpy(least_seq_path, path, path_len);
> - return ZOK;
> - case ZNONODE:
> + return rc;
> + case ZNODEEXISTS:
> + sleep(1);
why sleep here?
Thanks
Yuan
More information about the sheepdog
mailing list