有哪些功能?
1.dubbo注册服务 //或者说,叫协调。whatever。 统一命名服务
2.分布式锁 基于zookeeper。 其实本质上就是基于一个第三方中间件来专门存储多进程访问的数据。使用其他第三方软件存储数据也是一样,就看哪个更好使。
3.配置管理 ?
4.分布式队列
5.等待更多功能
分布式 数据一致性 协议
1.paxos 2.基于paxos,自创了一套协议,叫zookeeper协议 其实就是一个通信协议而已,只不过是用于分布式 多进程的情况下,访问一个共享资源/数据。
发展史
1.hadoop大数据的子项目 2.雅虎公司,对google chubby的实现,且开源
主要目的和作用是为了解决,中间件的单点问题
分布式 数据一致性 协议:到底要满足哪些要求?
1.顺序访问
主要是写操作的严格顺序性
2.事务
严格顺序
可以确保客户端,基于zookeeper,构建分布式同步功能。
严格顺序访问和事务之间的关系
严格顺序访问是基础,只有首先确保这一点,基于这个基础才能实现事务。
严格顺序访问如何实现?
每次请求访问,都有一个递增的唯一标识id。
所有的事务请求顺序,就以这个id为准按顺序进行操作。
数据结构
每个数据是ZNode数据结构。
数据如何存储
类似目录文件这种。就是树目录。
格式:哪个机器/哪个service/哪个method,就可以唯一定位哪个机器的远程方法调用。
数据存储在哪里?
内存。
速度
因为数据存储在内存,所以速度快。即可以实现,高服务器吞吐、减少延迟的目的。
每秒请求10万级别
适合读请求
tcp长连接
通过心跳保持通信。 所谓心跳,其实就是短时间内(以秒为单位,比如一般是1秒或几秒)发送数据和接受数据。
客户端连接服务器zookeeper的会话
数据节点-临时节点和持久节点
数据节点ZNode分两种
1.临时节点
指的是随客户端服务器会话session的生命周期一起创建和消亡
2.持久节点
会话连接断了,数据仍然还在
节点ZNode的数据格式
以/来分割
比如,/服务生产者ip/service类/method。
事件监控和通知
分几步
1.注册事件
2.触发事件
3.事件通知到某人
zookeeper的优势在哪里?和同类产品相比?
目前,分布式协调,zookeeper是唯一的解决方案。
集群
节点数量
节点数量三个起。
一般3 5个就够了。且为奇数数量。
节点之间互相通信
两两之间,互相通信。
每个节点都保存了所有节点的状态数据
如果挂了一个,怎么办?
客户端会自动连接到其他节点。
只要半数以上节点正常运行,集群就可以正常工作
1.主备复制 备作用主要是备份
2.如果更进一步,备也可以作为读,分担读的请求
不过,这个时候需要程序员在应用层面,区分读写请求
集群-节点角色和作用
三种角色
1.leader
读
写
2.跟/追随者follower
读
选举
3.观察者observer
读
不选举
leader选举算法
为什么要选leader?或者说,leader的作用是什么?
1.redis-哨兵机制
之所以选择一个哨兵作为Leader,是因为主数据节点挂了,需要故障转移和恢复。
但是,平时,所有的哨兵节点是平等的,所有客户端连接哨兵的时候是随机选择一个。
2.zookeeper
zookeeper,是一开始就有一个leader,专门用来接收客户端的所有请求。
一旦,这个唯一的leader挂了,那么zookeeper集群里的追随者follower节点会选举出来一个新的leader节点,替代挂了的那个旧的leader节点的位置和作用。
如何选?选举算法? 只有一个节点负责处理所有的请求,那个节点就是Leader节点。所以是单进程单线程,在处理所有请求,所以速度快。
具体细节?
leader负责接受请求,然后:
1.第一步,leader把proposal提议询问所有追随者follower
计算选票数量
2.如果过半数节点提议,第二步,leader把commit提交询问所有追随者follower,目的是要去follower提交刚才的那个proposal提议
与两阶段提交的区别?
与两阶段提交,稍微有一点区别,就是:
1.两阶段提交
是必须所有的节点都同意,才能提交事务。
2.zookeeper协议-消息广播工作模式
只要follower过半,就能提交事务。
如何计算票数?由谁来计算?
1.由leader计算票数
具体过程如上所述。
2.具体如何计算
这里注意一点,就是leader把提议prolocal询问所有follower的时候,follower是要给一个响应的,具体就是ack确认,leader每收到一个follower的ack确认,就加1。
最终到底是由谁来提交事务?
每个节点,包括leader和所有follower都要提交事务。
参考
mp.weixin.qq.com/s/z73f6rQXY…
协议
两种工作模式
1.崩溃恢复
用于解决故障恢复的问题
2.消息广播 用于解决分布式事务-两阶段提交的问题
四个方面
1.系统模型
2.问题描述
3.算法描述
4.运行分析
过半进程子集quorum(法定数量的意思)
故障恢复
流程
1.leader挂了
2.follower选举出来一个新的leader
3.新的leader知道自己已经成为了leader
4.其他follower知道新的leader已经诞生
所有节点都要提交commit提议proposal,是什么意思?
待补充
不丢弃和丢弃
如果leader挂了,这时可能出现两种异常情况
1.leader提交proposal之后,才挂的
故障恢复之后,即选举出来新的Leader之后,所有的节点(包括新的leader和所有的follower)都仍然要提交那个提议proposal。
2.leader接受到了这个请求事务提议proposal,但是还没来得及提交proposal,就挂了
故障恢复之后,需要丢弃那个提议proposal。
确保不丢弃和丢弃,这个是由zookeeper协议来定义和实现的。
新的Leader,是否包含有最新/最大的事务提议proposal?
1.如果包含,那么就不用再查找到那个提议proposal
2.如果不包含,还需要查找
主从复制
其实,zookeeper也算是/类似于主备复制。 1.redis/mysql 从节点从主节点复制数据。
2.zookeeper follower节点从leader节点复制数据。因为所有的请求事务提议proposal都有Leader接受,就像是数据库/缓存的所有写操作都是由主节点接受。
丢弃提议Proposal的过程?
这个地方稍微有点不明白,没看懂!
待补充
选举
首先,要理解两种工作模式,一种是正常的工作模式,一种是异常即leader挂了。
1.正常情况下,是工作在发送消息模式
即leader向所有follower发送事务提议proposal
2.如果挂了,才需要执行以下步骤
1)选举新的leader
2)follower同步新leader的数据
3)leader接受新的请求事务提议proposal,然后,广播提议proposal给所有follower
新的Leader,到底是怎么选举出来的? 两两互相投票,且只投票一次,最先得到过半数量的投票之后,那个follower就成为新的leader——这一点,选举算法和redis-哨兵机制的选举leader一样。
只不过,选举出来leader之后,接下来要做的事情也差不多,无非就是进行故障转移。
1.redis
leader哨兵,对挂了的主数据节点的所有从数据节点进行故障转移。
2.zookeeper
1)确认自己已经成为新的leader
2)通知所有follower,自己已经成为leader
让所有follower来复制它的数据(即事务提议proposal)
新的leader,何以知道自己已经被选举为leader?
同上
连接/通信
1.leader和所有follower连接
2.follower之间不连接
就好比从节点之间也不连接一样
错!follower节点之间是互相通信的,不然怎么选举出来新的leader呢!
节点的三种状态
1.leading
即leader状态,说明该状态的节点是leader
2.looking
即选举状态,说明现在没有Leader或leader挂了正在进行选举
3.following
即follower状态,说明该状态的节点是follower,目前没有正在选举leader
每个节点都有一个事务提议proposal队列,用于按顺序处理即提交提议proposal
zookeeper协议和paxos协议的区别
作用
这两个协议的作用,都是为了解决分布式 数据一致性 协议的问题。
区别
基本上一样,因为zookeeper协议是基于paxos改了一点东西。
比如,选举leader时,一个是过半,一个是必须全部同意。其他基本上一样。
安装和部署
两种模式 1.单机 2.集群
集群
注意事项
1.配置文件-主配置文件
主要包含了所有节点的ip。且,每个节点的该配置文件内容一样。
2.配置文件-服务器id
每个机器的内容不一样。
这个配置文件就只有id这个一行内容。
单机
其实,和集群完全一样。因为,单机模式就是集群模式的特殊情况,什么特殊情况?就是集群只有一个节点。
配置文件的配置,就只剩下一个节点的ip等内容。除此之外,其他一样。
应用场景
发布和订阅数据
应用场景说明
动态更新配置文件里的数据。有三种解决方案:
1.基于磁盘文件
即配置文件。
如果要动态获取,可以定时读配置文件。
2.基于内存
JMX。监控运行时的内存数据。
像jdk的官方监控,都是使用这种JMX技术来监控各项指标数据。
3.基于中间件
具体见下面。
基于中间件zookeeper
步骤
1.初始化数据
一开始把数据,写到zookeeper。
由谁来写数据?可以配置。
2.数据更新
动态更新之后,通知给所有监听这个数据的应用进程。
具体怎么通知?zookeeper有watch机制。
域名和ip映射
主要包含几个方面
1.注册数据
2.监控数据
3.数据的消费者进程
名字服务
什么是名字服务?
比如,应用场景
1.数据库配置
需要唯一定位到一个数据库
2.rpc框架的远程方法调用
需要唯一定位到集群服务里的某一台机器ip的某个类service的某个方法method。
这个问题,有两种解决方案
1.java jndi
这种解决方案的名字,就是叫做java name directory interface。要解决的问题,就是唯一定位/查找到某个机器ip/port的进程。
2.中间件zookeeper
rpc框架-dubbo的注册服务名字。
分布式id
问题的产生
1.单机单库单表
直接使用数据库提供的自动递增功能就可以了
2.分库分表
此时,数据库的自动递增功能不能解决问题。那怎么才能生成一个集群架构下的全局的唯一id呢?两种解决方案。1.UUID 2.基于中间件zookeeper。
UUID
优点
使用方便
缺点
1.数据太长,32位十六进制+4位- = 总共36位
2.对人类不易读
基于中间件
主要是能解决UUID的缺点。
但是也带来了问题,就是引入了第三方软件,多了一个对中间件软件的依赖,对系统的稳定性又构成了威胁。具体选择哪种解决方案,就看需求,如果能使用UUID就使用UUID,怎么方便怎么来,如果实在要使用中间件,那就引入中间件。
分布式协调和通知
mysql 复制和bin log功能。
双击热备份。有点浪费。
冷备份。
分布式进程的三种通信方式 1.心跳检测
2.数据进度汇报
偏移量
3.系统调用
rpc框架的远程方法调用
消息中间件-metaQ
组成节点 1.消息生产者 2.metaQ 3.消息消费者
以上每一种节点,都是集群。
协调的节点是zookeeper,也是集群。具体集群的实现原理参考上文。
详细说明
1.生产者
负载均衡选择一个节点,具体流程是:生产者——zookeeper:获取中间件集合,轮询选择一个——metaQ
2.metaQ
metaQ服务器(即broker)是主备复制
3.消费者
负载均衡选择一个节点,具体流程是:消费者——zookeeper:获取中间件集合,轮询选择一个——metaQ
总结
1.第一点,生产者和消费者的流程差不多,就是从协调者中间件zookeeper获取消息服务器的节点集合,然后按轮询算法选择一个写或读数据。
2.第二点,协调者中间件zookeeper会监控所有的消息中间件metaQ,metaQ挂了或是增加节点zookeeper都会自动感知得到,zookeeper并且更新保存自己这里的metaQ节点集合(删除挂了的或写入新增的节点)。
工作实践-支付系统
metaQ集群架构也是如上。
rpc中间件-dubbo
组成部分
1.服务生产者
2.注册中心中间件zookeeper
包含生产者集合数据 + 消费者集合数据。
3.服务消费者
流程和metaQ一样,就是通过协调者zookeeper实现负载均衡:消费者——zookeeper:从生产者集合里按轮询算法选择一个——生产者。
dubbo-监控中心
1.监控中心会获取和监控zookeeper的数据(生产者集合和消费者集合)
保存在消费者的本地
2.所以,如果zookeeper挂了,也不影响消费者查找到生产者,因为消费者的本地存储了生产者集合
临时节点
虽然zookeeper提供了持久节点,但是dubbo的节点都是临时节点,因为dubbo节点(生产者或消费者)挂了,那么zookeeper自动感知——即自动删除或增加。
参考
国内作者写的唯一一本zookeeper的书,而且写的非常好!