了解zookeeper与阅读api源码

栏目: 编程工具 · 发布时间: 6年前

内容简介:作者:其实zookeeper 能做什么只需要看看他的基本功能就行了,在这个基本功能能干什么,就看我们的想象力有多丰富了。zookeeper 多年前就很火了,说可以用来当做名字服务、管理配置、集群管理、服务发现、负载均衡、容灾、远程锁等等。

作者: tiankonguse | 更新日期:

其实zookeeper 能做什么只需要看看他的基本功能就行了,在这个基本功能能干什么,就看我们的想象力有多丰富了。

一、背景

zookeeper 多年前就很火了,说可以用来当做名字服务、管理配置、集群管理、服务发现、负载均衡、容灾、远程锁等等。

其实zookeeper 能做什么只需要看看他的基本功能就行了,在这个基本功能能干什么,就看我们的想象力有多丰富了。

当然,能够做什么是一回事,线上服务能不能使用是另一回事了,并不是可以做到就一定要使用,我们还需要看到支持某一功能时对于的弱点,值不值的这样选择。

就像有人说汇编语言很强大,可以做这个可以做哪个,但是我们实际线上服务一般不会使用汇编语言。 所以,我们先看看zookeeper 到底提供了什么基本功能吧。

二、功能

zookeeper有三个基本功能,如下:

1.储存的是一个树形结构的数据,树的叶子节点可以储存数据。

2.当某个节点的子节点变更时,连在这个节点的CLIENT可以实时监听到变化。

3.CLIENT对节点操作时,是原子操作。

在这三个功能的基础上,我们可以实现很多东西。

1. 文件系统

由于zookeeper的储存是个树形结构,刚好和目录显示,我们就可以使用zookeeper来当做文件系统。

叶子节点的值最好不要储存文件信息,而是储存成文件的路径或其他信息辅助信息。

2. 名字服务

名字服务比较抽象,而且很容易和配置服务或者服务发现冲突,因为他们的本质是一样的,只是定位不同而已。

这里一般指的时哪些数据库的配置,比如 mysql 数据库的连接信息、 redis 数据库的连接信息等。

3. 配置管理

这里的配置一般是一些杂项配置,比如服务的超时时间、服务的某些开关等等。

4. 远程锁

由于zookeeper的操作是原子的,可以使用zookeeper来当做分布式锁了。

就行redis的操作是原子的,我们可以使用redis来做分布式锁一样,虽然实现方式不一样,但是本质是一样的。

5. 集群管理

集群管理和名字服务很类似,都是获得后台服务的连接信息。

但是对于集群,这个连接信息是动态的。

后台服务可用时,会主动连接zookeeper中心,然后客户端就可以发现后台服务有哪些可用的机器了。

这里的关键点在于后台服务某台机器挂了或者新增了机器,客户端可以感知到机器的变化。

6. 服务发现 负载均衡 容灾

服务发现、负载均衡、容灾放在一起说吧。

容灾、服务发现和前面的集群管理一样,不过是换了一个名字,都是机器挂了能自动剔除,机器好了能自动加回来。

负载均衡这个就有难度了,默认使用zookeeper是不能做到负载均衡的。因为服务负载过高了,zookeeper是感知不到的。

所以整理需要其他辅助信息,比如每个服务端收集系统信息计算出一个负载值,客户端根据每台机器的负载值计算出该使用哪台机器。

当然,有时候负载不高,但是耗时较高怎么办?网络抖动怎么办?

所以使用zookeeper来做负载均衡是在有点强人所难了,通过各种辅助信息可以做到,但是代价比较大,耦合也会比较严重。

既然zookeeper不能用来当做负载均衡,自然也不能用来服务发现、容灾、集群管理、名字发现了。

因为负载均衡其实已经包含了那些所有的功能,本质都是决策出一个可用的后台机器然后使用。

那不用zookeeper用什么呢? 之前刚好看过一个开源的负载均衡组件Tseer(点击可查看),推荐使用那个。

当有,现在由于大数据横行,大家都使用这个,那不考虑负载均衡这个问题的话,使用zookeeper也可以接收。

三、用途

其实,zookeeper的关键用途还是在于一致性上,即原子操作。

数据原子更新后,也会分配一个唯一的递增的id来标示。

我这有个项目,主要使用这个唯一递增ID来实现了数据唯一版本号的功能。

当然,长远看这个迟早会遇到瓶颈的,因为我们是所有数据共用一个节点,这样所有数据的更新其实就是串行化了。

每次更新都需要协商,网络操作来回几次,少的话几毫秒,多的话十几毫秒也有可能,这里介绍平均5毫秒吧。

那每秒就只能有200个数据更新,一分钟只能有1.2W个数据更新,这就是上限了。

这样看来,zookeeper在那些轻量级的场景可以使用,到了更新量大或对服务可靠性要求较高时,就显得心有余而力不足了。

四、api源码

zookeeper提供了 c语言 的api,这里进行简单的阅读与解析。

1. 初始化

初始化函数是 zookeeper_init 。

这个函数做得事情也很简单,申请各种内存,检查参数合法性。

对于zookeeper的中心地址,一般会有多个,api对地址进行了随机打乱,然后先使用第一个地址。

一切检查完之后,会执行adaptor_init开两个线程进程,一个用于IO操作,并且封装了zookeeper内部的逻辑,一个用于处理业务数据。

2. 创建节点

创建函数有zoo_create和zoo_acreate。

zoo_create函数实际还是调用zoo_acreate函数,不过加了一个本地锁。

zoo_acreate函数做得事情就是请求包序列化,发包,然后在锁上等待直到处理数据线程发来通知。

3. 写数据

写数据调用zoo_set函数和zoo_set2函数。

这两个函数最终都是调用zoo_aset函数,即同步操作。

而zoo_aset的操作又和zoo_acreate类似,序列化数据,发包,锁等待,等到处理数据通知。

4.读数据

读数据函数zoo_get调用监听读函数zoo_wge。

监听读函数zoo_wget函数同步读函数zoo_awget。

而同步读函数做得事情和上面的写一样,这里不再重复叙述。

5. 序列化

对于网络通信,一般会关心传输的数据协议,也就是序列化与反序列化。

我们这边常用称为打包和解包,一个意思。

这是一段协议的打包代码,看着很完善,每个结构前有开始标识与结束标识,每个数据都哟偶自己的tag与类型,这不就是标准的TLV协议嘛,可以无限扩展,好用。

但是细看了start_record函数和serialize_String函数,我笑了。

zookeeper为了降低传输的数据大小,那些tag都没有打进去,于是这个协议变成了LV协议。

对于LV协议是臭名昭著的,因为扩展性特别差,相当于约定了每一字节的含义,只可追增,不可删除。

6. 其他

这里还有两个关键的两个线程逻辑还没看,后面看了再补上相关记录吧。

本文首发于公众号:天空的代码世界,微信号:tiankonguse-code。

推荐阅读:

了解zookeeper与阅读api源码

今天长按识别上面的二维码,在公众号中回复“ ACM模板 ”,你将免费获得我大学耗时四年整理的《ACM算法模板》。

回复“ 算法的世界 ”,或点击 阅读原文 加入“tiankonguse的朋友们”,已有三百多个小伙伴加入。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入浅出Node.js

深入浅出Node.js

朴灵 / 人民邮电出版社 / 2013-12-1 / CNY 69.00

本书从不同的视角介绍了 Node 内在的特点和结构。由首章Node 介绍为索引,涉及Node 的各个方面,主要内容包含模块机制的揭示、异步I/O 实现原理的展现、异步编程的探讨、内存控制的介绍、二进制数据Buffer 的细节、Node 中的网络编程基础、Node 中的Web 开发、进程间的消息传递、Node 测试以及通过Node 构建产品需要的注意事项。最后的附录介绍了Node 的安装、调试、编码......一起来看看 《深入浅出Node.js》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具