使用zookeeper搭建分布式应用服务
一 背景
传统的应用是部署在单台服务器上的,随着业务的扩大,单机引用变得越来越难以满足使用要求。通常应用部署在单台服务器上面临的第一个问题是,随着业务的扩大,更多的用户使用应用服务,服务的性能、存储会面临很大挑战。对于一个对性能要求很高的业务应用,增大带宽、内存、硬盘读写速度,可以在一定程度上增大应用的性能,但单台服务器的网口带宽不能无限增大,内存也有一定限制,硬盘读写速度增大到一定程度也难以再增加。通常这个时候通过把应用部署到多台服务器,应用做成集群服务,即多台服务器分别部署相同的应用,做到了应用处理业务请求的线性增强。
但当一个任务需要用的资源很多,单台服务并不能满足时,又陷入了增加单台服务器的带宽、内存、硬盘等。面临此种情况时,可以使用多台计算的磁盘、内存等资源将是一个很好的解决问题的方式,由此分布式存储、分布式计算等分布式技术变得越来越流行,也越来越重要。
有关分布式的知识点非常的多,本文不多讨论,仅讨论如何使用分布式协调服务组件zookeeper搭建一个分布式应用服务。
二 术语和缩写
术语/缩写 |
含 义 |
HBase |
Hadoop生态系统的分布式数据库 |
HDFS |
分布式文件系统 |
Zookeeper(ZK) |
分布式应用程序协调服务 |
三 搭建分布式应用服务
1、Zookeeper简单介绍
Zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源实现,是Hadoop和Hbase的重要组件,它是一个为分布式应用提供一致性服务的软件。
ZooKeeper是一种为分布式应用所设计的高可用、高性能且一致的开源协调服务,它提供了一项基本服务:分布式锁服务。由于ZooKeeper的开源特性,后来的开发者在分布式锁的基础上,摸索了出了其他的使用方法:配置维护、组服务、分布式消息队列、分布式通知/协调等。
2、面临的问题
把一个应用做成分布式应用通常会面临如下几个问题:
(1) 应用服务的可靠性、可用性问题
(2) 应用服务的读写一致性问题
(3) 应用服务的配置维护问题
(4) 应用服务的负载均衡(性能)问题
(5) 其他问题
上述为列举的几个常见的问题,未对所有问题进行分析展开。
3、使用zookeeper解决上述几个问题
1)应用服务的可靠性、可用性问题
通常可靠性、可用性问题就是对于用户来说,应用服务在用户不感知的情况下持续提供服务的能力。单个服务进程可能是不能满足要求的,通常是分布在不同机器上的两个或者多个服务进程来提应用服务的高可用性、高可靠性。
如下图所示:
Server应用服务部署到多个服务器上,其中一个节点为Master,对外提供服务,其他节点为Standby,为挂起状态,Standby在Master正常的情况下不对外提供同服务,只有在Master服务停止(服务挂掉或者服务器断点等),Standby的服务会进行Master选举,选举出来的Standy服务会变成Master对外提供服务,之前的Master服务重启后,发现Master已经存在,则会变成Standby服务。
因此,从客户端用户角度来看,应用服务除了在Master选举过程中有短暂的时间停止服务外,应用服务一直在正常的对外提供服务,从而实现了应用服务的高可用性。
使用Zookeeper实现分布式应用Master主从选举一般有如下两种方式:
方式一:
不同服务共同创建zookeeper临时性znode节点,创建成功的为Master服务节点,未注册上的为Standby节点;standby节点通过在Master znode节点设置watcher监听Master是否存在,不存在则重新进行一轮Master选举。
示意图如下图所示:
方式二:
不同服务创建Zookeeper临时性Sequential的znode节点,znode序号小的为Master服务节点,其他的为Standby节点;standby节点通过在Master znode节点设置watcher监听Master是否存在,不存在则重新进行一轮Master选举。
示意图如下图所示:
上述两种方式方式均可以实现基于Zookeeper的主从选举,从而使分布式应用服务具有高可用性。
2)应用服务的读写一致性问题
在单机应用中,资源的读写可能会因为写数据未加锁,多线程读取时会出现脏读问题等问题。通常的解决方式是在多线程编程时对竞争的资源加锁,对资源的读写添加各种同步锁,读写锁等。但是在分布式应用中,应用部署在不同服务器上,属于不同的进程,不能通过上述方式加锁。
应用服务可以选择利用zookeeper的特性实现分布式锁,从而解决分布式应用对竞争资源的读写一致性问题。
基于zookeeper分布式锁的流程:
(1) 在zookeeper指定节点lock下创建临时顺序节点node_n;
(2) 获取lock下所有子节点children;
(3) 判断本节点是不是序号最小的子节点,若是,则获取锁;若不是,则监听比该节点小的那个节点的删除事件;
(4) 若监听事件生效,则回到步骤(2)重新进行判断,直到获取锁。
3)应用服务的配置维护问题
分布式应用服务通常是部署在多个服务器上的,多个服务器上的应用服务会共享一下配置。应用服务部署后,如果调整配置内容,如果配置文件在服务器本地,则需要一个一个修改,然后重启所有服务。如果配置文件在HDFS这种分布式文件系统中,虽然只需要修改一处,但也需要重启服务才能使用最新配置。
Zookeeper本身也是一个分布式应用,在任意节点读取znode内容均是一样的,同时zookeeper的事件监听与通知机制也可以是应用服务不重启的情况下获取的配置更改的通知,并完成配置的更新。
4)应用服务的负载均衡(性能)问题
使用Zookeeper也可以为分布式应用实现负载均衡的策略,通常用户的读写请求到达master主节点,可以提供服务的应用有多个,master主节点需要做请求分发,请求分发时会根据当前的多个应用服务的负载进行统计,最终把请求分发给负载较小的应用服务,从而实现负载均衡。
此种方式的分布式应用服务示意图如下图所示:
四 Zookeeper在项目中的应用
1、采用zookeeper做分布式应用
如果只允许一个节点写入,可以多个节点读取
可以主节点做HA,从节点均可以读取
2、主节点写入数据时,可以采用共享存储持久化
然后通过zk临时节点写入,其他节点注册watch监控node或者其children节点变化,数据变化后通知其它节点更新
3、考虑到zk信息可能会丢失消息或者因为网络问题导致未接收到信息,可以通过定时任务扫描持久化信息,更新内存缓存信息