文章部分笔记来源于千峰讲解的zookeeper教程当中
Zookeeper 最早起源于雅虎
研究院的一个研究小组。在当时,研究人员发现,在雅虎内部很多大型系统基本都需要依赖一个类似的ZooKeeper系统来进行分布式协调
,但是这些系统往往都存在分布式单点问题
。
什么是分布式系统中的单点故障:
通常分布式系统采用主从模式,就是一个主控机连接多个处理节点。主节点负责分发任务,从节点负责处理任务,当我们的主节点发生故障时,那么整个系统就都瘫痪了,那么我们把这种故障叫作单点故障,zk通过选举机制来解决此问题。
所以,雅虎的开发人员就试图开发一个通用的无单点问题的分布式协调框架
,以便让开发人员将精力集中在处理业务逻辑上。
关于“ZooKeeper
”这个项目的名字,其实也有一段趣闻。在立项初期,考虑到之前内部很多项目都是使用动物的名字来命名的(例如著名的Pig项目),雅虎的工程师希望给这个项目也取一个动物的名字。
时任研究院的首席科学家 Raghu Ramakrishnan
开玩笑地说:“在这样下去,我们这儿就变成动物园了!”
此话一出,大家纷纷表示就叫动物园管理员吧,因为各个以动物命名的分布式组件放在一起,雅虎的整个分布式系统看上去就像一个大型的动物园了。
而 Zookeeper
正好要用来进行分布式环境的协调,于是,Zookeeper
的名字也就由此诞生了。
ZooKeeper是一个分布式的
,开放源码的分布式应用程序协调服务
,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性
服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
ZooKeeper 的设计目标是将那些复杂且容易出错的分布式一致性服务
封装起来,构成一个高效可靠的原语集
,并以一系列简单易用的接口提供给用户使用。
原语: 操作系统或计算机网络用语范畴。它是由若干条指令组成的,用于完成一定功能的一个过程。具有不可分割性,即原语的执行必须是连续的,在执行过程中不允许被中断。
zooKeeper代码版本中,提供了分布式独享锁
、选举
、队列的接口,代码在$zookeeper_home\src\recipes
。其中分布锁和队列有Java和C两个版本,选举只有Java版本。
以上都是来源于百度百科给我们的解释!
个人理解:ZooKeeper 是分布式应用程序的高性能协调服务。这一句话是官方解释,我们在不了解zookeeper的时候,看完百度百科上面的解释,其实脑子仍然是很模糊的,在Java层面,没用过zk的也都听说过,他可以做注册中心,还有分布式锁,首先脑子要明白一件事,zk不是普通的注册中心,他是可以存储数据的一个中间件,某种意义上来讲和redis非常像,但是和redis是两种类型的存储结构,redis是以key value形式存储的,zk是以节点(节点可以理解为就是文件夹)形式存储数据的。zk之所以说他是协调服务,
实际上都是基于他存储结构的特性,帮助我们在实际开发当中可以解决很多 服务与服务之间各种打交道 会产生的问题
。
例如redis他可以存储数据,但是因为他是key value存储在内存的,所以获取数据非常快,一般我们都用它来做缓存数据库,同时redis也可以完成分布式锁。
zk中的数据是保存在节点上的,节点就是znode,多个znode之间构成⼀颗树的⽬录结构。
Zookeeper 的数据模型是什么样⼦呢?它很像数据结构当中的树,也很像⽂件系统的⽬录
。
树是由节点所组成,Zookeeper 的数据存储也同样是基于节点,这种节点叫做 Znode
但是,不同于树的节点,Znode 的引⽤⽅式是路径引⽤,类似于⽂件路径:
/动物/猫
/汽⻋/宝⻢
这样的层级结构,让每⼀个 Znode 节点拥有唯⼀的路径,就像命名空间⼀样,对不同信息作出清晰的隔离。
zk中的znode,包含了四个部分:
data
:保存数据acl
:权限,定义了什么样的⽤户能够操作这个节点,且能够进⾏怎样的操作。
stat
:描述当前znode的元数据child
:当前节点的⼦节点适⽤于分布式锁的应⽤场景
- 单调递增可以实现服务注册与发现的效果
。假如会话关掉后大概10s左右,创建的临时节点就会消失。这个会话就是指的连接zk的客户端。那么临时节点是如何维持⼼跳呢?适⽤于临时的分布式锁
。zk的数据是运⾏在内存中,zk提供了两种持久化机制:
zk通过两种形式的持久化,在恢复时先恢复快照⽂件中的数据到内存中,再⽤⽇志⽂件中的数据做增量恢复,这样的恢复速度更快。
linux安装zookeeper详细教程:
https://blog.csdn.net/weixin_43888891/article/details/125400887?spm=1001.2014.3001.5501
https://blog.csdn.net/weixin_43888891/article/details/125400879
https://blog.csdn.net/weixin_43888891/article/details/125442668
https://blog.csdn.net/weixin_43888891/article/details/125474995
https://blog.csdn.net/weixin_43888891/article/details/125465486
https://blog.csdn.net/weixin_43888891/article/details/125478966
https://blog.csdn.net/weixin_43888891/article/details/125400914
在分布式系统中,zookeeper可以作为分布式协调组件,协调分布式系统中的状态。例如上图有两个服务,flag为两个服务的共用变量,这时候可以通过将变量存储到zk当中,来完成服务之间状态的同步与通知。
注册中心就是典型的案例,注册中心的其中一个点就是,当微服务集群做了负载均衡,假设一台机器挂了,他得立马告诉客户端,避免客户端调用了挂掉的服务。
zk在实现分布式锁上,可以做到强⼀致性。
分布式锁详解:https://blog.csdn.net/weixin_43888891/article/details/125461905
很多应用拆分成微服务,是为了承载高并发,往往一个进程扛不住这么大的量,因而需要拆分成多组进程,每组进程承载特定的工作,根据并发的压力用多个副本公共承担流量。
很多人说,支撑双十一是靠堆机器,谁不会?真正经历过的会觉得,能够靠堆机器堆出来的,都不是问题,怕的是机器堆上去了,因为架构的问题,并发量仍然上不去。
阻碍单体架构变为分布式架构的关键点就在于状态的处理
。如果状态全部保存在本地,无论是本地的内存,还是本地的硬盘,都会给架构的横向扩展带来瓶颈。
状态分为分发,处理,存储几个过程,如果对于一个用户的所有的信息都保存在一个进程中,则从分发阶段,就必须将这个用户分发到这个进程,否则无法对这个用户进行处理,然而当一个进程压力很大的时候,根本无法扩容,新启动的进程根本无法处理那些保存在原来进程的用户的数据,不能分担压力
。
所以要讲整个架构分成两个部分,无状态部分
和有状态部分
,而业务逻辑的部分往往作为无状态的部分,而将状态保存在有状态的中间件中
,如缓存,数据库,对象存储,大数据平台,消息队列等。