Zookeeper 分布式环境中的注册表

本文涉及的产品
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 03年,作者大二买了第一台计算机。记得那时候2种主题的书特别多,注册表和Bios。现在想想《教你21天玩转Bios》这样的书名都像个笑话儿。这么说是因为BOIS和注册表对普通用户,基本用不上。

03年,作者大二买了第一台计算机。记得那时候2种主题的书特别多,注册表和Bios。现在想想《教你21天玩转Bios》这样的书名都像个笑话儿。

这么说是因为BOIS和注册表对普通用户,基本用不上。但是注册表其实是Windows系统中非常重要的组件,提供了配置存储、事件监听响应等机制,Windows中很多服务开发都需要依赖注册表。

一、Zookeeper提供了分布式环境的注册表服务

ZooKeeper 典型的应用场景,限于篇幅就不详细展开,百度或https://www.jianshu.com/p/1e052bddba80

  • 命名服务
  • 配置管理
  • 集群管理
  • 分布式锁
  • 队列管理

当你了解了这些应用场景,会不会明白作者将zookeeper和注册表对标的想法?

二、Zookeeper Api

1.pom.xml

写作日期为2018.6.17,zookeeper版本为3.4.9。

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.9</version>
            <type>pom</type>
        </dependency>

2.创建zookeeper session

new Zookeeper是一个异步函数,调用之后马上返回。注册一个Watch回调函数,通常在这个函数中确认连接成功。用DownLatch.await等待确认连接成功。

CountDownLatch countDownLatch = new CountDownLatch(1);
ZooKeeper zk = new ZooKeeper("172.18.0.71:2181", 20000,
        new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println("process " + watchedEvent);
                if (watchedEvent.getState() ==
                        Event.KeeperState.SyncConnected) {
                    countDownLatch.countDown();
                }
            }
        });
try {
    countDownLatch.await();
} catch (Exception e) {
    e.printStackTrace();
}

3.创建永久节点

指明节点路径和节点上保存的数据。通常可以用JSON保存更多信息。

/*
  
public String create(final String path, byte data[], List<ACL> acl,
            CreateMode createMode)
*/
try {
    zk.create("/wsn","try creat".getBytes()
    ,ZooDefs.Ids.OPEN_ACL_UNSAFE
    ,CreateMode.PERSISTENT);
} catch (KeeperException e) {
    e.printStackTrace();
} catch (InterruptedException e) {
    e.printStackTrace();
}

4.创建临时节点,在session断开时删除节点

创建临时节点,该节点通常被认为是进程的替身,如果节点被删除,那么原进程已经退出。CreateMode指明节点类型。

try {
    zk.create("/wsn_t","EPHEMERAL".getBytes()
                                ,ZooDefs.Ids.OPEN_ACL_UNSAFE
                                ,CreateMode.EPHEMERAL);
} catch (KeeperException e) {
    e.printStackTrace();
} catch (InterruptedException e) {
    e.printStackTrace();
}

5.获取子节点

List<String> children  = zk.getChildren("/wsn",new MyWatcher());
Iterator<String> iter = children.iterator();
while (iter.hasNext())
{
    System.out.println("path :"+iter.next());
}

6.获取节点信息

ret = zk.getData("/wsn", null,stat);
System.out.println("info:"+new String(ret));
System.out.println(stat);

info:wsn test path
748,748,1534087028795,1534087028795,0,15,0,0,13,5,770

public class Stat implements Record {
  private long czxid;
  private long mzxid;
  private long ctime;
  private long mtime;
  private int version;
  private int cversion;
  private int aversion;
  private long ephemeralOwner;
  private int dataLength;
  private int numChildren;
  private long pzxid;
}

状态属性 说明
cZxid 数据节点创建时的事务ID
ctime 数据节点创建时的时间
mZxid 数据节点最后一次更新时的事务ID
mtime 数据节点最后一次更新时的时间
pZxid 数据节点的子节点列表最后一次被修改(是子节点列表变更,而不是子节点内容变更)时的事务ID
cversion 子节点的版本号
dataVersion 数据节点的版本号
aclVersion 数据节点的ACL版本号
ephemeralOwner 如果节点是临时节点,则表示创建该节点的会话的SessionID;如果节点是持久节点,则该属性值为0
dataLength 数据内容的长度
numChildren 数据节点当前的子节点个数

7.创建监听

getData

Sets data on the node, or deletes the node.设置数据和删除节点

getChildren

deletes the node of the given path or creates/delete a child under the node删除节点(通getData),子节点创建和删除;不响应孙子节点,和更改状态。
注:监听事件只响应一次。响应后需再次注册监听。

    private static class MyWatcher implements Watcher
    {
        @Override
        public void process(WatchedEvent event) {
            System.out.println("getChildren trigger");
            System.out.println("event tpye:"+event.getType());
            System.out.println("event state:"+event.getState());
            System.out.println("event path"+event.getPath());
            try {
                zk.getChildren("/wsn",new MyWatcher()); //再注册
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

为/wsn目录设置一个监听器。

zk.getChildren("/wsn",new MyWatcher());

实验,通过zkCli为/wsn添加一个临时节点。

[zk: localhost:2181(CONNECTED) 1] create -e /wsn/exam 'test'
Created /wsn/exam

getChildren trigger
event tpye:NodeChildrenChanged
event state:SyncConnected
event path/wsn

8.创建序列节点

实验演示,创建序列节点,生成00和01两个节点。

       zk.create("/wsn/seq/no"
                ,"wsn_seq".getBytes()
                ,ZooDefs.Ids.OPEN_ACL_UNSAFE
                ,CreateMode.EPHEMERAL_SEQUENTIAL);
        zk.create("/wsn/seq/no"
                ,"wsn_seq_another".getBytes()
                ,ZooDefs.Ids.OPEN_ACL_UNSAFE
                ,CreateMode.PERSISTENT_SEQUENTIAL);

[zk: localhost:2181(CONNECTED) 2] ls /wsn/sequence
[no0000000001, no0000000000]

总结

通过zookeeper API练习实验,可以加深理解zookeeper的原理。在zookeeperApi的基础上,可以扩展出更多的业务场景,满足分布式场景高可靠、命名、选举等需求。

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
目录
相关文章
|
3月前
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
3月前
|
负载均衡 Java 应用服务中间件
微服务分布式系统架构之zookeeper与dubbor-1
微服务分布式系统架构之zookeeper与dubbor-1
|
13天前
|
存储 运维 NoSQL
分布式读写锁的奥义:上古世代 ZooKeeper 的进击
本文作者将介绍女娲对社区 ZooKeeper 在分布式读写锁实践细节上的思考,希望帮助大家理解分布式读写锁背后的原理。
|
2月前
|
分布式计算 NoSQL Java
Hadoop-32 ZooKeeper 分布式锁问题 分布式锁Java实现 附带案例和实现思路代码
Hadoop-32 ZooKeeper 分布式锁问题 分布式锁Java实现 附带案例和实现思路代码
48 2
|
2月前
|
分布式计算 Hadoop
Hadoop-27 ZooKeeper集群 集群配置启动 3台云服务器 myid集群 zoo.cfg多节点配置 分布式协调框架 Leader Follower Observer
Hadoop-27 ZooKeeper集群 集群配置启动 3台云服务器 myid集群 zoo.cfg多节点配置 分布式协调框架 Leader Follower Observer
50 1
|
2月前
|
SQL NoSQL 安全
分布式环境的分布式锁 - Redlock方案
【10月更文挑战第2天】Redlock方案是一种分布式锁实现,通过在多个独立的Redis实例上加锁来提高容错性和可靠性。客户端需从大多数节点成功加锁且总耗时小于锁的过期时间,才能视为加锁成功。然而,该方案受到分布式专家Martin的质疑,指出其在特定异常情况下(如网络延迟、进程暂停、时钟偏移)可能导致锁失效,影响系统的正确性。Martin建议采用fencing token方案,以确保分布式锁的正确性和安全性。
52 0
|
2月前
|
存储 SQL 消息中间件
Hadoop-26 ZooKeeper集群 3台云服务器 基础概念简介与环境的配置使用 架构组成 分布式协调框架 Leader Follower Observer
Hadoop-26 ZooKeeper集群 3台云服务器 基础概念简介与环境的配置使用 架构组成 分布式协调框架 Leader Follower Observer
51 0
|
2月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
12天前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
26 8
|
28天前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
54 16