การแนะนำ
แอปพลิเคชัน Java มักจะมีการกำหนดค่าที่แตกต่างกัน เช่น ที่อยู่และพอร์ตการเชื่อมต่อ ตัวอย่างเช่น อาจมีลักษณะเช่นนี้หากเราใช้ คลาส
Properties :
public static void main(String []args) {
Properties props = new Properties();
props.setProperty("host", "www.tutorialspoint.com");
System.out.println("Hello, " + props.getProperty("host"));
}
และดูเหมือนว่าจะเพียงพอแล้ว เพราะ... เราสามารถรับคุณสมบัติจากไฟล์ได้ และทุกอย่างดูเหมือนจะเข้ากันได้ดีกับเราในเครื่องเดียว แต่ลองจินตนาการว่าระบบของเราเริ่มประกอบด้วยระบบที่แตกต่างกันซึ่งแยกออกจากกัน ระบบดังกล่าวเรียกอีกอย่างว่าระบบแบบกระจาย ในวิกิพีเดีย คุณสามารถดูคำจำกัดความต่อไปนี้:
ระบบแบบกระจายคือระบบที่มีส่วนประกอบอยู่บนคอมพิวเตอร์เครือข่ายที่แตกต่างกันซึ่งสื่อสารระหว่างกันและประสานงานการดำเนินการโดยการแลกเปลี่ยนข้อความระหว่างกัน คุณสามารถดูแผนภาพต่อไปนี้:
ด้วยแนวทางนี้ ระบบเดียวจึงถูกแบ่งออกเป็นส่วนประกอบต่างๆ การกำหนดค่าเป็นองค์ประกอบทั่วไปที่แยกจากกัน ส่วนประกอบอื่นๆ แต่ละส่วนประกอบทำหน้าที่เป็นไคลเอ็นต์สำหรับส่วนประกอบการกำหนดค่า กรณีนี้เรียกว่า "
การกำหนดค่าแบบกระจาย " มีการใช้งานการกำหนดค่าแบบกระจายที่แตกต่างกันมากมาย และในการทบทวนวันนี้ฉันขอเสนอให้ทำความคุ้นเคยกับหนึ่งในนั้นเรียกว่า Zookeeper
คนเลี้ยงสัตว์
เส้นทางในการทำความรู้จักกับ Zookeeper เริ่มต้นด้วยเว็บไซต์อย่างเป็นทางการ:
Zookeeper.apache.org บนเว็บไซต์อย่างเป็นทางการ คุณต้องไปที่ ส่วน "
ดาวน์โหลด " ในส่วนนี้ ให้ดาวน์โหลดไฟล์เก็บถาวรในรูปแบบ .tar.gz เช่น “zookeeper-3.4.13.tar.gz” tar เป็นรูปแบบไฟล์เก็บถาวรแบบดั้งเดิมสำหรับระบบยูนิต gz - หมายความว่า gzip ใช้เพื่อบีบอัดไฟล์เก็บถาวร หากเราทำงานบนเครื่อง Windows สิ่งนี้ก็ไม่ควรรบกวนเรา ผู้จัดเก็บสมัยใหม่ส่วนใหญ่ (เช่น
7-zip ) สามารถทำงานได้อย่างสมบูรณ์แบบบน Windows มาแยกเนื้อหาลงในไดเร็กทอรีบางส่วน ในเวลาเดียวกันเราจะเห็นความแตกต่าง - บนดิสก์ในสถานะที่แยกออกมานั้นจะมีพื้นที่ประมาณ 60 เมกะไบต์และเราดาวน์โหลดไฟล์เก็บถาวรขนาดประมาณ 35 เมกะไบต์ อย่างที่คุณเห็น การบีบอัดใช้งานได้จริง ตอนนี้คุณต้องเปิด Zookeeper โดยทั่วไป Zookeeper เป็นเซิร์ฟเวอร์ประเภทหนึ่ง Zookeeper สามารถทำงานในโหมดใดโหมดหนึ่งจากสองโหมด:
แบบสแตนด์อโลนหรือแบบ
จำลอง ลองพิจารณาตัวเลือกที่ง่ายที่สุดหรือที่เรียกว่าตัวเลือกแรก - โหมดสแตนด์อโลน เพื่อให้ Zookeper ทำงาน จำเป็นต้องมีไฟล์กำหนดค่า ดังนั้นเรามาสร้างมันกันที่นี่:
[КаталогРаспаковкиZookeeper]/conf/zoo.cfg
. สำหรับ Windows เราจะใช้คำแนะนำจากสื่อ: “
การติดตั้ง Apache ZooKeeper บน Windows ” เนื้อหาของไฟล์คอนฟิกูเรชันจะเป็นดังนี้:
tickTime=2000
dataDir=C:/zookeeper-3.4.13/data
clientPort=2181
มาเพิ่มตัวแปรสภาพแวดล้อม ZOOKEEPER_HOME ที่มีเส้นทางไปยังไดเร็กทอรีรากของ Zookeper (ตามคำแนะนำบนสื่อ) และยังเพิ่มส่วนต่อไปนี้ให้กับตัวแปรสภาพแวดล้อม PATH:
;%ZOOKEEPER_HOME%\bin;
นอกจากนี้ ไดเร็กทอรีที่ระบุใน dataDir จะต้องมีอยู่ มิฉะนั้น Zookeeper จะไม่เป็น สามารถเปิดเซิฟเวอร์ได้ ตอนนี้เราสามารถเริ่มต้นเซิร์ฟเวอร์ได้อย่างปลอดภัยโดยใช้คำสั่ง: zkServer ต้องขอบคุณความจริงที่ว่าไดเร็กทอรี Zookeeper ได้ถูกเพิ่มเข้าไปในตัวแปรสภาพแวดล้อมของพาธแล้ว เราจึงสามารถเรียกคำสั่ง Zookeper ได้จากทุกที่ ไม่ใช่แค่จากไดเร็กทอรี bin เท่านั้น
ZNode
ตามที่ระบุไว้ใน "
ภาพรวม Zookeeper " ข้อมูลใน Zookeper จะแสดงในรูปแบบของ
ZNodes (โหนด) ที่จัดเป็นโครงสร้างแบบต้นไม้ นั่นคือแต่ละ ZNode สามารถมีข้อมูลและมี ZNodes ลูกได้ ข้อมูลเพิ่มเติมเกี่ยวกับองค์กร ZNode สามารถพบได้ในเอกสารประกอบของ Zookeeper: "
โมเดลข้อมูลและเนมสเปซแบบลำดับชั้น " เพื่อทำงานร่วมกับ Zookeeper และ ZNode เราจะใช้
Zookeeper CLI (อินเทอร์เฟซบรรทัดคำสั่ง) ก่อนหน้านี้เราเริ่มต้นเซิร์ฟเวอร์โดยใช้คำสั่ง zkServer ตอนนี้เพื่อเชื่อมต่อ มาดำเนินการกัน
zkCli.cmd -server 127.0.0.1:2181
หากสำเร็จ เซสชันการเชื่อมต่อกับ Zookeeper จะถูกสร้างขึ้นและเราจะเห็นผลลัพธ์ต่อไปนี้โดยประมาณ:
สิ่งที่น่าสนใจคือแม้ทันทีหลังการติดตั้ง Zookeeper ก็มี ZNode อยู่แล้ว โดยมีเส้นทางดังนี้
/zookeeper/quota
สิ่งเหล่านี้เรียกว่า "
โควต้า " ตามที่ระบุไว้ใน "
Apache ZooKeeper Essentials " แต่ละ ZNode สามารถมีโควต้าที่เกี่ยวข้องได้ โดยจำกัดข้อมูลที่สามารถจัดเก็บได้ อาจระบุขีดจำกัดจำนวน znode และจำนวนข้อมูลที่เก็บไว้ได้ ยิ่งไปกว่านั้น หากเกินขีดจำกัดนี้ การดำเนินการกับ ZNode จะไม่ถูกยกเลิก แต่จะได้รับคำเตือนเกี่ยวกับการเกินขีดจำกัด ขอแนะนำให้อ่านเกี่ยวกับ ZNode ใน "
คู่มือโปรแกรมเมอร์ ZooKeeper: ZNodes " ตัวอย่างบางส่วนเกี่ยวกับวิธีการทำงานกับ ZNode:
ฉันอยากจะทราบด้วยว่า ZNodes นั้นแตกต่างออกไป ZNodes ปกติ (เว้นแต่คุณจะระบุแฟล็กเพิ่มเติม) เป็นประเภท "
ถาวร " มี ZNode ประเภท "
Ephemeral Node " ZNodes ดังกล่าวมีอยู่ในช่วงเวลาของเซสชันการเชื่อมต่อ Zookeeper ที่สร้างขึ้นเท่านั้น มี ZNode ประเภท "
Sequence Node " ZNodes เหล่านี้ต่อท้ายด้วยตัวเลขจากลำดับเพื่อให้แน่ใจว่าไม่ซ้ำกัน โหนดลำดับอาจเป็นแบบถาวรหรือแบบชั่วคราวก็ได้ ขอแนะนำข้อมูลพื้นฐานเล็กน้อยเกี่ยวกับ ZNode ที่นี่: “
Zookeeper ZNodes – ลักษณะและตัวอย่าง ”
ผู้เฝ้าดู ZNode
ฉันอยากจะพูดคุยเกี่ยวกับผู้ดูด้วย รายละเอียดเกี่ยวกับสิ่งเหล่านี้เขียนไว้ในเอกสารของ Zookeeper: "
ZooKeeper Watches " กล่าวโดยสรุป ผู้เฝ้าดูคือสิ่งกระตุ้นที่เกิดขึ้นเพียงครั้งเดียวซึ่งถูกกระตุ้นโดยเหตุการณ์บางอย่าง โดยการดึงข้อมูลโดยการดำเนินการ getData(), getChildren() หรือ existing() เราสามารถสร้างทริกเกอร์เป็นการดำเนินการเพิ่มเติมได้ Zookeeper รับรองลำดับของการประมวลผลเหตุการณ์ นอกจากนี้ เอกสารระบุว่าก่อนที่เราจะเห็นค่า ZNode ใหม่ เราจะเห็นเหตุการณ์เกี่ยวกับการเปลี่ยนค่าเก่าเป็นค่าใหม่ คุณสามารถอ่านเพิ่มเติมเกี่ยวกับ Watchers ได้ที่นี่: “
นาฬิกา ZooKeeper – คุณสมบัติและการรับประกัน ” เพื่อลองสิ่งนี้ ลองใช้
CLI อีกครั้ง : สมมติว่าเรามี ZNode บางตัวที่มีค่าที่เราจัดเก็บสถานะของบริการบางอย่าง:
[zk: 127.0.0.1:2181(CONNECTED) 0] create /services/service1/status stopped
Created /services/service1/status
[zk: 127.0.0.1:2181(CONNECTED) 1] get /services/service1/status [watch]
stopped
ตอนนี้ หากข้อมูล
/services/service1/status
เปลี่ยนแปลง ทริกเกอร์แบบครั้งเดียวของเราจะเริ่มทำงาน:
เป็นเรื่องน่าสนใจที่เมื่อเชื่อมต่อกับ Zookeeper เราจะได้เห็นว่าผู้เฝ้าดูทำงานอย่างไร:
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
SyncConnectedเป็นหนึ่งในกิจกรรม Zookeper ที่เป็นไปได้ รายละเอียดเพิ่มเติมสามารถพบได้ในคำอธิบาย API
ผู้ดูแลสวนสัตว์และ Java
ตอนนี้เรามีความเข้าใจพื้นฐานแล้วว่า Zookeeper ทำอะไรได้บ้าง ตอนนี้มาทำงานกับมันผ่าน Java ไม่ใช่ผ่าน CLI และสำหรับสิ่งนี้ เราจะต้องมีแอปพลิเคชัน Java ซึ่งเราจะดูวิธีทำงานกับ Zookeeper ในการสร้างแอปพลิเคชัน เราจะใช้ ระบบสร้างโปรเจ็ ก ต์
Gradle การใช้ "
ปลั๊กอิน Gradle Build Init " เราจะสร้างโครงการ หากต้องการทำสิ่งนี้ ให้รันคำสั่ง:
gradle init --type java-application
หาก Gradle ขอให้คุณชี้แจงคำถาม เราจะคงค่าเริ่มต้นไว้ (เพียงกด Enter) ตอนนี้เรามาเปิดสคริปต์การสร้างกันเช่น ไฟล์ build.gradle ประกอบด้วยคำอธิบายว่าโปรเจ็กต์ของเราทำจากอะไร และอาร์ติแฟกต์ใดบ้าง (ไลบรารี เฟรมเวิร์ก) ที่โปรเจ็กต์ขึ้นอยู่กับ เพราะ เราต้องการใช้ Zookeeper ก็ต้องเพิ่มเข้าไป ดังนั้น เรามาเพิ่มการพึ่งพา Zookeeper ให้กับบล็อกการขึ้นต่อกัน:
dependencies {
implementation 'org.apache.zookeeper:zookeeper:3.4.13'
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับ Gradle ได้ในบทวิจารณ์: "
A Brief Introduction to Gradle " ดังนั้นเราจึงมีโปรเจ็กต์ Java เราเชื่อมต่อไลบรารี Zookeeper เข้ากับโปรเจ็กต์นั้น มาเขียนอะไรบางอย่างตอนนี้ อย่างที่เราจำได้ การใช้ CLI เราเชื่อมต่อบางอย่างดังนี้:
zkCli.cmd -server 127.0.0.1:2181
มาประกาศแอตทริบิวต์ "เซิร์ฟเวอร์" ในคลาส App ด้วยวิธีการหลัก:
String server = "127.0.0.1:2181";
การเชื่อมต่อไม่ใช่การดำเนินการทันที เราจะต้องรอในเธรดหลักของการทำงานของโปรแกรมเพื่อให้การเชื่อมต่อเกิดขึ้น ดังนั้นเราจึงต้องมีล็อค มาประกาศด้านล่าง:
Object lock = new Object();
ตอนนี้เราต้องการใครสักคนเพื่อบอกว่าการเชื่อมต่อได้ถูกสร้างขึ้นแล้ว อย่างที่เราจำได้ เมื่อเราทำสิ่งนี้ผ่าน CLI ผู้เฝ้าดูก็ทำงานให้เรา ดังนั้นในโค้ด Java ทุกอย่างจึงเหมือนกันทุกประการ ผู้เฝ้าดูของเราจะแสดงข้อความเกี่ยวกับความสำเร็จและแจ้งเตือนทุกคนที่รออยู่ผ่านการล็อค มาเขียนผู้เฝ้าดู:
Watcher connectionWatcher = new Watcher() {
public void process(WatchedEvent we) {
if (we.getState() == Event.KeeperState.SyncConnected) {
System.out.println("Connected to Zookeeper in " + Thread.currentThread().getName());
synchronized (lock) {
lock.notifyAll();
}
}
}
};
ตอนนี้เรามาเพิ่มการเชื่อมต่อกับเซิร์ฟเวอร์ ZooKeeper:
int sessionTimeout = 2000;
ZooKeeper zooKeeper = null;
synchronized (lock) {
zooKeeper = new ZooKeeper(server, sessionTimeout, connectionWatcher);
lock.wait();
}
ทุกอย่างเรียบง่ายที่นี่ เมื่อดำเนินการวิธีการหลักในเธรดหลักของโปรแกรม เราจะล็อคและขอการเชื่อมต่อกับผู้ดูแลสวนสัตว์ ในขณะเดียวกันเราก็ปลดล็อคและรอจนกว่าจะมีคนมาคว้าล็อคและแจ้งให้เราทราบว่าเราจะดำเนินการต่อได้ เมื่อสร้างการเชื่อมต่อแล้ว ผู้เฝ้าดูจะทำงาน เขาจะตรวจสอบว่าเหตุการณ์ SyncConnected มาถึงแล้ว (ดังที่เราจำได้ว่านี่คือสิ่งที่ผู้ดูจับได้ผ่าน CLI) จากนั้นจึงเขียนข้อความ ต่อไปเราคว้าล็อค (เนื่องจากเธรดหลักปล่อยออกมาก่อนหน้านี้) และแจ้งเตือนเธรดทั้งหมดที่รอการล็อคเพื่อให้เราสามารถดำเนินการต่อได้ เธรดการประมวลผลเหตุการณ์ออกจากบล็อกที่ซิงโครไนซ์ ดังนั้นจึงปล่อยการล็อก เธรดหลักได้รับการแจ้งเตือน และหลังจากรอการปลดล็อก ดำเนินการต่อไปเนื่องจาก จนกว่าจะได้รับการล็อคจะไม่สามารถออกจากบล็อกที่ซิงโครไนซ์และทำงานต่อไปได้ ดังนั้นการใช้มัลติเธรดและ Zookeeper API ทำให้เราสามารถดำเนินการต่างๆ ได้ Zookeeper API กว้างกว่าที่ CLI อนุญาตมาก ตัวอย่างเช่น:
String znodePath = "/zookeepernode2";
List<ACL> acls = ZooDefs.Ids.OPEN_ACL_UNSAFE;
if (zooKeeper.exists(znodePath, false) == null) {
zooKeeper.create(znodePath, "data".getBytes(), acls, CreateMode.PERSISTENT);
}
byte[] data = zooKeeper.getData(znodePath, null, null);
System.out.println("Result: " + new String(data, "UTF-8"));
อย่างที่คุณเห็น เมื่อสร้างโหนด เราสามารถกำหนดค่า ACL ได้ นี่เป็นคุณสมบัติที่สำคัญอีกประการหนึ่ง ACL คือสิทธิ์ที่ใช้กับการดำเนินการกับ ZNode มีการตั้งค่ามากมาย ดังนั้นฉันขอแนะนำให้คุณดูเอกสารประกอบอย่างเป็นทางการเพื่อดูรายละเอียด: “
สิทธิ์ Zookeeper ACL ”
บทสรุป
ทำไมเราอ่านเรื่องนี้? เนื่องจาก Zookeeper ถูกนำมาใช้ในเทคโนโลยียอดนิยมอื่น ๆ ตัวอย่างเช่น Apache Kafka ต้องใช้ Zookeeper ซึ่งคุณสามารถอ่านได้ใน "
Kafka Quick Start Guide " นอกจากนี้ยังใช้ในฐานข้อมูล NOSQL HBase ซึ่งคุณสามารถอ่านเพิ่มเติมได้ใน "
HBase Quickstart Guide " จริงๆ แล้ว มีโปรเจ็กต์อื่นๆ อีกมากมายที่ใช้ Zookeeper บางส่วนมีระบุไว้ใน "
การใช้ Zookeeper ในโลกแห่งความเป็นจริง " ฉันหวังว่าฉันจะตอบคำถามว่า "ทำไม" คำถามที่สำคัญที่สุดในตอนนี้คือ “อะไรต่อไป?” ขั้นแรก คุณสามารถอ่านหนังสือต่อไปนี้ในหัวข้อ Apache Zookeeper:
ประการที่สอง มีรายงานวิดีโอที่ยอดเยี่ยมเกี่ยวกับ Zookeeper แนะนำให้ดู:
ประการที่สาม มีบทความที่มีประโยชน์หลายบทความที่จะเสริมภาพของโลก:
นี่เป็นบทวิจารณ์สั้น ๆ แต่เป็นคำเบื้องต้นฉันหวังว่ามันจะมีประโยชน์ #เวียเชสลาฟ
GO TO FULL VERSION