zookeeper 笔记 (二)

一.    ZK Shell的使用

1.    概述

    Zookeeper提供类似shell环境,方便用户访问、操作数据,使用 bin目录下的 zkCli.sh命令,可以进入shell环境,同时可以查看到Zookeeper环境配置。


2.    常用命令


zkCli.sh [-server ip:port]./zkCli.sh -timeout 0 -r -server ip:port
./zkCli.sh -timeout 5000 -server 192.9.200.242:2181
-r :即使ZooKeeper服务器集群一般以上的服务器当掉,也给客户端体统读服务
h显示所有命令
ls path查看某个节点下的所有子节点信息
ls / :列出根节点下所有的子节点信息
ls2 path :是ls 和 stat两个命令的结合
create [-s] [-e] path dataacl

创建节点

zk的节点分为两种:临时节点(随着zk session消亡而自动删除)、持久节点(一直存在)
-s 表示是顺序节点
-e 标识是临时节点
path 节点路径
data 节点数据
acl 节点权限

delete path [version]删除指定路径的节点如果有子节点要先删除子节点
rmr path递归删除一个znode,删除当前路径节点及其所有子节点
get path获取当前节点的数据内容
set path data [version] 修改当前节点的数据内容  如果指定版本,需要和当前节点的数据版本一致
connect host:port / clost连接到指定节点 / 关闭服务器
history / redo cmdno查看客户端这次会话所执行的所有命令 / 执行指定历史命令
setquota -n|-b val path
某个Znode指定多少存储空间或者允许创建多少个节点
n 指定可以设置多少个子节点
b 指定可以设置多大空间(byte)

对于配额不是硬性的提示,超过配额还是可以继续创建,只不过在日志里面有提示

(遇到问题记得看 zeekeeper.out 这个文件    ,默认在zk的bin目录下,

命令:tail –f zookeeper.out)

listquotapath查看配额信息
delquota [-n|-b] path删除节点路径的配额信息
stat path

查看节点的状态


czxid 创建该节点的事物ID
ctime 创建该节点的时间
mZxid 更新该节点的事物ID
mtime 更新该节点的时间
pZxid 操作当前节点的子节点列表的事物ID(这种操作包含增加子节点,删除子节点)
cversion 当前节点的子节点版本号
dataVersion 当前节点的数据版本号
aclVersion 当前节点的acl权限版本号
ephemeralowner 当前节点的如果是临时节点,该属性是临时节点的事物ID
dataLength 当前节点的d的数据长度
numchildren 当前节点的子节点个数

quit退出客户端
  

二.    ZK Client的使用

1.    连接zk并监听事件

/**
 * 该类解释怎么去连接zk并监听事件
 *  psvm    --- main
 *  sout  --- syso
 *
 */
public class ZKDemo{

    public static void main(String[] args) throws IOException {
        ZooKeeper zk = new ZooKeeper("192.168.121.99:22", 5000, new MyWatcher());
        System.out.println("zkState --- >"+zk.getState());

    }
}
/**
 * 监听器
 */
class MyWatcher implements Watcher{

    public void process(WatchedEvent event) {
        System.out.println("Receive watched event:" + event);

    }
}

2.    创建znode并监听事件

/**
解释如何去创建znode并监听事件
*/
public class ZKOperateDemo implements Watcher {
	private static final CountDownLatch cdl = new CountDownLatch(1);

	public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
		ZooKeeper zk = new ZooKeeper("192.168.56.101:2181", 5000, new ZKOperateDemo());
		cdl.await();

		String path1 = zk.create("/zk-test-", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
		System.out.println("Success create path: " + path1);
		String path2 = zk.create("/zk-test-", "456".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
		System.out.println("Success create path: " + path2);
	}

	@Override
	public void process(WatchedEvent event) {
		System.out.println("Receive watched event:" + event);
		if (KeeperState.SyncConnected == event.getState()) {
			cdl.countDown();
		}
	}
}

3.    改变znode并监听事件

/**
解释如何改变znode数据并监听事件
*/
public class ZKDataDemo implements Watcher {
	private static final CountDownLatch cdl = new CountDownLatch(1);
	private static ZooKeeper zk = null;
	private static Stat stat = new Stat();

	public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
		zk = new ZooKeeper("192.168.56.101:2181", 5000, new ZKDataDemo());
		cdl.await();

		zk.create("/zk-test", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
		System.out.println(new String(zk.getData("/zk-test", true, stat)));

		zk.getData("/zk-test", true, stat);
		System.out.println(stat.getCzxid() + ", " + stat.getMzxid() + ", " + stat.getVersion());
		zk.setData("/zk-test", "123".getBytes(), -1);

		Thread.sleep(Integer.MAX_VALUE);
	}

	@Override
	public void process(WatchedEvent event) {
		if (KeeperState.SyncConnected == event.getState()) {
			if (EventType.None == event.getType() && null == event.getPath()) {
				cdl.countDown();
			} else if (event.getType() == EventType.NodeDataChanged) {
				try {
					System.out.println(new String(zk.getData(event.getPath(), true, stat)));
					System.out.println(stat.getCzxid() + ", " + stat.getMzxid() + ", " + stat.getVersion());
				} catch (Exception e) {
				}
			}
		}
	}
}

4.    改变子节点并监听事件

/**
解释如何改变子节点并监听事件
*/
public class ZKChildrenDemo implements Watcher {
	private static final CountDownLatch cdl = new CountDownLatch(1);
	private static ZooKeeper zk = null;

	public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
		zk = new ZooKeeper("192.168.56.101:2181", 5000, new ZKChildrenDemo());
		cdl.await();

		zk.create("/zk-test", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

		zk.create("/zk-test/c1", "456".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);

		List<String> list = zk.getChildren("/zk-test", true);
		for (String str : list)
			System.out.println(str);

		zk.create("/zk-test/c2", "789".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);

		Thread.sleep(Integer.MAX_VALUE);
	}

	@Override
	public void process(WatchedEvent event) {
		if (KeeperState.SyncConnected == event.getState())
			if (EventType.None == event.getType() && null == event.getPath()) {
				cdl.countDown();
			} else if (event.getType() == EventType.NodeChildrenChanged) {
				try {
					System.out.println("Child: " + zk.getChildren(event.getPath(), true));
				} catch (Exception e) {
				}
			}
	}
}

5.    异步调用并完成回调

/**
解释如何异步调用并完成回调
*/
class ChildrenCallback implements AsyncCallback.Children2Callback {
	@Override
	public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
		System.out.println(
				"Child: " + rc + ", path: " + path + ", ctx: " + ctx + ", children: " + children + ", stat: " + stat);
	}
}

public class ZKChildrenAsyncDemo implements Watcher {
	private static final CountDownLatch cdl = new CountDownLatch(1);
	private static ZooKeeper zk = null;

	public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
		zk = new ZooKeeper("192.168.56.101:2181", 5000, new ZKChildrenAsyncDemo());
		cdl.await();

		zk.create("/zk-test", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

		zk.create("/zk-test/c1", "456".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);

		zk.getChildren("/zk-test", true, new ChildrenCallback(), "ok");

		Thread.sleep(Integer.MAX_VALUE);
	}

	@Override
	public void process(WatchedEvent event) {
		if (KeeperState.SyncConnected == event.getState())
			if (EventType.None == event.getType() && null == event.getPath()) {
				cdl.countDown();
			} else if (event.getType() == EventType.NodeChildrenChanged) {
				try {
					System.out.println("Child: " + zk.getChildren(event.getPath(), true));
				} catch (Exception e) {
				}
			}
	}
}

三.    分布式发展历程

四.    分布式技术详解

五.    分布式事务

1.    ACID

        ACID,指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

a. Atomicity 原子性

事务里的每一个步骤都必须完成,否则只能都不完成。不能只执行一部分事务。

b. Consistency 一致性

事务完成后应该维持数据库的一致性。

c. Isolation 隔离性

表示每次事务都会看到具有一致性的数据库,无论其他事务有什么行动。

d. Durability 持久性

在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。


2.    2PC/3PC

a. 2PC Two Phase Commit


2P- 阶段1:提交事务请求(投票阶段)

2P- 阶段2:执行事务提交(commit、rollback)


b. 3PC Three Phase Commit


3P- 阶段1:是否提交

3P- 阶段2:预先提交

3P- 阶段3:提交(commit、rollback)

与2PC区别:

>第二阶段才写undo和redo事务日志
> 第三阶段协调者出现异常或网络超时

>参与者也会commit

优点:

> 改善同步阻塞

> 改善单点故障

 缺点:

> 同步阻塞
> 单点故障
> 数据不一致
> 容错机制不完善

3.    CAP理论(分布式系统遵循的理论)

CAP:  一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)

CAP理论: 一个分布式系统不可能同时满足一致性、可用性和分区容错性这三个基本需求,最多只能同时满足其中的两项;


a. Consistency

数据在分布式环境下的多个副本之间能否保持一致性,这里

的一致性更多是指强一致性;

b. Availability

分布式系统一直处于可用状态,对于请求总是能在有限的时间

内返回结果致性;

c. Partition tolerance

除非整个网络故障,分布式系统在任何网络或者单点故障

时,仍能对外提供满足一致性和可用性的服务;


序号组合说明
1放弃P,满足AC

将数据和服务都放在一个节点上,避免因网络引起的负面

影响,充分保证系统的可用性和一致性。但放弃P意味着

放弃了系统的可扩展性
2放弃A,满足PC

当节点故障或者网络故障时,受到影响的服务需要等待一

定的世界,因此在等待时间里,系统无法对外提供正常服

务,因此是不可用的;
3放弃C,满足AP

系统无法保证数据的实时一致性,但是承诺数据最终会保

证一致性。因此存在数据不一致的窗口期,至于窗口期的

长短取决于系统的设计


4.    BASE理论

BASE:基本可用(Bascially Available)、软状态(Soft state)、最终一致性(Eventually consistent)

BASE理论:即使无法做到强一致性,但分布式系统可以根据自己的业务特点,采用适当的方式来使系统达到最终的一致性;

a. Basically Avaliable

    当分布式系统出现不可预见的故障时,允许损失部分可用性,保障系统的“基本可用”;体现在“时间上的损失”和“功能上的损失”;e.g:部分用户双十一高峰期淘宝页面卡顿或降级处理;

b. Soft state

    允许系统中的数据存在中间状态,既系统的不同节点的数据副本之间的数据同步过程存在延时,并认为这种延时不会影响系统可用性;e.g:12306网站卖火车票,请求会进入排队队列;

c. Eventually consistent

    所有的数据在经过一段时间的数据同步后,最终能够达到一个一致的状态;e.g:理财产品首页充值总金额短时不一致;


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值