Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1858906
  • 博文数量: 1000
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 7921
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-20 09:23
个人简介

storage R&D guy.

文章分类

全部博文(1000)

文章存档

2019年(5)

2017年(47)

2016年(38)

2015年(539)

2014年(193)

2013年(178)

分类: 服务器与存储

2015-07-22 16:52:56

1. 前言

网上关于zookeeper 原理分析的文章很多, 但是客户端的使用分析还是较少。在使用zookeeper时我们难免会碰到一些问题,本文旨在从zookeeper 客户端使用的角度分享一些应用开发的经验,让大家少走一些弯路。

全文分为三个章节:

  • 整体框架
  • 注意事项
  • 使用场景

2. 整体框架

2.1.流程分析

2.1.1. 数据结构

struct

                                                                  图1. 整体数据结构

 

zookeeper c 客户端主要围绕zhandler_t结构进行一系列操作,上图是一个全局性的展示,便于我们对其有个整体的了解。

重点关注其中4个队列:

to_process : 已经接收的网络数据包,准备进行处理;

to_send : 准备发送的网络数据包;

sent_requests :  异步操作时未完成的请求

completions_to_process : 已经完成的异步请求,准备执行(包括watcher回调)

2.1.2. 整体流程

frame

图2. 整体流程

        整体流程 包括:

        main线程:各种zookeeper api,  在应用中进行调用,用来执行zookeeper节点文件的增、删、改、查(包括watcher、异步回调、acl的设置)

        io线程:zookeeper_mt库才有,基于事件循环,进行网络通信;

        completion线程:zookeeper_mt库才有,执行异步回调、watcher回调;

2.1.3. main thread

main thread即应用开发的主线程,调用各种zookeeper api。

首先要调用zookeeper_init:进行资源初始化(参数的默认设置、host打乱顺序),如果是zookeeper_mt库则启动两个线程:io线程、completion线程, 设置相关参数、线程间通信管道。

接着就是各种zookeeper节点操作api(eg:zoo_create), 完成应用程序预期的功能。

2.1.4. io thread

do_io

图3. io thread

如上图所示,io线程使用poll进行事件循环,处理网络数据包,并进行协议包的解析与封装。

2.1.5. completion thread

do_completion

图4. completion thread

completion线程的功能比较单一,就是从completion_to_process队列中取出数据进行回调函数的运行。

2.2. 单线程与多线程

zookeeper  c 客户端分别提供了单线程的库与多线程的库,分别叫zookeeper_st 和 zookeeper_mt。

zookeeper_st主要用于不支持pthread 或者支持不完善的系统环境, zookeeper_st只提供异步操作的api, 应用程序需要在自己的事件循环中,调用api进行相关操作。

zookeeper_mt 会启动两个独立线程:io线程与completion线程, 封装了内部的事件循环,分别提供了同步和异步的api, 一般情况下建议使用这个库。

2.3. 同步与异步

zookeeper_st仅提供异步的api, zookeeper_mt提供同步与异步的api.

先说一下同步api, zookeeper_mt的同步:主线程调用完对应api后等待,io线程完成对应的操作后,通知主线程。

关于异步api, zookeeper_st,zookeeper_mt都提供,但是各自的调用方式不同。zookeeper_mt主线程执行完api调用后立即返回, completion线程完成回调函数的执行;但是zookeeper_st是单线程如果达到异步的效果呢?zookeeper_st提供了对应的事件处理函数: zookeeper_interest、zookeeper_process, 应用程序可以根据这两个api完成对应的事件循环,进行异步api的处理(可参见cli_st的实现)

2.4. 状态变迁

state

图5.状态变迁

2.5. 交互协议

4 字节长度 + 数据包内容

 

  • 握手包

握手请求包:prime_connection(zhandle_t *zh)

握手回应包:recv_buffer(zh->fd, zh->input_buffer);deserialize_prime_response

字段 长度(byte) 描述
protocolVersion 4 协议版本号
lastZxidSeen 8 最后一次事务id
timeOut 4 超时时间(ms)
sessionId 8 会话id
passwd_len 4 密码长度
passwd 16 密码
  • ping包
字段 长度(byte) tag 描述
xid 4 header PING_XID -2
type 4 header ZOO_PING_OP 11
  • auth包

auth请求包:send_auth_info、send_last_auth_info

字段 长度(byte) tag 描述
xid 4 header AUTH_XID -4
type 4 header ZOO_SETAUTH_OP 100
auth_type 4 req 0(ignored by the server)
scheme_len 4 req schema长度
scheme String req 具体schema字符串信息
auth_len 4 req auth buffer的长度
auth String req 具体auth字符串信息

auth回应包:deserialize_ReplyHeader

字段 长度(byte) tag 描述
xid 4 hdr AUTH_XID -4
zxid 8 hdr 事务id
err 4 hdr 返回信息,非0 出错
  • 设置全局watcher包

请求包:send_set_watches

字段 长度(byte) tag 描述
xid 4 header SET_WATCHES_XID -8
type 4 header ZOO_SETWATCHES_OP 101
relativeZxid 8 req 关联的事务id
dataWatches Len 4 (vector个数)String req get_data watcher
existWatches Len 4 (vector个数)String req exist watcher
childWatches Len 4 (vector个数)String req get_children watcher

回应包:deserialize_ReplyHeader

字段 长度(byte) tag 描述
xid 4 hdr AUTH_XID -4
zxid 8 hdr 事务id
err 4 hdr 返回信息,非0 出错
  • 基本api包

请求包:各个api, 例如zoo_acreate

字段 长度(byte) tag 描述
xid 4 header 自定义xid(xid = time(0), xid++)
type 4 header ZOO_CREATE_OP 1ZOO_DELETE_OP 2ZOO_EXISTS_OP 3

ZOO_GETDATA_OP 4

ZOO_SETDATA_OP 5

ZOO_GETACL_OP 6

ZOO_SETACL_OP 7

ZOO_GETCHILDREN_OP 8

ZOO_SYNC_OP 9

ZOO_GETCHILDREN2_OP 12

ZOO_CHECK_OP 13

ZOO_MULTI_OP 14

ZOO_CLOSE_OP -11

api_req 不同的请求封装不同的包.eg: zoo_awgetchar* path

Int32_t watch

req

回应包:process_sync_completion、process_completions

字段 长度(byte) tag 描述
xid 4 hdr AUTH_XID -4
zxid 8 hdr 事务id
err 4 hdr 返回信息,非0 出错
api_res 不同的请求封装不同的包.eg: zoo_awgetstruct buffer data;struct Stat stat; reply
阅读(2484) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~