zookeeper入门

应用场景

分布式锁:可以做到强一致性

无状态化的实现:数据存在zookeeper中

数据结构

zk的节点znode包含了4个部分

        data,保存的数据

        acl,权限

        stat,描述当前节点的元数据

        child,子节点

znode的类型

        持久节点:create /test 创建出持久化的节点,会话结束后依旧存在

        持久序号节点:创建出的节点根据先后顺序会在节点后面加一个数值,越靠后越大,( create -s /test)

        适用 分布式锁

临时节点:会话结束后,节点会被自动删除(create -e /test)

适用服务的注册与发现

 手动退出直接触发会话删除,其他情况客户端会话断开,临时节点会超时删除、

        临时序号节点:适用于做临时分布式锁 (create -e - s /test)

        Container节点:当容器节点没有任何子节点的时候就会定期删除(默认为60s) (create -c /myContainer)

        TTL节点:可以给节点设置到期时间,到期后被定时删除

持久化机制

zk是运行在内存中的,提供两种持久化机制

        1.事务日志

                zk把执行的命令以日志形式记录在dataLogDir指定的路径中

        2.数据快照

                zk在一定的时间间隔做一次内存数据的快照,把此事的内存数据保存在快照文件中

在数据恢复的时候先恢复快照文件中的数据,然后根据日志文件中的数据做增量恢复

zkCli命令的使用

创建

        create

        create -s

        create -e

        create -e -s

        create -c

        create -t TTL

查询

        ls

        递归查询ls -R

        获得节点数据 get

        获取节点详细信息 get - s

删除

        delete /test(删除当前节点)

        deleteAll /test (删除这个节点,以及所有子节点)

        delete -v number /test (如果test的版本号和number相同就能删除,乐观锁)

权限       

Curator客户端

引入依赖

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.7.2</version>
        </dependency>
        <!--zookeeper-client-curator-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.12.0</version>
        </dependency>

加入配置

curator.retryCount=5
curator.elapsedTimeMs=5000
curator.connectString=192.168.88.130:2181
curator.sessionTimeoutMs=6000
curator.connectionTimeoutMs=5000

注册bean接收请求

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "curator")
public class WrapperZK {

    private int retryCount;

    private int elapsedTimeMs;

    private String connectString;

    private int SessionTimeoutMs;

    private int connectionTimeoutMs;
}

注册Curator

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryNTimes;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

@Configuration
public class CuratorConfig {
    @Resource
    private WrapperZK wrapperZK;

    @Bean(initMethod = "start")
    public CuratorFramework getCuratorFramework() {
        return CuratorFrameworkFactory.newClient(
                wrapperZK.getConnectString(),
                wrapperZK.getSessionTimeoutMs(),
                wrapperZK.getConnectionTimeoutMs(),
                new RetryNTimes(wrapperZK.getRetryCount(), wrapperZK.getElapsedTimeMs()));
    }

}

zk的分布式锁

读锁:前提之前没有写锁

写锁:前提之前没有任何锁

羊群效应:所有的节点都监听获取锁的那个节点,当节点释放锁,就会触发其他所有节点去抢占锁

链式监听:因为所有的节点都有序号,所以可以采用链式监听,按照顺序获取锁,这样占有锁的节点只被一个节点监听,当释放锁的时候不会触发大量的抢锁,减少了CPU资源的消耗;

zk的Watch机制

客户端功能,能够监听znode的变化:当znode发生create,delete、setData时,客户端就会接收到异步通知

原理:服务端会维护一个哈希表,当有事件监听的时候,znode对应的节点就会插入watch的客户端列表,

当发生事件的时候,就会获取节点的watch列表进行通知

命令:

get -w /node 监听节点

get -w -R /node 监听节点及所有子节点

ls -w /node 监听目录中下一级子节点是否发生变化

ls -R -w /node 监听所有层级子节点

zk的集群

zk集群中有三种角色:

        leader:处理集群中的所有事务请求(可写可读),一个集群只能由一个leader

        follower:只能处理读请求,能参与leader的选举

        Observer:只能处理读请求,不能参与leader的选举

ZAB协议

        ZAB协议用来解决崩溃恢复和主从同步的问题

        ZAB协议定义了四种节点状态:looking:选举状态 leading:主节点状态 followin :从节点状态 observering观察者状态

内部选举

        在分布式系统中选主最直接的方法是直接选定集群的一个节点为leader,其它的节点为follower,这样引入的一个问题是如果leader节点挂掉,整个集群就挂掉了。需要有一种算法自动选主,如果leader节点挂掉,则从follower节点中选出一个主节点。

1. 选举阶段 Leader election

最大ZXID也就是节点本地的最新事务编号,包含epoch和计数两部分。epoch是纪元的意思,相当于Raft算法选主时候的term,标识当前leader周期,每次选举一个新的Leader服务器后,会生成一个新的epoch

  • 所有节点处于Looking状态,各自依次发起投票,投票包含自己的服务器ID和最新事务ID(ZXID)。
  • 如果发现别人的ZXID比自己大,也就是数据比自己新,那么就重新发起投票,投票给目前已知最大的ZXID所属节点。
  • 每次投票后,服务器都会统计投票数量,判断是否有某个节点得到半数以上的投票。如果存在这样的节点,该节点将会成为准Leader,状态变为Leading。其他节点的状态变为Following。

2. 发现阶段 Discovery

  • 为了防止某些意外情况,比如因网络原因在上一阶段产生多个Leader的情况。
  • Leader集思广益,接收所有Follower发来各自的最新epoch值。Leader从中选出最大的epoch,基于此值加1,生成新的epoch分发给各个Follower。
  • 各个Follower收到全新的epoch后,返回ACK给Leader,带上各自最大的ZXID和历史事务日志。Leader选出最大的ZXID,并更新自身历史日志。

3. 同步阶段 Synchronization

Leader刚才收集得到的最新历史事务日志,同步给集群中所有的Follower。只有当半数Follower同步成功,这个准Leader才能成为正式的Leader

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值