zookeeper官网下载:https://archive.apache.org/dist/zookeeper/
每台服务器有自己的唯一标识SID,优先选举SID最大的为Leader。
Zookeeper集群有两种情况会进入选举:
- 服务器启动初始化。
- 运行期间与Leader失去连接。
总结:
- 比较Epoch,大的直接获胜。
- Epoch相同,ZXID大的胜出。
- ZXID相同,SID大的胜出。
启动hadoop102、hadoop103、hadoop104脚本
#!/bin/bash
# 判断没有参数
if [$# -lt 1]
then
echo "No Args Input..."
exit;
fi
case $1 in
"start")
for i in hadoop102 hadoop103 hadoop104
do
echo "----------------- zookeeper $i 启动 -----------------"
ssh $i "/opt/install/zookeeper-3.5.7/bin/zkServer.sh start"
done
;;
"stop")
for i in hadoop102 hadoop103 hadoop104
do
echo "----------------- zookeeper $i 停止 -----------------"
ssh $i "/opt/install/zookeeper-3.5.7/bin/zkServer.sh stop"
done
;;
"status")
for i in hadoop102 hadoop103 hadoop104
do
echo "----------------- zookeeper $i 状态 -----------------"
ssh $i "/opt/install/zookeeper-3.5.7/bin/zkServer.sh status"
done
;;
*)
echo "Input Args Error..."
;;
esac
查看启动报错日志:
# 查看启动报错日志
bin/zkServer.sh start-foreground
命令基本语法 | 功能描述 |
---|---|
help | 显示所有操作命令 |
ls /path | 1.使用 ls 命令来查看当前 znode 的子节点 [可监听];2.-w 监听子节点变化;3.-s 附加次级信息 |
create | 1.普通创建;2.-s 含有序列;2.-e 临时(重启或者超时消失) |
get /path | 1.获得节点的值(可监听);2.-w 监听节点内容变化;3.-s 附加次级信息 |
set | 设置节点的具体值 |
stat | 查看节点状态 |
delete | 删除节点 |
deleteall | 递归删除节点 |
在分布式系统中,有多个节点,可以动态上下线,客户端能够感知节点的上下线情况。
集群上创建/servers节点
# 启动客户端
bin/zkCli.sh
# 创建节点
create /servers "servers"
DistributeServer.java
import org.apache.zookeeper.*;
import java.io.IOException;
public class DistributeServer {
private static String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zk = null;
private String parentNode = "/servers";
// 创建到 zk 的客户端连接
public void getConnect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, event -> {
});
}
// 注册服务器
public void registerServer(String hostname) throws Exception {
String create = zk.create(parentNode + "/server",
hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(hostname + " is online " + create);
}
// 业务功能
public void business(String hostname) throws Exception {
System.out.println(hostname + " is working ...");
Thread.sleep(Long.MAX_VALUE);
}
public static void main(String[] args) throws Exception {
// 1 获取 zk 连接
DistributeServer server = new DistributeServer();
server.getConnect();
// 2 利用 zk 连接注册服务器信息
server.registerServer(args[0]);
// 3 启动业务功能
server.business(args[0]);
}
}
DistributeClient.java
import org.apache.zookeeper.ZooKeeper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class DistributeClient {
private static String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zk = null;
private String parentNode = "/servers";
// 创建到 zk 的客户端连接
public void getConnect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, event -> {
// 再次启动监听
try {
getServerList();
} catch (Exception e) {
e.printStackTrace();
}
});
}
// 获取服务器列表信息
public void getServerList() throws Exception {
// 1 获取服务器子节点信息,并且对父节点进行监听
List<String> children = zk.getChildren(parentNode, true);
// 2 存储服务器信息列表
ArrayList<String> servers = new ArrayList<>();
// 3 遍历所有节点,获取节点中的主机名称信息
for (String child : children) {
byte[] data = zk.getData(parentNode + "/" + child,
false, null);
servers.add(new String(data));
}
// 4 打印服务器列表信息
System.out.println(servers);
}
// 业务功能
public void business() throws Exception {
System.out.println("client is working ...");
Thread.sleep(Long.MAX_VALUE);
}
public static void main(String[] args) throws Exception {
// 1 获取 zk 连接
DistributeClient client = new DistributeClient();
client.getConnect();
// 2 获取 servers 的子节点信息,从中获取服务器信息列表
client.getServerList();
// 3 业务进程启动
client.business();
}
}
分布式锁和分布式事务的区别:
参考:https://zhuanlan.zhihu.com/p/183753774
pom.xml
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.7</version>
</dependency>
DistributedLock.java
package com.cnwanj.distributed;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
/**
* @author: cnwanj
* @date: 2022-02-19 15:55:41
* @version: 1.0
* @desc: Zookeeper分布式锁实现
*/
public class DistributedLock {
private final String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private final int sessionTimeout = 2000;
private final ZooKeeper zk;
// 等待连接完毕
private CountDownLatch connectLatch = new CountDownLatch(1);
// 等待监听上一个节点完毕
private CountDownLatch waitLatch = new CountDownLatch(1);
// 前一个节点路径
private String waitPath;
private String currentMode;
public DistributedLock() throws IOException, InterruptedException, KeeperException {
// 建立连接
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
// 释放连接等待(若已建立连接)
if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
connectLatch.countDown();
}
// 释放监听等待(存在释放锁 && 路径是前一个节点)
if (watchedEvent.getType() == Event.EventType.NodeDeleted && watchedEvent.getPath().equals(waitPath)) {
waitLatch.countDown();
}
}
});
// 线程等待,建立连接再执行后面
connectLatch.await();
// 判断根目录是否存在
Stat stat = zk.exists("/locks", false);
if (stat == null) {
// 创建根节点(参数1:目录名称,参数2:目录下内容,参数3:对外开放,参数4:永久创建)
zk.create("/locks", "locks".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
}
// 加锁
public void zkLock() throws KeeperException, InterruptedException {
// 创建临时带序号节点
currentMode = zk.create("/locks/" + "seq-", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
// 校验节点是否第一个,是的话直接加锁,若不是,需要监听前一个是否解锁
List<String> childrenList = zk.getChildren("/locks", false);
// 如果只有一个节点,直接获取锁
if (childrenList.size() == 1) {
return;
} else {
// 从小到大排序
Collections.sort(childrenList);
// 当前节点名称
String thisNode = currentMode.substring("/locks/".length());
// 获取节点位置
int index = childrenList.indexOf(thisNode);
if (index == -1) {
System.out.println("数据异常");
} else if (index == 0) {
// thisNode为最小,直接获取锁
return;
} else {
// 获取前一个节点路径
waitPath = "/locks/" + childrenList.get(index - 1);
// 获取前一个节点,初始化监听
zk.getData(waitPath, true, null);
// 等待监听
waitLatch.await();
return;
}
}
}
// 解锁
public void unZkLock() throws KeeperException, InterruptedException {
// 删除节点
zk.delete(currentMode, -1);
}
}
DistributedLockTest.java
package com.cnwanj.distributed;
import org.apache.zookeeper.KeeperException;
import java.io.IOException;
/**
* @author: cnwanj
* @date: 2022-02-19 21:50:39
* @version: 1.0
* @desc: 测试Zookeeper分布式锁
*/
public class DistributedLockTest {
public static void main(String[] args) throws InterruptedException, IOException, KeeperException {
// 创建分布式锁1
final DistributedLock lock1 = new DistributedLock();
// 创建分布式锁2
final DistributedLock lock2 = new DistributedLock();
// 创建线程1
new Thread(() -> {
// 获取锁对象
try {
lock1.zkLock();
System.out.println("线程1获取锁");
Thread.sleep(3 * 1000);
lock1.unZkLock();
System.out.println("线程1释放锁");
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
}).start();
// 创建线程2
new Thread(() -> {
try {
lock2.zkLock();
System.out.println("线程2获取锁");
Thread.sleep(3 * 1000);
lock2.unZkLock();
System.out.println("线程2释放锁");
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
Apache Curator is a Java/JVM client library for Apache ZooKeeper, a distributed coordination service. It includes a highlevel API framework and utilities to make using Apache ZooKeeper much easier and more reliable. It also includes recipes for common use cases and extensions such as service discovery and a Java 8 asynchronous DSL.
意思是:Curator是Zookeeper的一个Java/Jvm客户端库,也是一个分布式协调服务,Curator成为Zookeeper更简单可靠的一个高可用框架和工具,它也包含了一些常用的用例和扩展方法,如Java8和异步DSL。
官网:https://curator.apache.org
maven依赖引入:
<!-- zookeeper依赖 -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.7</version>
</dependency>
<!-- curator依赖 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>4.3.0</version>
</dependency>
package com.cnwanj.lock.curator;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
/**
* @author: cnwanj
* @date: 2022-02-20 11:57:56
* @version: 1.0
* @desc: curator实现分布式锁
*/
public class CuratorTest {
private String rootNode = "/locks";
private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private int connectionTimeout = 2000;
private int sessionTimeout = 2000;
public static void main(String[] args) {
new CuratorTest().test();
}
private void test() {
// 分布式锁1
InterProcessMutex lock1 = new InterProcessMutex(getCuratorFramework(), rootNode);
// 分布式锁2
InterProcessMutex lock2 = new InterProcessMutex(getCuratorFramework(), rootNode);
// 线程1
new Thread(() -> {
try {
lock1.acquire();
System.out.println("线程1获取锁");
lock1.acquire();
System.out.println("线程1再次获取锁");
Thread.sleep(5 * 1000);
lock1.release();
System.out.println("线程1释放锁");
lock1.release();
System.out.println("线程1再次释放锁");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
// 线程1
new Thread(() -> {
try {
lock2.acquire();
System.out.println("线程2获取锁");
lock2.acquire();
System.out.println("线程2再次获取锁");
Thread.sleep(5 * 1000);
lock2.release();
System.out.println("线程2释放锁");
lock2.release();
System.out.println("线程2再次释放锁");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
private CuratorFramework getCuratorFramework() {
// 重试策略,尝试时间3秒,重试3次
RetryPolicy policy = new ExponentialBackoffRetry(3000, 3);
// 创建Curator
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString(connectString)
.connectionTimeoutMs(connectionTimeout)
.sessionTimeoutMs(sessionTimeout)
.retryPolicy(policy)
.build();
// 开启连接
client.start();
System.out.println("zk初始化完成...");
return client;
}
}
拜占庭将军问题是一个协议问题,拜占庭帝国军队的将军们必须全体一致的决定是否攻击某一支敌军。问题是这些将军在地理上是分隔开来的,并且将军中存在叛徒。叛徒可以任意行动以达到以下目标:欺骗某些将军采取进攻行动;促成一个不是所有将军都同意的决定,如当将军们不希望进攻时促成进攻行动;或者迷惑某些将军,使他们无法做出决定。如果叛徒达到了这些目的之一,则任何攻击行动的结果都是注定要失败的,只有完全达成一致的努力才能获得胜利。
**Paxos算法:**一种基于消息传递且具有高度容错特性的一致性算法。
**Paxos算法解决的问题:**就是如何快速正确的在一个分布式系统中对某个数据值达成一致,并且保证不论发生任何异常,都不会破坏整个系统的一致性。
Zab 借鉴了 Paxos 算法,是特别为 Zookeeper 设计的支持崩溃恢复的原子广播协议。基于该协议,Zookeeper 设计为只有一台客户端(Leader)负责处理外部的写事务请求,然后Leader 客户端将数据同步到其他 Follower 节点。即 Zookeeper 只有一个 Leader 可以发起提案。
CAP理论告诉我们,一个分布式系统不可能同时满足以下三种:
这三个基本需求,最多只能同时满足其中的两项,因为P是必须的,因此往往选择就在CP或者AP中。
1)一致性(Consistency)
在分布式环境中,一致性是指数据在多个副本之间是否能够保持数据一致的特性。在一致性的需求下,当一个系统在数
据一致的状态下执行更新操作后,应该保证系统的数据仍然处于一致的状态。
2)可用性(Available)
可用性是指系统提供的服务必须一直处于可用的状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果。
3)分区容错性(Partition Tolerance)
分布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和可用性的服务,除非是整个网络
环境都发生了故障。
ZooKeeper保证的是CP
zkServer.sh start启动 > new QuorumPeerMain();
NIO:
- 非堵塞IO通信方式,由一个线程处理所有的IO事件,并负责分发。
- 线程之前通过wait、notify通信,减少线程切换。
- 事件来到时触发操作,不需要堵塞监视事件,存在驱动机制。
选举主要分为两步:发送投票和处理投票
通过选举算法(FastLeaderElection)生成选票。
发送选票:
FastLeaderElection类:
QuorumCnManager类:
处理选票:
在对称密钥系统中,分发密钥往往是最薄弱的环节 1976年,斯坦福大学的Diffie和Hellman提出了一种全新的密钥系统 特点: 1.加密密钥和解密密钥不同 2.解密算法E和解密算法D满足三个要求: D(E(p))=p p指文本字符 从E推出D极其困难 从选择明文攻击不可能破解E
http://blog.csdn.net/lihe111/archive/2010/04/08/5461932.aspx 下载:http://coenraets.org/samples/PhotoInput/PhotoInputDemo.zip 总结:Flex4 组件开发应该是继承SkinnableComponent http://ker...
1.下载 Tomcat 解压到 D:\Java\apache-tomcat-9.0.132.配置Tomcat环境变量 1、新建变量名:CATALINA_HOME,变量值:D:\Java\apache-tomcat-9.0.13 2、打开PATH,添加变量值:%CATALINA_HOME%\lib;%CATALINA_HOME%\bi...
简单的说,GUI编程就是给程序加上图形化界面.python的脚本开发简单,有时候只需几行代码就能实现丰富的功能,而且python本身是跨平台的,所以深受程序员的喜爱.如果给程序加一个图形化界面,那么普通的用户也就能用上python的脚本,极大提升工作效率,所以给python程序加上图形化界面,把自己写的脚本,提供给普通用户,的确是一件激动人心的事!如何给python脚本加图形化界面?作者首先考虑了...
1.限制与要求不允许修改链表结构。时间复杂度O(n),空间复杂度O(1)。2.思考2.1判断是否有环如果链表有环,那么在遍历链表时则会陷入死循环,利用这个特征,我们可以设计这样的算法。使用一个slow指针,一个fast指针。slow指针一次往后遍历以1个节点,fast指针一次往后遍历2个节点,一直做这样的操作。如果fast指针在遍历过程中,遍历到了NULL节点说明链表没有环。否则当slow指针和f...
命令符git inigit commit -m “想起的名字”git add .https://gitee.com/Git名字/仓库名字git push -u origin master
一共有2中方法:1.mWebView.loadUrl("file:///android_asset/index.html");2,.private void ProcessWebString() {// 加载 asset 文件String tpl = getFromAssets("index.html");mWebView.loadDataWithBaseURL(null, tpl, "text/...
在做毕设的过程中,由于需要相对准确地提取一张图像的光照分量(光照分量一般是低频部分,所以平滑滤波可以提取,高斯滤波边缘保持能力很差),便找了许多边缘保持滤波算法,后来发现了何凯明大神提出的引导滤波算法,时间复杂度仅为O(N),N为图像像素总数,也即与滤波半径无关,极大地提高了运算速度,就学习了一下,顺便记录下自己的思考。主要参考文献是何凯明的《Guided Image Filtering》以及ht...
文章目录PaddlePaddle简介PaddlePaddle GPU版本安装使用PaddlePaddle做线性回归参考PaddlePaddle简介PaddlePaddle(飞浆)是百度开发的国产深度学习框架。用PaddlePaddle的好处是可以用AI Studio平台提供的GPU算力进行模型训练,不仅节约时间而且还是免费的。PaddlePaddle也提供了像PaddleSeg等一些套件,对于新手上手深度学习模型的项目很友好。PaddlePaddle GPU版本安装步骤一:创建虚拟环境。
风管 用于空气输送和分布的管道系统注塑机 将热塑性塑料或热固性塑料利用塑料成型模具制成各种形状的塑料制品的主要成型设备电机定子 电动机静止不动的部分立绕机 实现立绕过程(制作螺旋丝的一种绕线方法)的一种机器设备嵌扩一体机 绕线机器设备单邦机 线材设备插纸机 插槽纸,实现线和铁芯的绝缘效果交换机 为接入交换机的任意两个网络节点提供独享的电信号通路企业的生产计划是由上层管理系统ERP来完成,而车间排产计划则是由MES的计划管理系统来完成AGV 装备有电磁或光学等自动导航装置,能够沿规定的导航路
2016年应届生申办上海户籍正在火热进行中,希望这篇文档能帮助大家。根据《2016年非上海生源应届普通高校毕业生进沪就业申办本市户籍办法》,需要提供11个附件。总体来说,附件1和附件8由公司提供,不用担心;附件10和附件11基本不需要提供;其他材料则都由个人准备。
一、NoClassDefFoundError错误发生的原因 NoClassDefFoundError错误的发生,是因为Java虚拟机在编译时能找到合适的类,而在运行时不能找到合适的类导致的错误、例如在运行时我们想调用某个类的方法或者访问这个类的静态成员的时候,发现这个类不可用,此时Java虚拟机就会抛出。 NoClassDefFoundError错误与...