分布式系统中的问题
处理任务的问题
消息延迟:顺序消费问题
处理机器性能:导致消息延迟
时钟偏移:时钟信号在不同时间到达电路各个部分的现象,这就是时钟偏移。
网络延迟
进程崩溃
集群的问题
主节点崩溃:无法分配新的任务-需要选举解决
从节点崩溃:不能判断任务是否完成-判断节点是否失效
通信故障:主从无法信息交换
脑裂:只因为网络分区,导致多主,整体不一致
Cap
base理论
Zookeeper 基础知识
能做什么?
宏观:在分布式系统中,协作,管理竞争
功能:选举主节点,管理组内成员,管理元数据
Cap:主要满足了一致性,可用性两种,分区提供只读能力
不适合的场景
海量数据存储
运行模式:单机模式、伪集群模式和集群模式
单机模式:这种模式一般适用于开发测试环境,一方面我们没有那么多机器资源,另外就是平时的开发调试并不需要极好的稳定性。
集群模式:一个 ZooKeeper 集群通常由一组机器组成,一般 3 台以上就可以组成一个可用的 ZooKeeper 集群了。组成 ZooKeeper 集群的每台机器都会在内存中维护当前的服务器状态,并且每台机器之间都会互相保持通信。
伪集群模式:这是一种特殊的集群模式,即集群的所有服务器都部署在一台机器上。当你手头上有一台比较好的机器,如果作为单机模式进行部署,就会浪费资源,这种情况下,ZooKeeper 允许你在一台机器上通过启动不同的端口来启动多个 ZooKeeper 服务实例,以此来以集群的特性来对外服务。
集群模式角色与读写
主从模式写只能master 读是其他节点
领导者(leader):负责进行投票的发起和决议,更新系统状态,读写都是leader,每个操作都会有zid,每操作一个都是自增的,不会回退。
跟随者(follower):用于接收客户端请求并给客户端返回结果,在选主过程中进行投票。
观察者(observer):可以接受客户端连接,将写请求转发给 leader,但是observer 不参加投票的过程,只是为了扩展系统,提高读取的速度
结构:数据树
/
/master data:server id
/workers
/worker-1 data:test.com:2181
/tasks
/task-1-2 data: run cmd;
/assign
/worker-1/task-1-1 date: run cmd
Znode:每个节点叫Znode
/Master 保存 主节点机器id
/workers下面每个znode节点代表一个从节点信息,添加一个代表新增一个从节点
/tasks下面每个znode节点代表一个未分配的任务信息
/assign下面每个节点代表一个已分配任务信息 并且有执行完的状态
原语:指zk的基本方法,用这些方法能实现分布式锁,集群交互等功能,就是給最基本的操作,你可以用这些操作实现复杂的功能
原语包括:主要是对文件目录树的操作,1创建目录create 2 删除目录delete 3 检查目录是否存在exists 4设置目录对应数据setDate 5返回对应目录数据getDate 6 返回对应节点的所有子节点信息getChildren 7 sync 等待从节点数据同步最新
Znode:生命周期与节点类型
根据持续时间分
持久节点(persistent): 只能delete操作删除
临时节点(ephemeral):当客户端会话链接超时或主动关闭时,或者某个客户端主动删除该节点
根据是否有序
有序节点会在节点后面加 -1 来标识顺序,这里猜测应该是支持处理顺序执行任务用的,有序节点分两种,持久有序(persistent_sequential)临时有序(ephemeral_sequential)
监视与通知:
这里指的是客户端与zk的数据交互,当zk目录树变化的时候会通知客户端,客户端收到通知后,需要去zk添加一个监视点来保证下次更改zk会通知。
优势:客户端不会收到2次通知,这样就不会有网络导致的执行顺序问题,如果收到通知后,zk有了变化,也是不通知客户端的,客户端执行完本次通知,会去zk添加监视点,添加前会读取最新的zk目录树。
多个客户端操作一个目录树?重复操作问题如何解决?
有version
Zookeeper 仲裁
在集群模式下,文件树需要同步,单如果完全同步会影响相应时间。
法人:例如有5个服务器 法人设置成3个,对文件树的操作只要其中3台服务器成功,就算成功,其他的操作后同步。
不推荐双数服务器,3台只允许挂1台 4台也只允许挂1台,没啥卵用。
疑问:数据不一致问题怎么解决的,zk节点数据不一致,如果客户端连接了少数据的节点不就会出现数据不一致问题么。
脑裂
脑裂指一个集群因为网络原因分成2堆或多堆,每堆都选出一个主,不再是一个整体,仲裁的过半机制解决了脑裂问题
会话
一个客户端必须与zk服务器建立会话才能通信,当会话终止,在会话期间创建的临时节点会消失。
客户端会连接到集群中的一台服务器,通过tcp协议连接通信,当与当前服务器不能正常通信,会话会转移到其他服务器上。
会话提供了顺序保障,意味着同一个会话请求是FIFO先进先出的顺序执行。
zk实现锁
1 创建/lock临时节点(获取锁)
2 删除/lock临时节点(删除锁)
3 不用写过期时间,如果用锁的客户端挂了或超时了,会因为临时节点(ephemeral)的缘故消失。
zk实现服务治理
1 启动master服务器 /master节点上会添加服务器id
2 启动从节点,workers 上会添加一条目录 有从节点信息
3 所有节点需要ls命令监视/workers 和/tasks
4 客户端 添加一个任务 在/tasks 目录下创建任务目录和执行内容
5 主节点收到通知 分配任务,在/assign目录创建 执行这个任务的worker和任务目录名
6 从节点收到通知 确定 在/assign目录 下的任务是分配给他自己的,然后就执行任务并标注任务完成。
总结操作
1 添加服务到zk集群
2 客户端连接
3 添加任务到zk集群
4 主服务器分配任务
5 从服务器识别并执行任务
问题?分配任务后 task 里删除对应目录吗
zk保证
ZooKeeper 非常快速且非常简单。但是,由于它的目标是成为构建更复杂服务(例如同步)的基础,因此它提供了一组保证。这些是:
顺序一致性 - 来自客户端的更新将按发送顺序应用。
原子性 - 更新要么成功要么失败。没有部分结果。
单一系统映像 - 无论客户端连接到哪个服务器,它都会看到相同的服务视图。即,即使客户端故障转移到具有相同会话的不同服务器,客户端也永远不会看到系统的旧视图。
可靠性 - 应用更新后,它将从那时起持续存在,直到客户端覆盖更新。
及时性 - 系统的客户视图保证在特定时间范围内是最新的。