[sheepdog] [PATCH] zookeeper: fix cluster hang by giving priority to process LEAVE event
Yunkai Zhang
yunkai.me at gmail.com
Thu Jul 19 04:31:38 CEST 2012
Does anyone review this path? I have tested it for several days in our
testing environment, it have passed more than 120 cases, it works well
for us.
On Mon, Jul 16, 2012 at 1:07 PM, Yunkai Zhang <yunkai.me at gmail.com> wrote:
> From: Yunkai Zhang <qiushu.zyk at taobao.com>
>
> V2:
> - fix zk_queue_pop() when it's called by zk_unblock():
> continue to process block event when is_zk_unblock is True
> -------------------------------------------------------- >8
>
> As cluster request may retry infinitely when some sheeps left, than
> cluster_op_done could not to be called forever, so it will cause cluster
> hang problem.
>
> By giving priority to process LEAVE event when there is unfinished BLOCK
> event, we can fix this issue, but also comply with the rule which is very
> important for distributed system I think:
>
> All sheeps should process all events in the same order.
>
> Signed-off-by: Yunkai Zhang <qiushu.zyk at taobao.com>
> ---
> sheep/cluster/zookeeper.c | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/sheep/cluster/zookeeper.c b/sheep/cluster/zookeeper.c
> index 7bd20bd..e03fd22 100644
> --- a/sheep/cluster/zookeeper.c
> +++ b/sheep/cluster/zookeeper.c
> @@ -71,6 +71,7 @@ static struct zk_event zk_levents[SD_MAX_NODES];
> static int nr_zk_levents;
> static unsigned zk_levent_head;
> static unsigned zk_levent_tail;
> +static bool is_zk_unblock;
>
> static void *zk_node_btroot;
> static struct zk_node *zk_master;
> @@ -239,9 +240,11 @@ static int zk_queue_pop(zhandle_t *zh, struct zk_event *ev)
> struct zk_event *lev;
> eventfd_t value = 1;
>
> - /* process leave event */
> - if (uatomic_read(&zk_notify_blocked) <= 0 &&
> - uatomic_read(&nr_zk_levents)) {
> + /*
> + * Continue to process LEAVE event even if
> + * we have an unfinished BLOCK event.
> + */
> + if (!is_zk_unblock && uatomic_read(&nr_zk_levents)) {
> nr_levents = uatomic_sub_return(&nr_zk_levents, 1) + 1;
> dprintf("nr_zk_levents:%d, head:%u\n", nr_levents, zk_levent_head);
>
> @@ -282,6 +285,9 @@ static int zk_queue_pop(zhandle_t *zh, struct zk_event *ev)
> return 0;
> }
>
> + if (!is_zk_unblock && uatomic_read(&zk_notify_blocked) > 0)
> + return -1;
> +
> if (zk_queue_empty(zh))
> return -1;
>
> @@ -618,7 +624,9 @@ static void zk_unblock(void *msg, size_t msg_len)
> struct zk_event ev;
> eventfd_t value = 1;
>
> + is_zk_unblock = 1;
> rc = zk_queue_pop(zhandle, &ev);
> + is_zk_unblock = 0;
> assert(rc == 0);
>
> ev.type = EVENT_NOTIFY;
> @@ -656,9 +664,6 @@ static void zk_handler(int listen_fd, int events, void *data)
> if (ret < 0)
> return;
>
> - if (uatomic_read(&zk_notify_blocked) > 0)
> - return;
> -
> ret = zk_queue_pop(zhandle, &ev);
> if (ret < 0)
> goto out;
> --
> 1.7.10.4
>
--
Yunkai Zhang
Work at Taobao
More information about the sheepdog
mailing list