switch 切换目录
1
2
3
4
5
6#!/usr/bin/expect -f
set dirname [lindex $argv 0]
spawn sudo su - $dirname
expect "adminlp:"
send "adminlp@v\$3234\r"
interactcp 拷贝
1
2
3
4
5
6
7#!/usr/bin/expect -f
set file [lindex $argv 0]
set dir [lindex $argv 1]
spawn sudo cp $file $dir
expect "adminlp:"
send "adminlp@v\$3234\r"
interactcmd 串行执行
1
2
3
4
5
6
7
8
9
10
11
file=$1
cmd=$2
num=1
for ip in `cat $file|grep -v "#"|awk '{print $2}'|sort|uniq`;do
echo "$num: $ip:"
#ssh mrdTomcat@$ip "$cmd"
ssh $ip "$cmd"
echo
num=$(($num+1))
donescp 串行拷贝
1
2
3
4
5
6
7
8
9
file=$1
scp_s=$2
scp_d=$3
for ip in `cat $file|grep -v "#"|awk '{print $2}'|sort|uniq`;do
echo "$ip:"
scp $scp_s mrdTomcat@$ip:$scp_d
done
TCP IP 模型
TCP/IP
1 | TCP划分两个协议: |
协议和标准
1 | * 协议 |
OSI模型和TCP/IP协议族
1 | TCP/IP被广泛应用在因特网中,现在成为了占主导地位的商用体系结构;而OSI模型则从来没有被完全实现过 |
OSI模型
1 | OSI模型的作用就是展示两个不同的系统怎样做到互相通信,且不需要改变底层的硬件或软件逻辑 |
分层的体系结构
1
2
3
4
5
6
7
8
9OSI模型由7个排列的层组成:
1. 物理层
2. 数据链路层
3. 网络层
4. 传输层
5. 会话层
6. 表示层
7. 应用层
*报文的传输一般只涉及OSI模型的下三层:物理层,数据链路层,网络层*层与层之间的通信
1
2
3
4
5
6
71. 层之间的接口
每个接口都定义了该层必须向它的上层提供什么样的信息和服务
2. 层的组织方式
OSI七层可以看属于三个组:
* 物理层,数据链路层,网络层 是 网络支撑层,这些层的任务是把数据从一个设备传送到另一个设备
* 会话层,表示层,应用层 是 用户支撑层,这些层使得一些本来没有关系的软件系统之间有了互相操作性
* 传输层 是将这两层连接起来,使得底层发送的是高层可以使用的形式封装
1
第7层的分组被封装在第6层的分组中;第6层的分组被封装在第5层的分组中,以此类推
OSI模型中的各层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51* 物理层
物理层通过物理媒体传送比特流时所需要的各种功能
物理层涉及到接口和传送媒体的机械和电气规约
物理层关心的内容:
* 接口和媒体的物理特性
* 比特的表示(比特流(0和1序列)经过编码变成信号:电或光)
* 数据率(传输速率,每秒发送比特数)
* 比特的同步(发送和接收设备时钟同步)
* 线路配置(点对点配置,多点配置)
* 物理拓扑(网状拓扑,星状拓扑,环状拓扑,总线拓扑)
* 传输方式(单工方式,半双工方式,全双工方式)
* 数据链路层
数据链路层的任务:
* 组帧(将比特流划分成可以处理的数据单元,称为帧)
* 物理编址(在帧上附加一个首部,指明帧的发送方或接收方,本地寻址)
* 流量控制(接收方接收数据的速度小于发送方发送数据的速率,那么链路层使用流量控制来限速)
* 差错控制(检测并重传损伤或丢失的帧,增加了物理层的可靠性.帧后加尾部实现)
* 接入控制(当多个设备连接到同一个链路时,数据链路层必须决定任意时刻该由哪个设备对链路有控制权)
* 网络层
网络层负责把分组从源点交付到终点,这可能哟啊跨越多个网络(链路)
网络层的任务:
* 逻辑编址(网络层给从上层传来的分组附加一个首部,包括发送方和接收方的逻辑地址和其他信息)
* 路由选择(多个独立网络或链路互相连接组成互联网,这些连接设备就要为数据分组选路或交换到达目的地)
* 传输层
传输层负责报文的进程到进程的交付.进程是运行在主机上的应用程序
传输层确保整个报文原封不动的按顺序到达,它监督从源点到终点这一级的差错控制和流量控制
传输层任务:
* 服务点编址(传输层首部必须包含服务点地址(端口地址))
* 分段与重装(一个报文划分若干报文段,每个报文段包含一个序号.报文到达时,传输层利用序号将它们重装起来,丢失的分组也能识别并替换为正确的分组)
* 连接控制(传输层可以是无连接的,也可以面向连接的)
* 流量控制(传输层的流量是端到端的)
* 差错控制(传输层的差错控制是端到端的)
* 会话层
对某些进程来说,下四层提供的服务还不够充分.
会话层就是网络的对话控制器,它用于建立,维持并同步正在通信的系统之间的交互
会话层任务:
* 对话控制(运行两个进程之间的通信按半双工或全双工方式进行)
* 同步(会话层允许在数据流中插入若干检查点,用于确认数据是否正常,是否需要重传)
* 表示层
表示层考虑的问题是两个系统所交换的信息的语法和语义
表示层任务:
* 转换(在不同的编码方法之间提供互操作性,发送方转换成公共格式,接收方将公共格式转换为相应格式)
* 加密(将原始信息转换为另一种形式,然后发送到网上)
* 压缩(数据压缩减少了信息中包含的比特数)
* 应用层
应用层让用户能够接入网络(给用户提供接口,也提供服务支持)
应用层提供特定服务:
* 网络虚拟终端
* 文件传送,存取和管理(FTAM)
* 邮件服务
* 名录服务TCP/IP协议族
1
2
3
4
5
6
7
8
9
10
11TCP/IP协议族目前被认为是一个五层模型:
* 物理层
* 数据链路层
* 网络层
* 传输层
* 应用层
*TCP/IP 与 OSI模型相比少了会话层和表示层:*
* TCP/IP有很多传输层协议,会话层的某些功能在传输层协议中已经具备
* 应用层并不仅仅是一个软件,这一层允许开发的应用很多.特定的应用程序需要使用到会话层和表示层中的某些功能,这些功能可以包含在应用软件中进行开发
* TCP/IP是一个分层协议,它由多个交互的模块构成,每个模块有特定的功能,这些模块并不是必须互相依赖的
* OSI模型具体规定了哪一层应该具备哪些功能,而TCP/IP协议族的每一层包含的是一些相对独立的协议,可以根据系统的需要把这些协议混合并重新搭配使用TCP/IP中的各层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28* 物理层
TCP/IP没有定义任何特定的协议,它支持所有标准和专用协议
通信以比特为单位,当两个节点之间建立连接后,就会有一个比特流在它们之间流动.
但对于物理层来说每个比特都将被独立对待
*注意: 如果一个节点与n条链路相连,那么它需要n个物理层协议,每条链路各需要一个,原因在于不同的链路可能使用不能的物理层协议*
* 数据链路层
TCP/IP没有为数据链路层定义任何特定的协议,它支持所有标准和专用协议
通信仍然发生在两个节点之间,不过通信的单位却是帧的分组
一个帧就是封装了来自网络层的数据的分组,并为其附加一个首部,有时再加一个尾部
在首部主要包含了这个帧的源地址和目的地址
*注意: 当一个节点接收到一个帧后,就会将其提交给数据链路层,该帧被打开,卸下数据,然后在通过数据链路层重新生成一个新的帧,用于传输*
* 网络层
在网络层,TCP/IP支持的是网际协议(IP),IP传输的是称为数据报的分组,每个数据报独立传输,不同的数据报可以走不同的路由,也可能不按顺序到达,也可能会重复
IP不会跟踪记录这些数据报走过的路由,并且在它们到达目的地后,IP也不具有按原顺序重排的能力
*注意:网络层上的通信是端到端的通信,而数据链路层和物理层的通信是节点到节点的通信*
* 传输层
传输层和网络层之间一个重要的区别:
**网络中的所有节点都必须具有网络层,但只有两端的计算机上才具有传输层**
**网络层负责将一个个数据报独立地从计算机A发送到计算机B,而传输层负责将完整的报文从计算机A发送给计算机B.一个报文可以被分个成若干个数据报,数据报通过网络层传输**
TCP/IP传输层有两个传输层协议:
* 用户数据报协议(UDP)
* 传输控制协议(TCP)
* 流控制传输协议(SCTP)
*注意:传输单位可以是报文段/用户数据报或者分组*
* 应用层
应用层使用户能够获得网络所提供的服务
*注意: 应用层的通信与传输层的通信一样,都是端到端的。通信单位是报文*
分布式二阶段和三阶段提交协议
1 | 在分布式系统中,为了保证数据的高可用,通常,我们会将数据保留多个副本(replica),这些副本会放置在不同的物理的机器上.为了对用户提供正确的增,删,改,差等语义,我们需要保证这些放置在不同物理机器上的副本是一致的. |
分布式事务
1
2
3分布式事务是指会涉及到操作多个数据库的事务(其实就是将对同一库事务的概念扩大到了对多个库的事务).目的是为了保证分布式系统中的数据一致性.分布式事务处理的关键是必须有一种方法可以知道事务在任何地方所做的所有动作,提交或回滚事务的决定必须产生统一的结果(全部提交或全部回滚)
在分布式系统中,各个节点之间在物理上相互独立,通过网络进行沟通和协调.由于存在事务机制,可以保证每个独立节点上的数据操作可以满足ACID.但是,相互独立的节点之间无法准确的知道其他节点中的事务执行情况.所以从理论上讲,两台机器理论上无法达到一致的状态.如果想让分布式部署的多台机器中的数据保持一致性,那么就要保证在所有节点的数据操作,要不全部都执行,要么全部的都不执行.但是,一台机器在执行本地事务的时候无法知道其他机器中的本地事务的执行结果.所以它也就不知道本次事务到底应该commit还是roolback.所以,常规的解决办法就是引入一个"协调者"的组件来统一调度所有分布式节点的执行.XA规范
1
2
3
4
5
6
7
8
9
10
11
12X/Open组织(即现在的Open Group)定义了分布式事务处理模型.
X/Open DTP模型(1994)包括: 应用程序(AP),事务管理器(TM),资源管理器(RM),通信资源管理器(CRM)四部分.
一般,常见的事务管理器(TM)是交易中间件,常见的资源管理器(RM)是数据库,常见的通信资源管理器(CRM)是消息中间件.
通常把一个数据库内部的事务处理(如对多个表的操作)作为本地事务看待.
数据库的事务处理对象是本地事务,而分布式事务处理的对象是全局事务.
所谓全局事务,是指分布式事务处理环境中,多个数据库可能需要共同完成一个工作,这个工作即是一个全局事务(例如,一个事务中可能更新几个不同的数据库,对数据库的操作发生在系统的各处但必须全部被提交或回滚).此时一个数据库对自己内部所做操作的提交不仅依赖本身操作是否成功,还要依赖与全局事务相关的其它数据库的操作是否成功.如果任一数据库的任一操作失败,则参与此事务的所有数据库所做的所有操作都必须回滚.一般情况下,某一数据库无法知道其它数据库在做什么,因此,在一个DTP环境中,交易中间件是必需的,由它通知和协调相关数据库的提交或回滚.而一个数据库只将其自己所做的操作(可恢复)影射到全局事务中.
XA 就是"X/Open DTP"定义的交易中间件与数据库之间的接口规范(即接口函数),交易中间件用它来通知数据库事务的开始,结束以及提交,回滚等.
XA 接口函数由数据库厂商提供
二阶提交协议和三阶提交协议就是根据这一思想衍生出来的.可以说二阶段提交其实就是实现XA分布式事务的关键(确切地说:两阶段提交主要保证了分布式事务的原子性"即所有结点要么全做要么全不做")2PC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47二阶段提交(Two-phaseCommit)也叫二阶段提交协议(Two-phaseCommit protocol)
二阶段提交是指在计算机网络以及数据库领域内,为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种算法(Algorithm).
在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败.当一个事务跨越多个节点时,为了保持事务的ACID特性,需要引入一个作为"协调者"的组件来统一掌控所有节点(称作参与者)的操作结果,并最终指示这些节点是否要把操作结果进行真正的提交(比如将更新后的数据写入磁盘等等).
因此,二阶段提交的算法思路可以概括为:参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作.
二阶提交协议两个阶段: 准备阶段(投票阶段) 和 提交阶段(执行阶段)
1.准备阶段
事务协调者(事务管理器)给每个参与者(资源管理器)发送Prepare消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务,写本地的redo和undo日志,但不提交,到达一种"万事俱备,只欠东风"的状态
可以进一步将准备阶段分为以下三个步骤:
1.协调者节点向所有参与者节点询问是否可以执行提交操作(vote),并开始等待各参与者节点的响应
2.参与者节点执行询问发起的所有事务操作,并将Undo信息和Redo信息写入日志.(注意:若成功这里其实每个参与者已经执行了事务操作)
3.各参与者节点响应协调者节点发起的询问.如果参与者节点的事务操作实际执行成功,则它返回一个"同意"消息;如果参与者节点的事务操作实际执行失败,则它返回一个"终止"消息
2.提交阶段
如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息,否则,发送提交(Commit)消息.参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源.(注意:必须在最后阶段释放锁资源)
接下来分两种情况分别讨论提交阶段的过程:
1.当协调者节点从所有参与者节点获得的相应消息都为"同意"时
1.协调者节点向所有参与者节点发出"正式提交(commit)"的请求
2.参与者节点正式完成操作,并释放在整个事务期间内占用的资源
3.参与者节点向协调者节点发送"完成"消息
4.协调者节点接收到所有参与者节点反馈的"完成"消息后,完成事务
2.如果任一参与者节点在第一阶段返回的响应消息为"终止",或者 协调者节点在第一阶段的询问超时之前无法获取所有参与者节点的响应消息
1.协调者节点向所有参与者节点发出"回滚操作(rollback)"的请求
2.参与者节点利用之前写入的Undo信息执行回滚,并释放在整个事务期间内占用的资源
3.参与者节点向协调者节点发送"回滚完成"消息
4.协调者节点接收到所有参与者节点反馈的"回滚完成"消息后,取消事务
不管最后结果如何,第二阶段都会结束当前事务
二阶段提交看起来确实能够提供原子性的操作,但是不幸的事,二阶段提交还是有几个缺点的:
1.同步阻塞问题
执行过程中,所有参与节点都是事务阻塞型的.当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态
2.单点故障
由于协调者的重要性,一旦协调者发生故障,参与者会一直阻塞下去.尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)
3.数据不一致
在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这会导致只有一部分参与者接受到了commit请求.而在这部分参与者接到commit请求之后就会执行commit操作,但是其他部分未接到commit请求的机器则无法执行事务提交.于是整个分布式系统便出现了数据不一致性的现象
4.二阶段无法解决的问题
协调者再发出commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了.那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交
由于二阶段提交存在着诸如同步阻塞,单点问题,脑裂等缺陷,所以,研究者们在二阶段提交的基础上做了改进,提出了三阶段提交.3PC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52三阶段提交(Three-phase commit),也叫三阶段提交协议(Three-phase commit protocol),是二阶段提交(2PC)的改进版
与两阶段提交不同的是,三阶段提交有两个改动点:
1.引入超时机制.同时在协调者和参与者中都引入超时机制
2.在第一阶段和第二阶段中插入一个准备阶段.保证了在最后提交阶段之前各参与节点的状态是一致的
也就是说,除了引入超时机制之外,3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有CanCommit,PreCommit,DoCommit三个阶段
1.CanCommit阶段
3PC的CanCommit阶段其实和2PC的准备阶段很像.协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应
1.事务询问
协调者向参与者发送CanCommit请求.询问是否可以执行事务提交操作.然后开始等待参与者的响应
2.响应反馈
参与者接到CanCommit请求之后,正常情况下,如果其自身认为可以顺利执行事务,则返回Yes响应,并进入预备状态.否则反馈No
2.PreCommit阶段
协调者根据参与者的反应情况来决定是否可以执行事务的PreCommit操作.根据响应情况,有以下两种可能:
1.假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务的预执行
1.发送预提交请求
协调者向参与者发送PreCommit请求,并进入Prepared阶段
2.事务预提交
参与者接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中
3.响应反馈
如果参与者成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令
2.假如有任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断
1.发送中断请求
协调者向所有参与者发送abort请求
2.中断事务
参与者收到来自协调者的abort请求之后(或超时之后,仍未收到协调者的请求)执行事务的中断
3.doCommit阶段
该阶段进行真正的事务提交,也可以分为以下两种情况:
1.执行提交
协调者接收到参与者发送的ACK响应
1.发送提交请求
协调接收到参与者发送的ACK响应,那么他将从预提交状态进入到提交状态.并向所有参与者发送doCommit请求
2.事务提交
参与者接收到doCommit请求之后,执行正式的事务提交.并在完成事务提交之后释放所有事务资源
3.响应反馈
事务提交完之后,向协调者发送Ack响应
4.完成事务
协调者接收到所有参与者的ack响应之后,完成事务
2.中断事务
协调者没有接收到参与者发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务
1.发送中断请求
协调者向所有参与者发送abort请求
2.事务回滚
参与者接收到abort请求之后,利用其在阶段二记录的undo信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源
3.反馈结果
参与者完成事务回滚之后,向协调者发送ACK消息
4.中断事务
协调者接收到参与者反馈的ACK消息之后,执行事务的中断
注意: 在doCommit阶段,如果参与者无法及时接收到来自协调者的doCommit或者rebort请求时,会在等待超时之后,继续进行事务的提交(其实这个应该是基于概率来决定的,当进入第三阶段时,说明参与者在第二阶段已经收到了PreCommit请求,那么协调者产生PreCommit请求的前提条件是它在第二阶段开始之前,收到所有参与者的CanCommit响应都是Yes.一旦参与者收到了PreCommit,意味他知道大家其实都同意修改了.所以,当进入第三阶段时,由于网络超时等原因,虽然参与者没有收到commit或者abort响应,但是他有理由相信:成功提交的几率很大)2PC与3PC区别
1
2
3相对于2PC,3PC主要解决的单点故障问题,并减少阻塞,因为一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit.而不会一直持有事务资源并处于阻塞状态.但是这种机制也会导致数据一致性问题,因为,由于网络原因,协调者发送的abort响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作.这样就和其他接到abort命令并执行回滚的参与者之间存在数据不一致的情况.
了解了2PC和3PC之后,我们可以发现,无论是二阶段提交还是三阶段提交都无法彻底解决分布式的一致性问题一阶段提交
1
2
3不像两阶段提交那样复杂,一阶段提交非常直白,就是从应用程序向数据库发出提交请求,到数据库完成提交或回滚之后,将结果返回给应用程序的过程.
一阶段提交不需要"协调者"角色,各节点之间不存在协调操作,因此其事务执行时间比两阶段提交要短,但是提交的"危险期"是每一个事务的实际提交时间.
相比于两阶段提交,一阶段提交出现在"不一致"的概率就变大了.但是我们必须注意到:只有当基础设施出现问题的时候(如网络中断,宕机等),一阶段提交才可能会出现"不一致"的情况,相比它的性能优势,很多团队都会选择这一方案
What is ACID
ACID是什么?
1 | ACID,指数据库事务正确执行的四个基本要素的缩写.包含:原子性(Atomicity),一致性(Consistency),隔离性(Isolation),持久性(Durability) |
1 | 数据库执行的5种状态: |
zookeeper zab protocol
ZAB 协议概述:
1
2
3
4
51.ZAB(ZooKeeper Atomic Broadcast,原子消息广播协议)协议是为分布式协调服务ZooKeeper专门设计的一种支持漰溃恢复的原子广播协议
2.ZAB在Paxos算法基础上进行了扩展改进而来,支持崩溃恢复
3.ZooKeeper实现了一种主备模式的系统架构来保持集群中各副本之间数据的一致性
具体,ZooKeeper使用一个单一的主进程来接收并处理客户端的所有事务请求,并采用ZAB的原子广播协议,将服务器的状态变更以事务Proposal的形式广播到所有的副本进程上去.ZAB协议的这个主备模型架构保证了同一时刻集群中只能够有一个主进程来广播服务器的状态变更,因此能够很好地处理客户端大量并发请求
所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器称为Leader服务器,而余下的其他服务器则成为Follower服务器.Leader服务器负责将一个客户端事务请求转换成一个事务Proposal(提议),并将该Proposal分发给集群中所有的Follower服务器.之后Leader服务器需要等待所有Follower服务器的反馈,一旦超过半数(>=N/2+1)的Follower服务器进行了正确反馈后,那么Leader就会再次向所有的Follower服务器分发Commit消息,要求其将前一个Proposal进行提交.ZAB 协议
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25ZAB协议的两种基本模式: 崩溃恢复模式和消息广播模式
1.崩溃恢复模式
ZAB协议会让ZK集群进入崩溃恢复模式的情况:
1.当服务框架在启动过程中
2.当Leader服务器出现网络中断,崩溃退出与重启等异常情况
3.当集群中已经不存在过半的服务器与Leader服务器保持正常通信
ZAB协议进入恢复崩溃模式会做什么事情?
1.当Leader出现问题,则进入恢复模式并选举出新的Leader服务器.当选举出新的Leader服务器,同时集群中已经有过半的机器与该Leader服务器完成状态同步(数据同步),退出崩溃恢复模式.进入消息广播模式
2.当新加入一台机器到集群中,如果此时集群已经存在一个Leader服务器在负责进行消息广播,那么新加入的服务器就会自觉地进入数据恢复模式.找到Leader服务器,并与其进行数据同步,然后进入消息广播模式,一起参与到消息广播流程中去
2.消息广播模式
针对客户端事务请求,Leader服务器会为其生成对应的事务proposal,并将其发送给集群中其余所有的机器,然后分别收集各自的选票,最后进行事务提交
1.ZAB协议消息广播使用的是一个原子广播协议,类似于二阶段提交协议.与二阶段提交协议不同的是,ZAB在提交过程中移除了中断逻辑
2.ZAB协议在有过半的Follower服务器已经反馈Ack之后就开始提交Proposal了,而不需要等待集群中所有Follower服务器都反馈响应
3.关于ZAB在Leader出现单点宕机如何保证事务提交,保证数据一致性,则引入崩溃恢复模式来解决这个问题
4.ZAB的消息广播协议是基于具有FIFO(先进先出)特性的TCP协议来进行网络通信,保证消息广播过程中消息的接收与发送的顺序性
在整个消息广播过程中,Leader服务器会为每一个事务请求处理,步骤如下:
1.Leader服务器会为事务请求生成一个全局的的递增事务ID(即ZXID),保证每个消息的因果关系的顺序
2.Leader服务器会为该事务生成对应的Proposal,进行广播
3.Leader服务器会为每一个Follower服务器都各自分配一个单独的队列,让将需要广播的事务Proposal依次放入这些队列中去,并根据FIFO策略进行消息发送
4.每一个Follower服务器在接收到这个事务Proposal之后,首先以日志形式写入本地磁盘,并且成功写入后反馈给Leader服务器一个Ack响应
5.当Leader服务器接收超过半数的Follower的Ack响应,Leader自身也会完成对事务的提交.同时就会广播一个Commit消息给所有的Follower服务器以通知进行事务提交.每一个Follower服务器在接收到Commit消息后,也会完成对事务的提交ZAB的崩溃恢复
1
2
3基本特性,确保当Leader出现单点问题,在新选举出Leader后,保证数据一致性
1.ZAB协议需要确保那些已经在Leader服务器上提交的事务最终被所有服务器都提交
2.ZAB协议需要确保丢弃那些只在Leader服务器上被提出的事务ZAB的Leader选举算法
1
2
3
4
51.旧Leader宕机后,选举新Leader中,旧的Leader重启后不可能再次成为这次选举的新Leader
2.旧Leader宕机后,在剩下的Follower服务器选取新Leader的标准,一定是事务ID最大的那个Follower成为新Leader(即数据同步最新的那台Follower服务器)
3.事务ID(ZXID)是64位的数字.其中低32位可以看作是一个简单的单调递增的计数器,高32位则代表一个Leader从生到死的epoch编号
4.新Leader选举出来,从事务proposal中分析出旧Leader的epoch编号,并递增1,作为新的事务ID的高32位,然后新事务ID的低32位从0位重新开始计数
5.新Leader通过事务ID和所有的Follower机器上的事务ID进行对比,确保数据同步.保证数据在所有的Follower上与之达成同步.旧Leader上新被提交的事务被抛弃.当数据达到同步,才将Follower服务器加入可用的Follower服务器列表.然后开始消息广播ZAB协议和Paxos算法两者关系
1
2
3
4
5
6
7
8
9
10
11
121.两者都存在一个类似于Leader进程都角色,由其负责协调多个Follower进程运行
2.Leader进程都会等待超过半数都Follower做出正确都反馈后,才会将以更提案进行提交
3.在ZAB协议中,每个Proposal中都包含一个epoch值,用来代表当前leader周期;在Paxos算法中,同样存在这样一个标识ballot
在paxos算法中,一个新选举产生都主进程会进行两个阶段都工作:
第一个阶段被称为读阶段,在这个阶段中,这个新的主进程会通过和所有其他进程进行通信都方式来收集上一个主进程提出的提案,并将他们提交.
第二个阶段被称为写阶段,在这个阶段中,当前主进程开始提出它自己都提案.
在paxos算法设计都基础上,ZAB协议额外添加了一个同步阶段,在同步阶段中,新都leader会确保存在过半都Follower已经提交了之前leader周期中都所有事务proposal.这一同步阶段都引入,能够有效地保证leader在新都周期中提出事务proposal之前,所有都进程都已经完成了对之前所有事务的提交.一旦完成同步阶段后,那么ZAB就会执行和paxos算法类似的写阶段
总之,ZAB协议和Paxos算法本质区别在于,两者的设计目标不太一样:
ZAB协议主要用于构建一个高可用的分布式数据主备系统
Paxos算法主要用于构建一个分布式一致性状态机系统
zabbix proxy install
zabbix-proxy yum source
1
2
3[root@localhost ~]# hostname zabbixproxy
[root@localhost ~]# echo zabbixproxy| tee /etc/hostname
[root@zabbixproxy ~]# rpm -ivh http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/zabbix-release-3.2-1.el7.noarch.rpmzabbix-proxy install mysql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21[root@zabbixproxy ~]# yum -y install mariadb-server mariadb
[root@zabbixproxy ~]# cat > /etc/my.cnf <<EOF
> [mysqld]
> character-set-server=utf8
> datadir=/mnt/data/mysql
> socket=/mnt/data/mysql/mysql.sock
> symbolic-links=0
> [mysqld_safe]
> log-error=/var/log/mariadb/mariadb.log
> pid-file=/var/run/mariadb/mariadb.pid
> !includedir /etc/my.cnf.d
> [mysql]
> socket=/mnt/data/mysql/mysql.sock
> [client]
> default-character-set=utf8
> socket=/mnt/data/mysql/mysql.sock
> EOF
[root@zabbixproxy ~]# mkdir -p /mnt/data/mysql
[root@zabbixproxy ~]# chown -R mysql.mysql /mnt/data/mysql
[root@zabbixproxy ~]# systemctl start mariadb
[root@zabbixproxy ~]# systemctl enable mariadbzabbix-proxy install
1
2[root@zabbixproxy ~]# yum -y install zabbix-proxy-mysql
[root@zabbixproxy ~]# yum -y install zabbix-get zabbix-java-gateway zabbix-senderzabbix-proxy mysql configuration
1
2
3
4
5[root@zabbixproxy ~]# mysql
MariaDB [(none)]> create database zabbix_proxy character set utf8 collate utf8_bin;
MariaDB [(none)]> grant all privileges on zabbix_proxy.* to zabbix@'localhost' identified by 'zabbixproxy';
MariaDB [(none)]> flush privileges;
[root@zabbixproxy ~]# zcat /usr/share/doc/zabbix-proxy-mysql-3.2.3/schema.sql.gz | mysql -uzabbix -pzabbixproxy -hlocalhost -B zabbix_proxyzabbix-proxy configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42[root@zabbixproxy ~]# vim /etc/zabbix/zabbix_proxy.conf
ProxyMode=0
Server=192.168.13.202
ServerPort=10051
Hostname=zabbix-proxy-company
HostnameItem=system.hostname
ListenPort=10051
LogFile=/var/log/zabbix/zabbix_proxy.log
LogFileSize=512
DebugLevel=3
PidFile=/var/run/zabbix/zabbix_proxy.pid
DBHost=192.168.13.204
DBName=zabbix_proxy
DBUser=zabbix
DBPassword=xxxxxxxxxxxx
DBSocket=/mnt/data/mysql/mysql.sock
DBPort=3306
ProxyLocalBuffer=48
ProxyOfflineBuffer=24
HeartbeatFrequency=60
ConfigFrequency=600
DataSenderFrequency=1
StartPollers=15
StartTrappers=10
StartPingers=10
StartDiscoverers=10
StartHTTPPollers=5
SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
CacheSize=512M
StartDBSyncers=8
HistoryCacheSize=2048M
HistoryIndexCacheSize=128M
Timeout=4
TrapperTimeout=300
UnreachablePeriod=45
UnavailableDelay=60
UnreachableDelay=15
ExternalScripts=/etc/zabbix/zabbix_exec
FpingLocation=/usr/sbin/fping
LogSlowQueries=3000
User=zabbix
Include=/etc/zabbix/zabbix_proxy.d/*.confzabbix-proxy start
1
2[root@zabbixproxy ~]# systemctl start zabbix-proxy
[root@zabbixproxy ~]# systemctl enable zabbix-proxyzabbix-server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16open: http://zabbix-server
open: Administration -> Proxies -> Create proxy
Proxy name = zabbixproxy($hostname)
Proxy mode = active(主动)
Add(添加)
open: Configuration -> Hosts -> Create host
host:
Host name=zabbix-proxy-company($hostname)
Visible name=192.168.13.204($zabbix-proxy-ip)
New group=zabbix proxy
Agent interfaces=($zabbix-proxy-ip:port)
Monitored by proxy=zabbixproxy(Proxy name)
Template:
Link new templates(添加模板)
zabbix monitor cpu
zabbix monitor cpu
1 | 系统监控:(CPU) |
zabbix install
zabbix install
zabbix yum source
1
2
3
4
5[root@localhost ~]# hostname zabbixserver
[root@localhost ~]# echo zabbixserver| tee /etc/hostname
[root@localhost ~]# rpm -ivh http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/zabbix-release-3.2-1.el7.noarch.rpm
[root@localhost ~]# rpm -ivh http://repo.zabbix.com/zabbix/3.2/rhel/6/x86_64/zabbix-release-3.2-1.el6.noarch.rpmzabbix-server mysql install
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23[root@zabbixserver ~]# yum -y install mariadb-server mariadb
[root@zabbixserver ~]# cat > /etc/my.cnf <<EOF
> [mysqld]
> character-set-server=utf8
> datadir=/mnt/data/mysql
> socket=/mnt/data/mysql/mysql.sock
> symbolic-links=0
> [mysqld_safe]
> log-error=/var/log/mariadb/mariadb.log
> pid-file=/var/run/mariadb/mariadb.pid
> !includedir /etc/my.cnf.d
> [mysql]
> socket=/mnt/data/mysql/mysql.sock
> [client]
> default-character-set=utf8
> socket=/mnt/data/mysql/mysql.sock
> EOF
[root@101 ~]# mkdir -p /mnt/data/mysql
[root@101 ~]# chown -R mysql.mysql /mnt/data/mysql
[root@101 ~]# systemctl start mariadb
[root@101 ~]# systemctl enable mariadbzabbix-server install
1
2[root@101 ~]# yum -y install zabbix-server-mysql zabbix-web-mysql httpd
[root@101 ~]# yum -y install zabbix-java-gateway zabbix-sender zabbix-getzabbix-server mysql set
1
2
3
4[root@101 ~]# mysql
MariaDB [(none)]> create database zabbix character set utf8 collate utf8_bin;
MariaDB [(none)]> grant all privileges on zabbix.* to zabbix@10.0.1.89 identified by 'UPCLfTHSj72a';
[root@101 ~]# zcat /usr/share/doc/zabbix-server-mysql-3.2.3/create.sql.gz | mysql -uzabbix -pUPCLfTHSj72a -h10.0.1.89 -B zabbixzabbix-server configuration
1
2
3
4
5[root@101 ~]# vim /etc/zabbix/zabbix_server.conf
DBHost=10.0.1.89
DBName=zabbix
DBUser=zabbix
DBPassword=UPCLfTHSj72azabbix-server start
1
2[root@101 ~]# systemctl start zabbix-server
[root@101 ~]# systemctl enable zabbix-serverhttpd zabbix.conf configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34[root@101 ~]# vim /etc/httpd/conf.d/zabbix.conf
Alias /zabbix /usr/share/zabbix
<Directory "/usr/share/zabbix">
Options FollowSymLinks
AllowOverride None
Require all granted
<IfModule mod_php5.c>
php_value max_execution_time 300
php_value memory_limit 1024M
php_value post_max_size 32M
php_value upload_max_filesize 20M
php_value max_input_time 300
php_value always_populate_raw_post_data -1
php_value date.timezone Asia/Shanghai
</IfModule>
</Directory>
<Directory "/usr/share/zabbix/conf">
Require all denied
</Directory>
<Directory "/usr/share/zabbix/app">
Require all denied
</Directory>
<Directory "/usr/share/zabbix/include">
Require all denied
</Directory>
<Directory "/usr/share/zabbix/local">
Require all denied
</Directory>httpd start
1
[root@101 ~]# systemctl restart httpd
打开浏览器,配置zabbix-server
1
http://{IP}:80/zabbix 用户名/密码: Admin/zabbix
zabbix-server nginx反向代理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18[root@192 vhost]# cat zabbix.conf
# zabbix
server {
listen 80;
server_name zabbix.domain.cn;
location / {
rewrite ^/ http://zabbix.domain.cn/zabbix/;
}
location /zabbix {
proxy_pass http://192.168.13.202;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
access_log /mnt/log/nginx/zabbix.domain.cn.log main;
}zabbix-agent install
1
[root@59 ~]# yum -y install zabbix-agent zabbix-sender
zabbix-agent configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24[root@59 ~]# cp /etc/zabbix/{zabbix_agentd.conf,abbix_agentd.conf.bak}
[root@59 ~]# cat > /etc/zabbix/zabbix_agentd.conf <<EOF
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=20
DebugLevel=3
SourceIP=10.0.1.90
EnableRemoteCommands=1
LogRemoteCommands=1
Server=10.0.1.89
ListenPort=10050
StartAgents=5
ServerActive=10.0.1.89
Hostname=10.0.1.90
HostMetadataItem=system.uname
RefreshActiveChecks=120
BufferSend=5
BufferSize=200
MaxLinesPerSecond=100
Timeout=10
AllowRoot=0
Include=/etc/zabbix/zabbix_agentd.d/*.conf
UnsafeUserParameters=1
EOFzabbix-agent start
1
2[root@59 ~]# systemctl start zabbix-agent
[root@59 ~]# systemctl enable zabbix-agentzabbix-aget iptables
1
2
3
4
5
6
7[root@59 ~]# iptables -I INPUT -p tcp -m tcp --dport 10050 -m comment --comment "zabbix_agentd listen " -j ACCEPT
or:
[root@59 ~]# /etc/init.d/iptables status
[root@59 ~]# iptables -I INPUT 3 -s 192.168.13.204/32 -j ACCEPT
[root@59 ~]# iptables -I INPUT 5 -s 192.168.13.204/32 -p tcp -m tcp --dport 22 -j ACCEPT
[root@59 ~]# iptables -I INPUT 5 -s 192.168.13.204/32 -p tcp -m tcp --dport 10050 -j ACCEPT
[root@59 ~]# /etc/init.d/iptables save