zookeeper简介:
在分布式环境中,多个服务之间协调一致。有提供分布式锁、服务配置。实现分布式领域CAP(consistency一致性,Availiablity高可用,patition tolrenance 分区容错性)原理中的CP。
问题一:为何zookeeper要有leader?
zookeeper是以Fast Paxos算法为基础,paxos算法存在活锁的问题,即当有多个proposer交错提交时,有可能互相排斥导致没有一个proposer能提交成功,而Fase Paxos作了一些优化,通过选举产生一个leader,只有leader才能提交proposer,具体的可以看一下Fast Paxos算法
zookeeper协调一致原理paxos算法:
在分布式系统只发生几起宕机或网络异常情况下,在集群内部对某个数据达成一致(proposer和accepter和learner都认为某个value被选定),并且保证不论发生上述任何异常,都不会整个系统的一致性。
在paxos算法中,分为以下角色:
proposer:提议者
accepter:决策者
learners:最终决策学习者
提议者想决策者提出方案,决策者会根据zookeeper的权重(时间约后启动,权重越大)选择leader,如果过半的决策者同意则产生主节点。
选举状态:
looking:竞选状态
following:随从状态,参与投票
observing:观察状态,不参与投票
leading:领导中
选举流程:
假设有5台机器,分别A,B,C,D,E。 注:zookeeper启动的时候,会读集群的配置Ip
1.A启动,当前没有leader,给自己投票,其他机器没有启动,收不到反馈信息,处于LOOKING
2.B启动,当前没有leader,给自己投票,B发消息给其他机器,A接受到了来自B的投票,B比自己服务号大,接受投票,支持B当选,B接收到A 小于或等于自己的投票,支持A投自己。所以2:1,但是没有超过一半;following状态
3.C启动,当前没有leader,给自己投票,广播给A和B,A和B收到比自己大的服务号,支持C当选并且A清空支持B的投票,此时比分为A:B:C=1:1:3,超过一半,C胜出,成为LEADER,状态为leading
4.D启动,已经有leader了,同步leader状态,不参与投票,observing状态
zookeeper弱点--脑裂:
zookeeper之间是通过心跳检测来确认节点是否可用,在网络延迟的情况下,会出现假死情况。假设A,B,C,D,E,F,E七个节点,C为主节点。现在C假死了,A,B可用连C,D,E,F都连不上C,D,E,F会通知集群所有可用的zk(master挂掉了,超过半数都连不上C,我们要重新选举),从而F会成为新的主节点。F去通知client主节点切换了,但是会有网络延迟。此时有两部分client,一部分连接新master,一部分连接老大master,如果此时client要更新同一份数据进行更新,就无法保持一致性了。
eureka(希腊语,词义:我找到啦,我发现了)
特点:
1.如果某台服务器宕机了,不会有选举过程,客户端会自动切换到其他eureka,如果故障服务器回复后,又将重新纳入集群,并同步新的服务注册信息。当网络故障,每个eruka吃持续对外提供服务,zookeeper要先选举,只有master对外提供服务
2.eureka当机器心跳异常,会进入自我保护模式,延长注册服务过期时间,就是好数据和坏数据都留着总比丢掉好数据强,等网络恢复后再推出保护模式
部署:
1.下载war包:
http://search.maven.org/#search%7Cga%7C1%7Ceureka-server
2.git下载源码编译:
https://github.com/Netflix/eureka
3.自己建spring-boot项目:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath />
</parent>
<artifactId>luochaoqun-spring-cloud-eureka</artifactId>
<properties>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
package com.main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
*@author:luo.cq
*@email:lcqjava@sina.cn
*@since:2018年5月30日
*@description:
*
**/
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
配置项application.properties:
server.port=9000
eureka.instance.hostname=localhost
#don't regist self
eureka.client.register-with-eureka=false
#jinzhi jiansuo fuwu
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka
界面: