欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

柚子快報(bào)激活碼778899分享:【ZooKeeper學(xué)習(xí)筆記】

柚子快報(bào)激活碼778899分享:【ZooKeeper學(xué)習(xí)筆記】

http://yzkb.51969.com/

1. ZooKeeper基本概念

Zookeeper官網(wǎng):https://zookeeper.apache.org/index.html

Zookeeper是Apache Hadoop項(xiàng)目中的一個(gè)子項(xiàng)目,是一個(gè)樹(shù)形目錄服務(wù)Zookeeper翻譯過(guò)來(lái)就是動(dòng)物園管理員,用來(lái)管理Hadoop(大象)、Hive(蜜蜂)、Pig(小豬)的管理員,簡(jiǎn)稱(chēng)zkZookeeper的本質(zhì)是一個(gè)分布式的、開(kāi)源的、提供分布式應(yīng)用程序協(xié)調(diào)服務(wù)的組件Zookeeper提供的主要功能有:

配置管理分布式鎖集群管理

2. ZooKeeper常用命令

2.1 ZooKeeper數(shù)據(jù)模型

在正式介紹Zookeeper的常用命令之前,我們先來(lái)了解一下Zookeeper的相關(guān)數(shù)據(jù)模型:

Zookeeper的是一個(gè)樹(shù)形目錄服務(wù),其數(shù)據(jù)模型與unix文件系統(tǒng)目錄樹(shù)類(lèi)似,是一個(gè)層次化的結(jié)構(gòu)這里面的每一個(gè)節(jié)點(diǎn)都被稱(chēng)為ZNode,每個(gè)節(jié)點(diǎn)上都會(huì)保存自己的數(shù)據(jù)以及元數(shù)據(jù)信息節(jié)點(diǎn)也可以擁有子節(jié)點(diǎn),同時(shí)允許少量數(shù)據(jù)(1MB)存儲(chǔ)在該節(jié)點(diǎn)之下節(jié)點(diǎn)類(lèi)型大致可以分為如下四類(lèi):

PERSISTENT:持久化節(jié)點(diǎn)EPHEMERAL:臨時(shí)節(jié)點(diǎn) -ePERSISTENT_SEQUENTIAL:持久化順序節(jié)點(diǎn) -sEPHEMERAL_SEQUENTIAL:臨時(shí)順序節(jié)點(diǎn) -e -s

2.2 ZooKeeper常用命令

Zookeeper是一個(gè)常見(jiàn)的客戶(hù)端-服務(wù)器模型,我們可以使用命令行或者JavaAPI的方式充當(dāng)客戶(hù)端進(jìn)行訪(fǎng)問(wèn),其架構(gòu)如下圖所示:

服務(wù)端命令:

./zkServer.sh start啟動(dòng)zookeeper服務(wù)

./zkServer.sh status查看zookeeper服務(wù)運(yùn)行狀態(tài)

./zkServer.sh restart重啟zookeeper服務(wù)

./zkServer.sh stop關(guān)閉zookeeper服務(wù)

客戶(hù)端命令:

./zkCli.sh -server ip:port連接指定的zookeeper服務(wù)(如連接本地可忽略選項(xiàng)直接使用./zkCli.sh)

quit退出客戶(hù)端交互界面

help查看命令幫助

ls 目錄查看指定目錄下的znode節(jié)點(diǎn)

ls -s 目錄查看節(jié)點(diǎn)詳細(xì)信息

create znode [value]創(chuàng)建znode節(jié)點(diǎn)(可以攜帶data)

create znode -e [value]創(chuàng)建臨時(shí)節(jié)點(diǎn)(會(huì)話(huà)結(jié)束后消失)create znode -s [value]創(chuàng)建順序節(jié)點(diǎn)

get znode查看節(jié)點(diǎn)攜帶數(shù)據(jù)

set znode value設(shè)置節(jié)點(diǎn)數(shù)據(jù)

delete znode刪除指定的znode節(jié)點(diǎn)(必須為空)

deleteall znode刪除指定的znode節(jié)點(diǎn)及其子節(jié)點(diǎn)

2.3 ZooKeeper的JavaAPI操作

2.3.1 Curator介紹

Curator:是一個(gè)Zookeeper的Java客戶(hù)端庫(kù)

常見(jiàn)的Zookeeper Java客戶(hù)端有如下幾種:

原生JavaAPIZkClientCurator Curator的目標(biāo)就是簡(jiǎn)化Zookeeper客戶(hù)端的使用Curator項(xiàng)目最初有Netflix公司研發(fā),后來(lái)捐給了Apache基金會(huì),成為頂級(jí)項(xiàng)目

Curator官網(wǎng):http://curator.apache.org/

2.3.2 Curator API操作

2.3.2.1 建立連接

我們可以使用CuratorFrameworkFactory靜態(tài)工廠(chǎng)類(lèi)進(jìn)行創(chuàng)建,可以通過(guò)如下兩種方式配置:

使用newClient()方法使用build()方法

下面我們就給出對(duì)應(yīng)兩種代碼的實(shí)現(xiàn)方式: newClient:

/**

* ZooKeeper測(cè)試類(lèi)

*/

public class ZooKeeperTest {

private CuratorFramework client = null;

@Before

public void initByNewClient() {

CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181",

3000,

3000,

new ExponentialBackoffRetry(3000, 1));

this.client = client;

this.client.start();

}

}

build:

/**

* ZooKeeper測(cè)試類(lèi)

*/

public class ZooKeeperTest {

private CuratorFramework client = null;

@Before

public void init() {

CuratorFramework client = CuratorFrameworkFactory

.builder()

.connectString("127.0.0.1:2181")

.sessionTimeoutMs(3000)

.connectionTimeoutMs(3000)

.retryPolicy(new ExponentialBackoffRetry(3000, 1))

.namespace("")

.build();

client.start();

this.client = client;

}

}

其中各個(gè)配置項(xiàng)含義如下:

connectString:連接字符串,配置服務(wù)器地址,格式為ip:portsessionTimeoutMs:會(huì)話(huà)超時(shí)時(shí)間connectionTimeoutMs:連接超時(shí)時(shí)間retryPolicy:重試策略namespace:設(shè)置根目錄位置

2.3.2.2 創(chuàng)建節(jié)點(diǎn)

創(chuàng)建節(jié)點(diǎn)有如下常見(jiàn)的四種方式: Case1:創(chuàng)建節(jié)點(diǎn)(不攜帶數(shù)據(jù))

@Test

public void testCreate1() throws Exception {

String path = client.create().forPath("/app1");

System.out.println(path);

}

Case2:創(chuàng)建節(jié)點(diǎn)(攜帶數(shù)據(jù))

@Test

public void testCreate2() throws Exception {

String path = client.create().forPath("/app2", "curator java api".getBytes());

System.out.println(path);

}

Case3:創(chuàng)建多級(jí)節(jié)點(diǎn)

@Test

public void testCreate4() throws Exception {

client.create().creatingParentsIfNeeded().forPath("/test/test1/test2");

}

Case4:創(chuàng)建節(jié)點(diǎn)并指定類(lèi)型

@Test

public void testCreate3() throws Exception {

client.create().withMode(CreateMode.EPHEMERAL).forPath("/app3");

client.create().withMode(CreateMode.PERSISTENT).forPath("/app4");

client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/app5");

client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/app6");

}

2.3.2.3 刪除節(jié)點(diǎn)

刪除節(jié)點(diǎn)有如下常見(jiàn)的兩種方式: Case1:刪除節(jié)點(diǎn)(不含子節(jié)點(diǎn))

@Test

public void testDelete() throws Exception {

client.delete().forPath("/app1");

}

Case2:刪除節(jié)點(diǎn)(遞歸刪除子節(jié)點(diǎn))

@Test

public void testDeleteAll() throws Exception {

client.delete().deletingChildrenIfNeeded().forPath("/test");

}

2.3.2.4 查詢(xún)節(jié)點(diǎn)

查詢(xún)節(jié)點(diǎn)有如下常見(jiàn)的三種方式: Case1:查詢(xún)子節(jié)點(diǎn)信息

@Test

public void testGetChildren() throws Exception {

List childrenList = client.getChildren().forPath("/");

System.out.println(childrenList);

}

Case2:查詢(xún)節(jié)點(diǎn)數(shù)據(jù)

@Test

public void testGetData() throws Exception {

byte[] bytes = client.getData().forPath("/app2");

System.out.println("data: " + new String(bytes));

}

Case3:查詢(xún)節(jié)點(diǎn)詳細(xì)信息

@Test

public void testGetData3() throws Exception {

Stat stat = new Stat();

client.getData().storingStatIn(stat).forPath("/app2");

System.out.println(stat);

}

2.3.2.5 修改節(jié)點(diǎn)

修改節(jié)點(diǎn)有如下常見(jiàn)的兩種方式: Case1:修改節(jié)點(diǎn)數(shù)據(jù)

@Test

public void testSetData() throws Exception {

Stat stat = client.setData().forPath("/app1", "some data".getBytes());

System.out.println(stat);

}

Case2:修改節(jié)點(diǎn)數(shù)據(jù)(帶有版本號(hào))

@Test

public void testSetData2() throws Exception {

Stat stat = new Stat();

client.getData().storingStatIn(stat).forPath("/app2");

int version = stat.getVersion();

System.out.println(version);

client.setData().withVersion(version).forPath("/app2", "set with version".getBytes());

}

3. ZooKeeper的事件監(jiān)聽(tīng)機(jī)制

Watcher事件監(jiān)聽(tīng)機(jī)制:

ZooKeeper允許用戶(hù)在指定節(jié)點(diǎn)上注冊(cè)一些Watcher,當(dāng)一些特定事件發(fā)生時(shí),ZooKeeper就會(huì)將事件通知給對(duì)其感興趣的客戶(hù)端,這是ZooKeeper提供分布式協(xié)調(diào)服務(wù)的重要特性ZooKeeper引入了Watcher機(jī)制來(lái)實(shí)現(xiàn)發(fā)布 / 訂閱功能,能夠讓多個(gè)訂閱者同時(shí)監(jiān)聽(tīng)某一個(gè)對(duì)象,當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生變化時(shí)就會(huì)通知所有訂閱者ZooKeeper提供原生Watcher的方式,但是比較麻煩,因此Curator使用Cache數(shù)據(jù)結(jié)構(gòu)進(jìn)行了優(yōu)化實(shí)現(xiàn)監(jiān)聽(tīng)機(jī)制Curator提供了如下三種Cache:

NodeCache:只監(jiān)聽(tīng)某一個(gè)指定的節(jié)點(diǎn)變化PathChildrenCache:監(jiān)控一個(gè)節(jié)點(diǎn)的所有子節(jié)點(diǎn)TreeCache:監(jiān)控整個(gè)樹(shù)上的節(jié)點(diǎn),類(lèi)似于前兩者的組合

3.1 Node Cache

代碼實(shí)現(xiàn):

@Test

public void testCuratorCache() throws Exception {

NodeCache cache = new NodeCache(client, "/app1");

cache.getListenable().addListener(new NodeCacheListener() {

@Override

public void nodeChanged() throws Exception {

System.out.println("監(jiān)聽(tīng)到節(jié)點(diǎn)變化...");

}

});

cache.start();

while (true) {

}

}

3.2 PathChildren Cache

代碼實(shí)現(xiàn):

@Test

public void testPathChildrenCache() throws Exception {

PathChildrenCache cache = new PathChildrenCache(client, "/app1", true);

cache.getListenable().addListener(new PathChildrenCacheListener() {

@Override

public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {

System.out.println("監(jiān)聽(tīng)到子節(jié)點(diǎn)變化...");

PathChildrenCacheEvent.Type type = pathChildrenCacheEvent.getType();

if (type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)) {

System.out.println("監(jiān)聽(tīng)到子節(jié)點(diǎn)數(shù)據(jù)變化...");

System.out.println("更新后數(shù)據(jù): " + pathChildrenCacheEvent.getData().getData());

}

}

});

cache.start();

while (true) {

}

}

3.3 Tree Cache

代碼實(shí)現(xiàn):

@Test

public void testTreeCache() throws Exception {

TreeCache cache = new TreeCache(client, "/app1");

cache.getListenable().addListener(new TreeCacheListener() {

@Override

public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {

System.out.println("監(jiān)聽(tīng)到節(jié)點(diǎn)發(fā)生變化...");

System.out.println(treeCacheEvent);

}

});

cache.start();

while (true) {

}

}

4. ZooKeeper分布式鎖

4.1 ZooKeeper分布式鎖原理

核心思想:當(dāng)用戶(hù)獲取到鎖時(shí)就創(chuàng)建節(jié)點(diǎn),使用完鎖就刪除節(jié)點(diǎn)

每當(dāng)一個(gè)用戶(hù)想要獲取鎖時(shí)就在/lock節(jié)點(diǎn)下創(chuàng)建一個(gè) **臨時(shí)順序 **節(jié)點(diǎn)然后獲取/lock節(jié)點(diǎn)下的全部子節(jié)點(diǎn),如果發(fā)現(xiàn)當(dāng)前節(jié)點(diǎn)編號(hào)是最小的,則該節(jié)點(diǎn)對(duì)應(yīng)的客戶(hù)端獲取到鎖,使用完鎖后,刪除該節(jié)點(diǎn)如果發(fā)現(xiàn)節(jié)點(diǎn)編號(hào)不是最小的,則對(duì)前一個(gè)比自己小的編號(hào)節(jié)點(diǎn),并注冊(cè)事件監(jiān)聽(tīng)器,監(jiān)聽(tīng)刪除事件如果后續(xù)發(fā)現(xiàn)比自己小的節(jié)點(diǎn)被刪除,則客戶(hù)端會(huì)接收到來(lái)自ZooKeeper的通知,然后再次判斷所對(duì)應(yīng)節(jié)點(diǎn)編號(hào)是否是最小的,重復(fù)上述步驟

注意:這里創(chuàng)建臨時(shí)節(jié)點(diǎn)是因?yàn)榉乐公@取到鎖的客戶(hù)端宕機(jī)了,進(jìn)而導(dǎo)致鎖永遠(yuǎn)不會(huì)被刪的情況;這是創(chuàng)建順序節(jié)點(diǎn)是方便編號(hào)的排序

Cutator提供了下面五種分布式鎖的方式:

InterProcessMutex(分布式可重入排他鎖)InterProcessSemaphoreMutex(分布式不可重入排他鎖)InterProcessReadWriteLock(分布式讀寫(xiě)鎖)InterProcessMutliLock(將多個(gè)鎖作為單個(gè)實(shí)體管理的容器)InterProcessSemaphoreV2(共享信號(hào)量)

4.2 分布式鎖實(shí)戰(zhàn)(模擬12306搶票)

代碼如下:

package org.example;

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;

import java.util.concurrent.TimeUnit;

public class ZooKeeperLockTest {

private static int tickets = 10; // 票數(shù)

public static void main(String[] args) {

// 建立連接

CuratorFramework client = CuratorFrameworkFactory

.builder()

.connectString("127.0.0.1:2181")

.sessionTimeoutMs(3000)

.connectionTimeoutMs(3000)

.retryPolicy(new ExponentialBackoffRetry(3000, 1))

.namespace("")

.build();

client.start();

// 獲取分布式鎖

InterProcessMutex lock = new InterProcessMutex(client, "/lock");

Thread t1 = new Thread(() -> {

while (true) {

try {

boolean hasLock = lock.acquire(3, TimeUnit.SECONDS);

if (hasLock && tickets > 0) {

// 不斷搶票

System.out.println("線(xiàn)程" + Thread.currentThread().getName() + "搶到了當(dāng)前第" + tickets + "張票");

tickets--;

if (tickets <= 0) {

break;

}

}

} catch (Exception e) {

throw new RuntimeException(e);

} finally {

try {

lock.release();

} catch (Exception e) {

throw new RuntimeException(e);

}

}

}

}, "攜程");

Thread t2 = new Thread(() -> {

while (true) {

try {

boolean hasLock = lock.acquire(3, TimeUnit.SECONDS);

if (hasLock && tickets > 0) {

// 不斷搶票

System.out.println("線(xiàn)程" + Thread.currentThread().getName() + "搶到了當(dāng)前第" + tickets + "張票");

tickets--;

if (tickets <= 0) {

break;

}

}

} catch (Exception e) {

throw new RuntimeException(e);

} finally {

try {

lock.release();

} catch (Exception e) {

throw new RuntimeException(e);

}

}

}

}, "飛豬");

t1.start();

t2.start();

}

}

5. ZooKeeper集群管理

Leader選舉過(guò)程:

ServerId:服務(wù)器ID

比如有三臺(tái)服務(wù)器,編號(hào)分別是1,2,3。則編號(hào)越大在選擇算法中的權(quán)重就越大

Zxid:數(shù)據(jù)ID

服務(wù)器中存放的數(shù)據(jù)ID越大,值越大說(shuō)明更新的越頻繁,則在選擇算法中的權(quán)重就越大

在Leader選舉的過(guò)程中如果某臺(tái)ZooKeeper超過(guò)了半數(shù)選票,則直接當(dāng)選為L(zhǎng)eader

柚子快報(bào)激活碼778899分享:【ZooKeeper學(xué)習(xí)筆記】

http://yzkb.51969.com/

文章鏈接

評(píng)論可見(jiàn),查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀(guān)點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/19196325.html

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪(fǎng)問(wèn)

文章目錄