zookeeper c客户端分析

原创
2013/10/24 18:28
阅读数 1.4K

记录下对zookeeper c客户端的学习,欢迎拍砖。

zookeeper c客户端分单线程库和多线程库,本文主要分析多线程库。

1. 线程模型

客户端通常会有3个线程,主线程,io线程和completion线程。

主线程:也就是调用zookeeper_init()的线程,主线程通常还会根据业务的需要调用各种zookeeper的API接口,比如节点的增删查改,ACL的设置等等。此外还会提供watch事件的异步回调处理函数。

io线程:负责建立维护与服务器的tcp连接,并通过该连接向服务器发送请求,接收服务器的响应及watch消息推送。对于同步请求,io线程收到服务器的响应后会直接进行处理。对于异步请求的响应和watch事件,则转交给completion线程进行处理。

completion线程:负责异步请求的回调处理以及watch事件的回调处理。

zhandle_t操作句柄里有四个重要的链表,to_process, to_send, sent_request, completions_to_process。

to_send:在节点增删查改的API接口里,将请求ID及请求的内容存放到to_send链表中,io线程负责从中取出并将请求发送给服务器。

to_process:IO线程从服务器收到数据包后,存放到to_process链表中,然后从该链表中取出数据包并进行相应处理。

sent_request:在节点增删查改的API接口里,将请求ID,回调处理函数指针,或者是数据缓存区以一个结构体的方式存放到sent_request链表中,IO线程收到服务器的响应后,会从该链表中根据请求的ID找到对应的结构体,进行后续处理。

completions_to_process:对于服务器推送的watch事件,或者是异步请求的响应,IO线程将放到该链表中,然后发送信号通知completion线程进行处理。

2. 状态机

这里需要注意的是:结合IO线程的运行流程,可得知当状态切换为expired_session或者auth_failed时,io线程会结束(结束前会回调通知主线程),这时主线程需要根据业务需要进行相应处理比如重连。

3. 同步异步请求与处理流程

主线程调用"zoo_"开头的接口对节点进行增删查改的操作,这些接口可分为同步和异步两大类。同步接口以"zoo_*"开头,异步接口以"zoo_a*"开头。

这些接口的最终处理方式为:创建completion_list_t结构体,保存请求对应的xid,回调处理函数指针,以及同步接口中创建的sync_completion结构体,然后添加到zhandle句柄的sent_requests列表中;创建oarchive结构体,保存请求对应的xid,请求的具体内容,然后添加到zhandle句柄的to_send列表中,最后唤醒io线程。

sync_completion结构体中包含了条件锁,同步接口就是利用这个条件锁进行等待,直到请求得到处理。

4. zhandle_t句柄的引用计数

由于主线程,io线程,completion线程都会对同一个句柄zhandle_t进行操作,因此采用引用计数的方式防止调用zookeeper_close接口销毁该句柄时可能导致的异常情况。

在api_prolog(),api_epilog中封装了句柄引用计数的操作,io线程和completion线程启动时就会调用api_prolog,线程结束前调用api_epilog。另外,在zookeeper_close接口里首先会判断引用计数的个数,只有等引用计数为0时,才会最终对该句柄进行销毁。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
1 收藏
0
分享
返回顶部
顶部