分布式环境的特点
分布式、并发性、无序性
分布式环境下面临的问题
网络通信不可靠、网络分区(脑裂)、三态
中心化和去中心化
冷备或热备、无领导
分布式架构里面,很多的架构思想采用的是:当集群发生故障的时候,集群中的人群会自动“选举”出一个新的领导。
最典型的是:zookeeper /etcd
经典的CAP/BASE理论
cap
c(一致性)、a(可用性)、p(分区容错),在分布式架构里,没有办法同时满足一致性、可用性、分区容错,只能同时满足两个。
一致性:所有节点上的数据,时刻保持一致。
可用性:每个请求都能够收到一个响应,无论响应成功或者失败。
分区容错:当系统出现脑裂的时候,可能导致某些server与集群中的其他机器失去联系。
cap理论只适用于原子读写的Nosql场景,不适用于数据库。CP/AP。
base
基于cap理论,cap理论并不适用与数据库事务(因为更新错误的数据而导致数据出现紊乱,无论什么样的数据库高可用方案都是徒劳),XA事务虽然可以保证数据库分布式系统下的ACID特性,但是会带来性能方面的影响。
eBay尝试了一种完全不同的套路,放宽了对事务ACID的要求,提出了BASE理论。
Basically available:数据库采用分片模式,把100万的用户数据拆分在5个实例上。如果破坏了其中一个实例,仍然可以保证80%的用户可用。
soft-state:在基于client-server模式的系统中,server端是否有状态,决定了系统是否具备良好的水平拓展、负载均衡等特性。Server端承诺会维护client端状态数据,这个状态仅仅维持一段时间。这段时间以后,server端就会丢弃这个状态,恢复正常状态。
eventually consistent:数据的最终一致性。
初步认识zookeeper
zookeeper是一个开源的分布式协调服务,是雅虎创建的,基于google chubby。
zookeeper是什么
zookeeper能做什么
数据发布/订阅(配置中心:disconf)、负载均衡(dubbo 利用了zookeeper 机制实现了负载均衡)、命名服务、master选举(kafka、hadoop、hbase)、分布式队列…
zookeeper特性
顺序一致性:从同一个客户端发起事务请求,最终会严格按照顺序被应用到zookeeper中
原子性:所有的事务请求的处理结果在整个集群中的所有机器上的应用情况是一致的,也就是说,要么整个机群中的所有机器都成功应用了某个服务、要么全部不成功。
可靠性:一旦服务器成功应用了某个服务数据,并且对客户端做了响应,那么这个数据在整个集群中一定是同步并且保留下来的。
实时性:一旦一个服务被成功应用,客户端就能够立即从服务器端读取到事务变更后的最新状态;(zookeeper仅仅保证在一定时间内,近实时)
zookeeper 安装
单机环境
集群环境
zookeeper 集群,包含三种角色:leader 领导/ follower 追随者 / obserer 观察者
leader:接收所有follower的提案请求并统一协调发起投票,并与所有的follower进行内部的数据交换(同步)
follower:直接为客户端服务并参与提案的投票,同时与leader进行数据交换(同步)
observer:直接为客户端服务但并不参与提案的投票,同时也与leader进行数据交换(同步)
Zookeeper 配置集群
server.1=ip:2888:3181
server.2=ip:2888:3181
server.3=ip:2888:3181
id的取值范围:1~255;用id来标识该机器在集群中的机器序号
2888是follower节点与leader节点交换信息的端口号
3181是如果leader节点挂掉了,需要一个端口号来重新选举
创建myid
在每一个服务器的dataDir目录下创建一个myid的文件,文件就一行数据,数据的内容是每台机器对应的server ID的数据
cd temp
mkdir zookeeper
ls
cd zookeeper
ls
vim myid
文本内容:serverId
重启zookeeper
如果启动失败,检查下防火墙是否关闭
###关闭防火墙
systemctl stop firewalld
###杀死zookeeper进程
ps -ef|grep zookeeper
kill -9
observer
observer是一个特殊的zookeeper节点,可以帮助解决 zookeeper的拓展性(如果大量的客户端访问我们zookeeper集群,需要添加zookeeper集群机器数量。从而增加zookeeper集群的性能。导致zookeeper写性能下降,zookeeper的数据变更需要半数以上的服务器投票通过。造成网络消耗添加投票成本)
1.observer不参与投票。只接收投票结果。
2.不属于zookeeper的关键部位。
配置observer节点,提高集群的性能
###指定这台zookeeper为observer节点
peerType=observer
server.1=192.168.0.100:2888.3181
server.2=192.168.0.103:2888.3181
server.3=192.168.0.104:2888.3181:observer
对于客户端来说提高读的性能,对于zookeeper集群来说,提高写的性能
集群ip节点配置
192.168.0.100 Leader
192.168.0.103 Follower
192.168.0.104 Follower
# Zookeeper 中最小的时间单位
tickTime=2000
# follower节点启动后,与leader节点完成数据同步的时间
initLimit=10
# 用来leader节点和followere进行心跳检测的最大延迟时间
syncLimit=5
# 数据快照文件的目录
dataDir=/tmp/zookeeper
# zookeeper事务日志,默认在dataDir目录下
dataLogDir=
# 客户端和服务端建立连接的端口号
clientPort=2181
zookeeper中的一些概念
数据结构
zookeeper 的数据模型和系统类似,每个节点成为:znode. 是zookeeper种最小的数据单元。每一个znode上都可以保存和挂载子节点,从而构成一个层次化的属性结构。
持久化节点:节点创建后会一直存在zookeeper服务器上,知道主动删除
持久化有序节点:每个节点都会为它的一段子节点维护一个顺序
临时节点:临时节点的生命周期和客户端保持一致,当客户端会话失效,该节点自动清理
临时有序节点:在临时节点上多了一个有序特性
会话
Watcher
zookeeper 提供分布式数据发布/订阅,zookeeper 允许客户端向服务器注册一个watcher监听。当服务器端的节点触发指定事件的时候会触发watcher。服务器会向客户端发送一个事件通知。
watcher的通知时一次性的,一旦触发一次通知后,该watcher就失效。
ACL
zookeeper提供控制节点访问权限的功能,用于有效的保证 zookeeper 中数据的安全性。避免误操作而导致系统出现重大故障。
create/read/write/delete/admin
常用命令
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
-s:节点是否有序
-e: 是否是临时节点,默认情况下是持久节点
get [-s] [-w] path
获得指定path信息
set [-s] [-v version] path data
修改节点path对应的version
version 乐观锁
delete [-v version] path
必须先删除所有子节点,再删除父节点
stat 信息
cVersion = 0 子节点的版本号
aclVersion = 0 表示acl的版本号,修改节点权限
dataVersion = 0 表示当前节点的版本号
cZxid 节点被创建时的事务ID
mZxid 节点最后一次被更新的事务ID
pZxid 当前节点下的最后一次被修改时的事务ID
ctime 创建时间
mtime 修改时间
ephemeralOwner = 0x0 创建临时节点的时候,会有一个sessionid。该值存储的就i是这个sessionid
dataLength 数据长度
numChildren 子节点数
java api 的使用
权限控制模式
schema:授权对象
ip: 192.168.1.1
Digest: username,password
world:开放式的权限控制模式,数据节点的访问权限对所有用户开放。world:anyone
super:超级用户,可以对zookeeper 上的数据节点进行操作。
连接状态
KeeperState.Expired 在一定时间内客户端没有收到服务器的通知,则认为当前的会话已经过期了。
KeeperState.Dosconnected 断开连接
KeeperState.SyncConnected 客户端和服务端在某一个节点上建立连接,并完成一次version.Zxid同步
KeeperState.authFailed 授权失败
事件类型
NodeCreated 当节点被创建的时候触发
NodeDeleted 当子节点被创建、删除、子节点数据发生变化
NodeDataChanged 节点发生变化
NodeChildrenChanged 节点被删除
None 客户端和服务器端连接状态发生变化的时候,事件类型就是None
**
zkClient
导入jar包
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.6.1</version>
</dependency>
curator
curator本身是Netfirx 公司开源的zookeeper客户端
curator-framework 提供了fluent风格的api
curator-replice 提供了实现封装
curator链接重试策略
ExponentialBackoffRetry(间隔时间,重试册数) 衰减重试
RetryNTimes 指定最大重试次数
RetryOneTime 仅重试一次
RetryUntilElapsed 一直重试直到指定时间
使用场景
发布订阅/配置中心
发布者可以发布服务到zookeeper节点上,订阅者可以订阅数据,从而达到动态获取数据的能力。
实现配置信息的集中式管理和数据的动态更新。
实现配置中心有两种模式:push(主动推送)、pull(拉取)
push:服务器端主动将更新数据推送订阅的客户端
pull:客户端主动发起请求最新数据
长轮询
zookeeper采用推拉相结合的方式:客户端向服务器端注册自己关心的服务,一旦节点发生变化,服务器端就会向客户端发送watcher事件通知,客户端收到通知后,主动到服务器端获取更新后的数据。客户端启动的时候会在将服务进行本地缓存,提高效率。
特性:配置中心要求
1.数据量小
2.数据内容在运行时会发生动态变更
3.集群的各个机器共享配置
分布式锁
redis:setNx,如果字符串存在,返回0,删除通过Lua脚本删除。
mysql:创建一表,通过唯一索引的方式,insert 一条数据,其他客户端会出现唯一索引的异常,释放锁,删除记录。或者使用悲观锁for update(悲观锁 行锁)。
zookeeper: 临时有序节点watcher特性
排它锁(写锁)、共享锁(读锁)
负载均衡
ID生成器
分布式队列
统一命名服务
Master选举
99.999%可用
master-slave 模式
如果master节点挂掉了,这时候重新选举一个master节点出来,但会出现脑裂问题。
使用zookeeper解决
当master节点挂掉了,我们客户端会去zookeeper争抢注册master节点
LeaderLatch:写一个master
LeaderSelector:每一个应用都写一个临时有序节点,更具最小的节点来获取优先权。