Ò»¡¢ÅäÖ÷þÎñ
ÅäÖ÷þÎñÊÇ·Ö²¼Ê½Ó¦ÓÃËùÐèÒªµÄ»ù±¾·þÎñÖ®Ò»£¬Ëüʹ¼¯ÈºÖеĻúÆ÷¿ÉÒÔ¹²ÏíÅäÖÃÐÅÏ¢ÖÐÄÇЩ¹«¹²µÄ²¿·Ö¡£¼òµ¥µØËµ£¬ZooKeeper¿ÉÒÔ×÷Ϊһ¸ö¾ßÓи߿ÉÓÃÐÔµÄÅäÖô洢Æ÷£¬ÔÊÐí·Ö²¼Ê½Ó¦ÓõIJÎÓëÕß¼ìË÷ºÍ¸üÐÂÅäÖÃÎļþ¡£Ê¹ÓÃZooKeeperÖеĹ۲ì»úÖÆ£¬¿ÉÒÔ½¨Á¢Ò»¸ö»îÔ¾µÄÅäÖ÷þÎñ£¬Ê¹ÄÇЩ¸ÐÐËȤµÄ¿Í»§¶ËÄܹ»»ñµÃÅäÖÃÐÅÏ¢Ð޸ĵÄ֪ͨ¡£
ÏÂÃæÀ´±àдһ¸öÕâÑùµÄ·þÎñ¡£ÎÒÃÇͨ¹ýÁ½¸ö¼ÙÉèÀ´¼ò»¯ËùÐèʵÏֵķþÎñ£¨ÉÔ¼ÓÐ޸ľͿÉÒÔÈ¡ÏûÕâÁ½¸ö¼ÙÉ裩¡£
µÚÒ»£¬ÎÒÃÇΨһÐèÒª´æ´¢µÄÅäÖÃÊý¾ÝÊÇ×Ö·û´®£¬¹Ø¼ü×ÖÊÇznodeµÄ·¾¶£¬Òò´ËÎÒÃÇÔÚÿ¸öznodeÉÏ´æ´¢ÁËÒ»¸ö¼ü£¯Öµ¶Ô¡£
µÚ¶þ£¬ÔÚÈκÎʱºòÖ»ÓÐÒ»¸ö¿Í»§¶Ë»áÖ´ÐиüвÙ×÷¡£
³ý´ËÖ®Í⣬Õâ¸öÄ£ÐÍ¿´ÆðÀ´¾ÍÏñÊÇÓÐÒ»¸öÖ÷ÈË(ÀàËÆÓÚHDFSÖеÄnamenode)ÔÚ¸üÐÂÐÅÏ¢£¬¶øËûµÄ¹¤ÈËÔòÐèÒª×ñÑÕâЩÐÅÏ¢¡£
ÔÚÃûΪActiveKeyValueStoreµÄÀàÖбàдÁËÈçÏ´úÂ룺
package org.zk;
import java.nio.charset.Charset;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;
public class ActiveKeyValueStore extends ConnectionWatcher {
private static final Charset CHARSET=Charset.forName("UTF-8");
public void write(String path,String value) throws KeeperException, InterruptedException {
Stat stat = zk.exists(path, false);
if(stat==null){
zk.create(path, value.getBytes(CHARSET),Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}else{
zk.setData(path, value.getBytes(CHARSET),-1);
}
}
public String read(String path,Watcher watch) throws KeeperException, InterruptedException{
byte[] data = zk.getData(path, watch, null);
return new String(data,CHARSET);
}
}
|
write()·½·¨µÄÈÎÎñÊǽ«Ò»¸ö¹Ø¼ü×Ö¼°Æäֵдµ½ZooKeeper¡£ËüÒþ²ØÁË´´½¨Ò»¸öеÄznodeºÍÓÃÒ»¸öÐÂÖµ¸üÐÂÏÖÓÐznodeÖ®¼äµÄÇø±ð£¬¶øÊÇʹÓÃexists²Ù×÷À´¼ì²âznodeÊÇ·ñ´æÔÚ£¬È»ºóÔÙÖ´ÐÐÏàÓ¦µÄ²Ù×÷¡£ÆäËûÖµµÃÒ»ÌáµÄϸ½ÚÊÇÐèÒª½«×Ö·û´®Öµ×ª»»Îª×Ö½ÚÊý×飬ÒòΪÎÒÃÇÖ»ÓÃÁËUTF-8±àÂëµÄgetBytes()·½·¨¡£
read()·½·¨µÄÈÎÎñÊǶÁȡһ¸ö½ÚµãµÄÅäÖÃÊôÐÔ¡£ZooKeeperµÄgetData()·½·¨ÓÐÈý¸ö²ÎÊý£º
£¨1£©Â·¾¶
£¨2£©Ò»¸ö¹Û²ì¶ÔÏó
£¨3£©Ò»¸öStat¶ÔÏó
Stat¶ÔÏóÓÉgetData()·½·¨·µ»ØµÄÖµÌî³ä£¬ÓÃÀ´½«ÐÅÏ¢»Ø´«¸øµ÷ÓÃÕß¡£Í¨¹ýÕâ¸ö·½·¨£¬µ÷ÓÃÕß¿ÉÒÔ»ñµÃÒ»¸öznodeµÄÊý¾ÝºÍÔªÊý¾Ý£¬µ«ÔÚÕâ¸öÀý×ÓÖУ¬ÓÉÓÚÎÒÃǶÔÔªÊý¾Ý²»¸ÐÐËȤ£¬Òò´Ë½«Stat²ÎÊýÉèΪnull¡£
ΪÁË˵Ã÷ActiveKeyValueStoreµÄÓ÷¨£¬ÎÒÃDZàдÁËÒ»¸öÓÃÀ´¸üÐÂÅäÖÃÊôÐÔÖµµÄÀàConfigUpdater£¬Èç´úÂë1.1Ëùʾ¡£
´úÂë1.1 ÓÃÓÚËæ»ú¸üÐÂZooKeeperÖеÄÊôÐÔ
package org.zk;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import org.apache.zookeeper.KeeperException;
public class ConfigUpdater {
public static final String PATH="/config";
private ActiveKeyValueStore store;
private Random random=new Random();
public ConfigUpdater(String hosts) throws IOException, InterruptedException {
store = new ActiveKeyValueStore();
store.connect(hosts);
}
public void run() throws InterruptedException, KeeperException{
while(true){
String value=random.nextInt(100)+"";
store.write(PATH, value);
System.out.printf("Set %s to %s\n",PATH,value);
TimeUnit.SECONDS.sleep(random.nextInt(100));
}
}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
ConfigUpdater configUpdater = new ConfigUpdater(args[0]);
configUpdater.run();
}
}
|
Õâ¸ö³ÌÐòºÜ¼òµ¥£¬ConfigUpdaterÖж¨ÒåÁËÒ»¸öActiveKeyValueStore£¬ËüÔÚConfigUpdaterµÄ¹¹Ô캯ÊýÖÐÁ¬½Óµ½ZooKeeper¡£run()·½·¨ÓÀÔ¶ÔÚÑ»·£¬ÔÚËæ»úʱ¼äÒÔËæ»úÖµ¸üÐÂ/config
znode¡£
×÷ΪÅäÖ÷þÎñµÄÓû§£¬ConfigWatcher´´½¨ÁËÒ»¸öActiveKeyValueStore¶ÔÏóstore£¬²¢ÇÒÔÚÆô¶¯Ö®ºóͨ¹ýdisplayConfig()µ÷ÓÃÁËstoreµÄread()·½·¨£¬ÏÔʾËüËù¶Áµ½µÄÅäÖÃÐÅÏ¢µÄ³õʼֵ£¬²¢½«×ÔÉí×÷Ϊ¹Û²ì´«µÝ¸østore¡£µ±½Úµã״̬·¢Éú±ä»¯Ê±£¬ÔÙ´Îͨ¹ýdisplayConfig()ÏÔʾÅäÖÃÐÅÏ¢£¬²¢Ôٴν«×ÔÉí×÷Ϊ¹Û²ì´«µÝ¸østore£¬²Î¼û´úÂë1.2£º
Àý1.2 ¸ÃÓÃÓ¦¹Û²ìZooKeeperÖÐÊôÐԵĸüÐÂÇé¿ö£¬²¢½«Æä´òÓ¡µ½¿ØÖÆÌ¨
package org.zk;
import java.io.IOException;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
public class ConfigWatcher implements Watcher{
private ActiveKeyValueStore store;
@Override
public void process(WatchedEvent event) {
if(event.getType()==EventType.NodeDataChanged){
try{
dispalyConfig();
}catch(InterruptedException e){
System.err.println("Interrupted. exiting. ");
Thread.currentThread().interrupt();
}catch(KeeperException e){
System.out.printf("KeeperExceptionï¼?s. Exiting.\n", e);
}
}
}
public ConfigWatcher(String hosts) throws IOException, InterruptedException {
store=new ActiveKeyValueStore();
store.connect(hosts);
}
public void dispalyConfig() throws KeeperException, InterruptedException{
String value=store.read(ConfigUpdater.PATH, this);
System.out.printf("Read %s as %s\n",ConfigUpdater.PATH,value);
}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
ConfigWatcher configWatcher = new ConfigWatcher(args[0]);
configWatcher.dispalyConfig();
//stay alive until process is killed or Thread is interrupted
Thread.sleep(Long.MAX_VALUE);
}
}
|
µ±ConfigUpdater¸üÐÂznodeʱ£¬ZooKeeper²úÉúÒ»¸öÀàÐÍΪEventType.NodeDataChangedµÄʼþ£¬´Ó¶ø´¥·¢¹Û²ì¡£ConfigWatcherÔÚËüµÄprocess()·½·¨ÖжÔÕâ¸öʼþ×ö³ö·´Ó¦£¬¶ÁÈ¡²¢ÏÔʾÅäÖõÄ×îа汾¡£ÓÉÓÚ¹Û²ì½ö·¢Ë͵¥´ÎÐźţ¬Òò´Ëÿ´ÎÎÒÃǵ÷ÓÃActiveKeyValueStoreµÄread()·½·¨Ê±£¬¶¼½«Ò»¸öÐÂµÄ¹Û²ì¸æÖªZooKeeperÀ´È·±£ÎÒÃÇ¿ÉÒÔ¿´µ½½«À´µÄ¸üС£µ«ÊÇ£¬ÎÒÃÇ»¹ÊDz»Äܱ£Ö¤½ÓÊÕµ½Ã¿Ò»¸ö¸üУ¬ÒòΪÔÚÊÕµ½¹Û²ìʼþ֪ͨÓëÏÂÒ»´Î¶ÁÖ®¼ä£¬znode¿ÉÄÜÒѾ±»¸üйý£¬¶øÇÒ¿ÉÄÜÊǺܶà´Î£¬ÓÉÓÚ¿Í»§¶ËÔÚÕâ¶Îʱ¼äûÓÐ×¢²áÈκι۲죬Òò´Ë²»»áÊÕµ½Í¨Öª¡£¶ÔÓÚʾÀýÖеÄÅäÖ÷þÎñ£¬Õâ²»ÊÇÎÊÌ⣬ÒòΪ¿Í»§¶ËÖ»¹ØÐÄÊôÐÔµÄ×îÐÂÖµ£¬×îÐÂÖµÓÅÏÈÓÚ֮ǰµÄÖµ¡£µ«ÊÇ£¬Ò»°ãÇé¿öÏ£¬Õâ¸öDZÔÚµÄÎÊÌâÊDz»ÈݺöÊӵġ£
ÈÃÎÒÃÇ¿´¿´ÈçºÎʹÓÃÕâ¸ö³ÌÐò¡£ÔÚÒ»¸öÖÕ¶Ë´°¿ÚÖÐÔËÐÐConfigUpdater£¬È»ºóÔÚÁíÒ»¸ö¿Í»§¶ËÔËÐÐConfigWatcher£¬ÎÒÃÇ¿ÉÒÔÔ¤ÏÈ·Ö±ðÔÚÁ½¸ö¿Í»§¶ËÊäÈëÃüÁÏȲ»°´»Ø³µ£¬µÈÁ½¸ö¿Í»§¶ËµÄÃüÁîÊäÈëºÃºó£¬ÏÈÔÚÔËÐÐConfigUpdaterµÄ¿Í»§¶Ë°´»Ø³µ£¬ÔÙÔÚÁíÒ»¸ö¿Í»§¶Ë°´»Ø³µ£¬ÔËÐнá¹ûÈçÏ£º

¶þ¡¢¿É»Ö¸´µÄZooKeeperÓ¦ÓÃ
¹ØÓÚ·Ö²¼Ê½¼ÆËãµÄµÚÒ»¸öÎóÇøÊÇ¡°ÍøÂçÊǿɿ¿µÄ¡±¡£°´ÕÕËûÃǵĹ۵㣬³ÌÐò×ÜÊÇÓÐÒ»¸ö¿É¿¿µÄÍøÂ磬Òò´Ëµ±³ÌÐòÔËÐÐÔÚÕæÕýµÄÍøÂçÖÐʱ£¬ÍùÍù»á³öÏÖ¸÷ÖÖ±¸ÑùµÄ¹ÊÕÏ¡£ÈÃÎÒÃÇ¿´¿´¸÷ÖÖ¿ÉÄܵĹÊÕÏģʽ£¬ÒÔ¼°Äܹ»½â¾ö¹ÊÕϵĴëÊ©£¬Ê¹ÎÒÃǵijÌÐòÔÚÃæ¶Ô¹ÊÕÏʱÄܹ»¼°Ê±¸´Ô¡£
2.1 ZooKeeperÒì³£
ÔÚJava APIÖеÄÿһ¸öZooKeeper²Ù×÷¶¼ÔÚÆäthrows×Ó¾äÖÐÉùÃ÷ÁËÁ½ÖÖÀàÐ͵ÄÒì³££¬·Ö±ðÊÇInterruptedExceptionºÍKeeperException¡£
£¨Ò»£©InterruptedExceptionÒì³£
Èç¹û²Ù×÷±»Öжϣ¬Ôò»áÓÐÒ»¸öInterruptedExceptionÒì³£±»Å׳ö¡£ÔÚJavaÓïÑÔÖÐÓÐÒ»¸öÈ¡Ïû×èÈû·½·¨µÄ±ê×¼»úÖÆ£¬¼´Õë¶Ô´æÔÚ×èÈû·½·¨µÄÏ̵߳÷ÓÃinterrupt()¡£Ò»¸ö³É¹¦µÄÈ¡Ïû²Ù×÷½«²úÉúÒ»¸öInterruptedExceptionÒì³£¡£
ZooKeeperÒ²×ñÑÕâÒ»»úÖÆ£¬Òò´ËÄã¿ÉÒÔʹÓÃÕâÖÖ·½·¨À´È¡ÏûÒ»¸öZooKeeper²Ù×÷¡£Ê¹ÓÃÁËZooKeeperµÄÀà»ò¿âͨ³£»á´«²¥InterruptedExceptionÒì³££¬Ê¹¿Í»§¶ËÄܹ»È¡ÏûËüÃǵIJÙ×÷¡£InterruptedExceptionÒì³£²¢²»Òâζ×ÅÓйÊÕÏ£¬¶øÊDZíÃ÷ÏàÓ¦µÄ²Ù×÷ÒѾ±»È¡Ïû£¬ËùÒÔÔÚÅäÖ÷þÎñµÄʾÀýÖУ¬¿ÉÒÔͨ¹ý´«²¥Òì³£À´ÖÐÖ¹Ó¦ÓóÌÐòµÄÔËÐС£
£¨¶þ£©KeeperExceptionÒì³£
(1) Èç¹ûZooKeeper·þÎñÆ÷·¢³öÒ»¸ö´íÎóÐźŻòÓë·þÎñÆ÷´æÔÚͨÐÅÎÊÌ⣬Å׳öµÄÔòÊÇKeeperExceptionÒì³£¡£
¢ÙÕë¶Ô²»Í¬µÄ´íÎóÇé¿ö£¬KeeperExceptionÒì³£´æÔÚ²»Í¬µÄ×ÓÀà¡£
ÀýÈç:¡¡KeeperException.NoNodeExceptionÊÇKeeperExceptionµÄÒ»¸ö×ÓÀ࣬Èç¹ûÄãÊÔͼÕë¶ÔÒ»¸ö²»´æÔÚµÄznodeÖ´ÐвÙ×÷£¬Å׳öµÄÔòÊǸÃÒì³£¡£
¢Úÿһ¸öKeeperExceptionÒì³£µÄ×ÓÀà¶¼¶ÔÓ¦Ò»¸ö¹ØÓÚ´íÎóÀàÐÍÐÅÏ¢µÄ´úÂë¡£
ÀýÈç:¡¡KeeperException.NoNodeExceptionÒì³£µÄ´úÂëÊÇKeeperException.Code.NONODE
(2) ÓÐÁ½ÖÖ·½·¨±»ÓÃÀ´´¦ÀíKeeperExceptionÒì³££º
¢Ù²¶×½KeeperExceptionÒì³££¬²¢ÇÒͨ¹ý¼ì²âËüµÄ´úÂëÀ´¾ö¶¨²ÉÈ¡ºÎÖÖ²¹¾È´ëÊ©£»
¢ÚÁíÒ»ÖÖÊDz¶×½µÈ¼ÛµÄKeeperException×ÓÀ࣬²¢ÇÒÔÚÿ¶Î²¶×½´úÂëÖÐÖ´ÐÐÏàÓ¦µÄ²Ù×÷¡£
(3) KeeperExceptionÒì³£·ÖΪÈý´óÀà
¢Ù ״̬Òì³£
µ±Ò»¸ö²Ù×÷Òò²»Äܱ»Ó¦ÓÃÓÚznodeÊ÷¶øµ¼ÖÂʧ°Üʱ£¬¾Í»á³öÏÖ״̬Òì³£¡£×´Ì¬Òì³£²úÉúµÄÔÒòͨ³£ÊÇÔÚͬһʱ¼äÓÐÁíÍâÒ»¸ö½ø³ÌÕýÔÚÐÞ¸Äznode¡£ÀýÈ磬Èç¹ûÒ»¸öznodeÏȱ»ÁíÍâÒ»¸ö½ø³Ì¸üÐÂÁË£¬¸ù¾Ý°æ±¾ºÅÖ´ÐÐsetData²Ù×÷µÄ½ø³Ì¾Í»áʧ°Ü£¬²¢ÊÕµ½Ò»¸öKeeperException.BadVersionExceptionÒì³££¬ÕâÊÇÒòΪ°æ±¾ºÅ²»Æ¥Åä¡£³ÌÐòԱͨ³£¶¼ÖªµÀÕâÖÖ³åÍ»×ÜÊÇ´æÔڵģ¬Ò²¶¼»á±àд´úÂëÀ´½øÐд¦Àí¡£
һЩ״̬Òì³£»áÖ¸³ö³ÌÐòÖеĴíÎó£¬ÀýÈçKeeperException.NoChildrenForEphemeralsExceptionÒì³££¬ÊÔͼÔÚ¶ÌÔÝznodeÏ´´½¨×Ó½Úµãʱ¾Í»áÅ׳ö¸ÃÒì³£¡£
¢Ú ¿É»Ö¸´Òì³£
¿É»Ö¸´µÄÒì³£ÊÇÖ¸ÄÇЩӦÓóÌÐòÄܹ»ÔÚͬһ¸öZooKeeper»á»°Öлָ´µÄÒì³£¡£Ò»¸ö¿É»Ö¸´µÄÒì³£ÊÇͨ¹ýKeeperException.ConnectionLossExceptionÀ´±íʾµÄ£¬ËüÒâζ×ÅÒѾ¶ªÊ§ÁËÓëZooKeeperµÄÁ¬½Ó¡£ZooKeeper»á³¢ÊÔÖØÐÂÁ¬½Ó£¬²¢ÇÒÔÚ´ó¶àÊýÇé¿öÏÂÖØÐÂÁ¬½Ó»á³É¹¦£¬²¢È·±£»á»°ÊÇÍêÕûµÄ¡£
µ«ÊÇZooKeeper²»ÄÜÅжÏÓëKeeperException.ConnectionLossExceptionÒì³£Ïà¹ØµÄ²Ù×÷ÊÇ·ñ³É¹¦Ö´ÐС£ÕâÖÖÇé¿ö¾ÍÊDz¿·Öʧ°ÜµÄÒ»¸öÀý×Ó¡£Õâʱ³ÌÐòÔ±ÓÐÔðÈÎÀ´½â¾öÕâÖÖ²»È·¶¨ÐÔ£¬²¢ÇÒ¸ù¾ÝÓ¦ÓõÄÇé¿öÀ´²ÉÈ¡Êʵ±µÄ²Ù×÷¡£ÔÚÕâÒ»µãÉÏ£¬¾ÍÐèÒª¶Ô¡°Ãݵȡ±(idempotent)²Ù×÷ºÍ¡°·ÇÃݵȡ±(Nonidempotent)²Ù×÷½øÐÐÇø·Ö¡£ÃݵȲÙ×÷ÊÇÖ¸ÄÇЩһ´Î»ò¶à´ÎÖ´Ðж¼»á²úÉúÏàͬ½á¹ûµÄ²Ù×÷£¬ÀýÈç¶ÁÇëÇó»òÎÞÌõ¼þÖ´ÐеÄsetData²Ù×÷¡£¶ÔÓÚÃݵȲÙ×÷£¬Ö»ÐèÒª¼òµ¥µØ½øÐÐÖØÊÔ¼´¿É¡£¶ÔÓÚ·ÇÃݵȲÙ×÷£¬¾Í²»ÄÜäĿµØ½øÐÐÖØÊÔ£¬ÒòΪËüÃǶà´ÎÖ´ÐеĽá¹ûÓëÒ»´ÎÖ´ÐÐÊÇÍêÈ«²»Í¬µÄ¡£³ÌÐò¿ÉÒÔͨ¹ýÔÚznodeµÄ·¾¶ºÍËüµÄÊý¾ÝÖбàÂëÐÅÏ¢À´¼ì²âÊÇ·ñ·ÇÃݵȲÙâôµÄ¸üÐÂÒѾÍê³É¡£
¢Û²»¿É»Ö¸´µÄÒì³£
ÔÚijЩÇé¿öÏ£¬ZooKeeper»á»°»áʧЧ¡ª¡ªÒ²ÐíÒòΪ³¬Ê±»òÒòΪ»á»°±»¹Ø±Õ£¬Á½ÖÖÇé¿ö϶¼»áÊÕµ½KeeperException.SessionExpiredExceptionÒì³££¬»òÒòΪÉí·ÝÑé֤ʧ°Ü£¬KeeperException.AuthFailedExceptionÒì³£¡£ÎÞÂÛÉÏÊöÄÄÖÖÇé¿ö£¬ËùÓÐÓë»á»°Ïà¹ØÁªµÄ¶ÌÔÝznode¶¼½«¶ªÊ§£¬Òò´ËÓ¦ÓóÌÐòÐèÒªÔÚÖØÐÂÁ¬½Óµ½ZooKeeperÖ®Ç°ÖØ½¨ËüµÄ״̬¡£
2.2 ¿É¿¿µØ·þÎñÅäÖÃ
Ê×ÏÈÎÒÃÇÏȻعËÒ»ÏÂActivityKeyValueStoreµÄwrite£¨£©µÄ·½·¨£¬ËûÓÉÒ»¸öexists²Ù×÷½ô¸ú×ÅÒ»¸öcreate²Ù×÷»òsetData²Ù×÷×é³É£º
public class ActiveKeyValueStore extends ConnectionWatcher {
private static final Charset CHARSET=Charset.forName("UTF-8");
public void write(String path,String value) throws KeeperException, InterruptedException {
Stat stat = zk.exists(path, false);
if(stat==null){
zk.create(path, value.getBytes(CHARSET),Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}else{
zk.setData(path, value.getBytes(CHARSET),-1);
}
}
public String read(String path,Watcher watch) throws KeeperException, InterruptedException{
byte[] data = zk.getData(path, watch, null);
return new String(data,CHARSET);
}
}
|
×÷Ϊһ¸öÕûÌ壬write()·½·¨ÊÇÒ»¸ö¡°Ãݵȡ±²Ù×÷£¬ËùÒÔÎÒÃÇ¿ÉÒÔ¶ÔËû½øÐÐÎÞÌõ¼þÖØÊÔ¡£ÎÒÃÇн¨Ò»¸öÀàChangedActiveKeyValueStore£¬´úÂëÈçÏ£º
package org.zk;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;
public class ChangedActiveKeyValueStore extends ConnectionWatcher{
private static final Charset CHARSET=Charset.forName("UTF-8");
private static final int MAX_RETRIES = 5;
private static final long RETRY_PERIOD_SECONDS = 5;
public void write(String path,String value) throws InterruptedException, KeeperException{
int retries=0;
while(true){
try {
Stat stat = zk.exists(path, false);
if(stat==null){
zk.create(path, value.getBytes(CHARSET),Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}else{
zk.setData(path, value.getBytes(CHARSET),stat.getVersion());
}
} catch (KeeperException.SessionExpiredException e) {
throw e;
} catch (KeeperException e) {
if(retries++==MAX_RETRIES){
throw e;
}
//sleep then retry
TimeUnit.SECONDS.sleep(RETRY_PERIOD_SECONDS);
}
}
}
public String read(String path,Watcher watch) throws KeeperException, InterruptedException{
byte[] data = zk.getData(path, watch, null);
return new String(data,CHARSET);
}
}
|
ÔÚ¸ÃÀàÖУ¬¶ÔÇ°ÃæµÄwrite()½øÐÐÁËÐÞ¸Ä,¸Ã°æ±¾µÄwirte()Äܹ»Ñ»·Ö´ÐÐÖØÊÔ¡£ÆäÖÐÉèÖÃÁËÖØÊÔµÄ×î´ó´ÎÊýMAX_RETRIESºÍÁ½´ÎÖØÊÔÖ®¼äµÄ¼ä¸ôRETRY_PERIOD_SECONDS.
ÎÒÃÇÔÙн¨Ò»¸öÀàResilientConfigUpdater£¬¸ÃÀà¶ÔÇ°ÃæµÄConfigUpdater½øÐÐÁËÐ޸쬴úÂëÈçÏ£º
package org.zk;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.KeeperException.SessionExpiredException;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;
public class ResilientConfigUpdater extends ConnectionWatcher{
public static final String PATH="/config";
private ChangedActiveKeyValueStore store;
private Random random=new Random();
public ResilientConfigUpdater(String hosts) throws IOException, InterruptedException {
store=new ChangedActiveKeyValueStore();
store.connect(hosts);
}
public void run() throws InterruptedException, KeeperException{
while(true){
String value=random.nextInt(100)+"";
store.write(PATH,value);
System.out.printf("Set %s to %s\n",PATH,value);
TimeUnit.SECONDS.sleep(random.nextInt(10));
}
}
public static void main(String[] args) throws Exception {
while(true){
try {
ResilientConfigUpdater configUpdater = new ResilientConfigUpdater(args[0]);
configUpdater.run();
}catch (KeeperException.SessionExpiredException e) {
// start a new session
}catch (KeeperException e) {
// already retried ,so exit
e.printStackTrace();
break;
}
}
}
}
|
ÔÚÕâ¶Î´úÂëÖÐûÓжÔKeepException.SeeionExpiredExceptionÒì³£½øÐÐÖØÊÔ£¬ÒòΪһ¸ö»á»°¹ýÆÚʱ£¬ZooKeeper¶ÔÏó»á½øÈëCLOSED״̬£¬´Ë״̬ÏÂËü²»ÄܽøÐÐÖØÊÔÁ¬½Ó¡£ÎÒÃÇÖ»Äܽ«Õâ¸öÒì³£¼òµ¥Å׳ö²¢ÈÃÓµÓÐ×Å´´½¨Ò»¸öÐÂʵÀý£¬ÒÔÖØÊÔÕû¸öwrite()·½·¨¡£Ò»¸ö¼òµ¥µÄ´´½¨ÐÂʵÀýµÄ·½·¨ÊÇ´´½¨Ò»¸öеÄResilientConfigUpdaterÓÃÓÚ»Ö¸´¹ýÆÚ»á»°¡£
´¦Àí»á»°¹ýÆÚµÄÁíÒ»ÖÖ·½·¨ÊÇÔÚ¹Û²ìÖУ¨ÔÚÕâ¸öÀý×ÓÖÐÓ¦¸ÃÊÇConnectionWatcher£©Ñ°ÕÒÀàÐÍΪExpiredKeepState£¬È»ºóÔÙÕÒµ½µÄʱºò´´½¨Ò»¸öÐÂÁ¬½Ó¡£¼´Ê¹ÎÒÃÇÊÕµ½KeeperException.SessionExpiredEceptionÒì³££¬ÕâÖÖ·½·¨»¹ÊÇ¿ÉÒÔÈÃÎÒÃÇÔÚwrite£¨£©·½·¨ÄÚ²»¶ÏÖØÊÔ£¬ÒòΪÁ¬½Ó×îÖÕÊÇÄܹ»ÖØÐ½¨Á¢µÄ¡£²»¹ÜÎÒÃDzÉÓúÎÖÖ»úÖÆ´Ó¹ýÆÚ»á»°Öлָ´£¬ÖØÒªµÄÊÇ£¬ÕâÖÖ²»Í¬ÓÚÁ¬½Ó¶ªÊ§µÄ¹ÊÕÏÀàÐÍ£¬ÐèÒª½øÐв»Í¬µÄ´¦Àí¡£
×¢Ò⣺
ʵ¼ÊÉÏ,ÕâÀïºöÂÔÁËÁíÒ»ÖÖ¹ÊÕÏģʽ¡£µ±ZooKeeper¶ÔÏó±»´´½¨Ê±£¬Ëû»á³¢ÊÔÁ¬½ÓÁíÒ»¸öZooKeeper·þÎñÆ÷¡£Èç¹ûÁ¬½Óʧ°Ü»ò³¬Ê±£¬ÄÇôËû»á³¢ÊÔÁ¬½Ó¼¯ºÏÌåÖеÄÁíһ̨·þÎñÆ÷¡£Èç¹ûÔÚ³¢ÊÔ¼¯ºÏÌåÖеÄËùÓзþÎñÆ÷Ö®ºóÈÔÈ»ÎÞ·¨½¨Á¢Á¬½Ó£¬Ëü»áÅ׳öÒ»¸öIOExceptionÒì³£¡£ÓÉÓÚËùÓеÄZooKeeper·þÎñÆ÷¶¼²»¿ÉÓõĿÉÄÜÐÔºÜС£¬ËùÒÔijЩӦÓóÌÐòÑ¡ÔñÑ»·ÖØÊÔ²Ù×÷£¬Ö±µ½ZooKeeper·þÎñΪֹ¡£
Õâ½ö½öÊÇÒ»ÖÖÖØÊÔ´¦Àí²ßÂÔ£¬»¹ÓÐÐí¶àÆäËû´¦Àí²ßÂÔ£¬ÀýÈçʹÓá°Ö¸Êý·µ»Ø¡±£¬Ã¿´Î½«ÖØÊԵļä¸ô³ËÒÔÒ»¸ö³£Êý¡£HadoopÄÚºËÖÐorg.apache.hadoop.io.retry°üÊÇÒ»×鹤¾ß£¬ÓÃÓÚ¿ÉÒÔÖØÓõķ½Ê½½«ÖØÊÔÂß¼¼ÓÈë´úÂ룬Òò´ËËû¶ÔÓÚ¹¹½¨ZooKeeperÓ¦Ó÷dz£ÓÐÓá£
Èý¡¢Ëø·þÎñ
3.1·Ö²¼Ê½Ëø¸ÅÊö
·Ö²¼Ê½ËøÔÚÒ»×é½ø³ÌÖ®¼äÌṩÁËÒ»ÖÖ»¥³â»úÖÆ¡£ÔÚÈκÎʱ¿Ì£¬ÔÚÈκÎʱ¿ÌÖ»ÓÐÒ»¸ö½ø³Ì¿ÉÒÔ³ÖÓÐËø¡£·Ö²¼Ê½Ëø¿ÉÒÔÔÚ´óÐÍ·Ö²¼Ê½ÏµÍ³ÖÐʵÏÖÁìµ¼ÕßÑ¡¾Ù£¬ÔÚÈκÎʱ¼äµã£¬³ÖÓÐËøµÄÄǸö½ø³Ì¾ÍÊÇϵͳµÄÁìµ¼Õß¡£
×¢Òâ
²»Òª½«ZooKeeper×Ô¼ºµÄÁìµ¼ÕßÑ¡¾ÙºÍʹÓÃÁËZooKeeper»ù±¾²Ù×÷ʵÏÖµÄÒ»°ãÁìµ¼ÕßÑ¡»ìΪһ̸¡£ZooKeeper×Ô¼ºµÄÁìµ¼ÕßÑ¡¾Ù»úÖÆÊǶÔÍâ²»¹«¿ªµÄ£¬ÎÒÃÇÕâÀïËùÃèÊöµÄÒ»°ãÁìµ¼ÕßÑ¡¾Ù·þÎñÔò²»Í¬£¬ËûÊǶÔÄÇЩÐèÒªÓëÖ÷½ø³Ì±£³ÖÒ»Öµķֲ¼Ê½ÏµÍ³ËùÉè¼ÆµÄ¡£
(1) ΪÁËʹÓÃZooKeeperÀ´ÊµÏÖ·Ö²¼Ê½Ëø·þÎñ£¬ÎÒÃÇʹÓÃ˳ÐòznodeÀ´ÎªÄÇЩ¾ºÕùËøµÄ½ø³ÌÇ¿ÖÆÅÅÐò¡£
˼·ºÜ¼òµ¥£º
¢Ù Ê×ÏÈÖ¸¶¨Ò»¸ö×÷ÎªËøµÄznode£¬Í¨³£ÓÃËüÀ´ÃèÊö±»Ëø¶¨µÄʵÌ壬³ÆÎª/leader£»
¢Ú È»ºóÏ£Íû»ñµÃËøµÄ¿Í»§¶Ë´´½¨Ò»Ð©¶ÌÔÝ˳Ðòznode£¬×÷ÎªËøznodeµÄ×ӽڵ㡣
¢Û ÔÚÈκÎʱ¼äµã£¬Ë³ÐòºÅ×îСµÄ¿Í»§¶Ë½«³ÖÓÐËø¡£
ÀýÈ磬ÓÐÁ½¸ö¿Í»§¶Ë²î²»¶àͬʱ´´½¨znode£¬·Ö±ðΪ/leader/lock-1ºÍ/leader/lock-2£¬ÄÇô´´½¨/leader/lock-1µÄ¿Í»§¶Ë½«»á³ÖÓÐËø£¬ÒòΪËüµÄznode˳ÐòºÅ×îС¡£ZooKeeper·þÎñÊÇ˳ÐòµÄÖÙ²ÃÕߣ¬ÒòΪËü¸ºÔð·ÖÅä˳ÐòºÅ¡£
¢Ü ͨ¹ýɾ³ýznode /leader/lock-l¼´¿É¼òµ¥µØ½«ËøÊÍ·Å£»
¢Ý ÁíÍ⣬Èç¹û¿Í»§¶Ë½ø³ÌËÀÍö£¬¶ÔÓ¦µÄ¶ÌÔÝznodeÒ²»á±»É¾³ý¡£
¢Þ ½ÓÏÂÀ´£¬´´½¨/leader/lock-2µÄ¿Í»§¶Ë½«³ÖÓÐËø£¬ÒòΪËü˳ÐòºÅ½ô¸úǰһ¸ö¡£
¢ß ͨ¹ý´´½¨Ò»¸ö¹ØÓÚznodeɾ³ýµÄ¹Û²ì£¬¿ÉÒÔʹ¿Í»§¶ËÔÚ»ñµÃËøÊ±µÃµ½Í¨Öª¡£
(2) ÈçÏÂÊÇÉêÇë»ñÈ¡ËøµÄα´úÂë¡£
¢ÙÔÚËøznodeÏ´´½¨Ò»¸öÃûΪlock-µÄ¶ÌÔÝ˳Ðòznode£¬²¢ÇÒ¼ÇסËüµÄʵ¼Ê·¾¶Ãû(create²Ù×÷µÄ·µ»ØÖµ)¡£
¢Ú²éÑ¯ËøznodeµÄ×ӽڵ㲢ÇÒÉèÖÃÒ»¸ö¹Û²ì¡£
¢ÛÈç¹û²½ÖèlÖÐËù´´½¨µÄznodeÔÚ²½Öè2ÖÐËù·µ»ØµÄËùÓÐ×Ó½ÚµãÖоßÓÐ×îСµÄ˳ÐòºÅ£¬Ôò»ñÈ¡µ½Ëø¡£Í˳ö¡£
¢ÜµÈ´ý²½Öè2ÖÐËùÉè¹Û²ìµÄ֪ͨ²¢ÇÒתµ½²½Öè2¡£
3.2 µ±Ç°ÎÊÌâÓë·½°¸
3.2.1 ÑòȺЧӦ
(1) ÎÊÌâ
ËäÈ»Õâ¸öËã·¨ÊÇÕýÈ·µÄ£¬µ«»¹ÊÇ´æÔÚһЩÎÊÌâ¡£µÚÒ»¸öÎÊÌâÊÇÕâÖÖʵÏÖ»áÊܵ½¡°ÑòȺЧӦ¡±(herd effect)µÄÓ°Ïì¡£¿¼ÂÇÓгɰÙÉÏǧ¿Í»§¶ËµÄÇé¿ö£¬ËùÓеĿͻ§¶Ë¶¼ÔÚ³¢ÊÔ»ñµÃËø£¬Ã¿¸ö¿Í»§¶Ë¶¼»áÔÚËøznodeÉÏÉèÖÃÒ»¸ö¹Û²ì£¬ÓÃÓÚ²¶×½×Ó½ÚµãµÄ±ä»¯¡£Ã¿´ÎËø±»ÊÍ·Å»òÁíÍâÒ»¸ö½ø³Ì¿ªÊ¼ÉêÇë»ñÈ¡ËøµÄʱºò£¬¹Û²ì¶¼»á±»´¥·¢²¢ÇÒÿ¸ö¿Í»§¶Ë¶¼»áÊÕµ½Ò»¸ö֪ͨ¡£
¡°ÑòȺЧӦ¡°¾ÍÊÇÖ¸´óÁ¿¿Í»§¶ËÊÕµ½Í¬Ò»Ê¼þµÄ֪ͨ£¬µ«Êµ¼ÊÉÏÖ»ÓкÜÉÙÒ»²¿·ÖÐèÒª´¦ÀíÕâһʼþ¡£ÔÚÕâÖÖÇé¿öÏ£¬Ö»ÓÐÒ»¸ö¿Í»§¶Ë»á³É¹¦µØ»ñÈ¡Ëø£¬µ«ÊÇά»¤¹ý³Ì¼°ÏòËùÓпͻ§¶Ë·¢Ë͹۲ìʼþ»á²úÉú·åÖµÁ÷Á¿£¬Õâ»á¶ÔZooKeeper·þÎñÆ÷Ôì³ÉѹÁ¦¡£
(2) ·½°¸½â¾ö·½°¸
ΪÁ˱ÜÃâ³öÏÖÑòȺЧӦ£¬ÎÒÃÇÐèÒªÓÅ»¯Í¨ÖªµÄÌõ¼þ¡£¹Ø¼üÔÚÓÚÖ»ÓÐÔÚǰһ¸ö˳ÐòºÅµÄ×Ó½ÚµãÏûʧʱ²ÅÐèҪ֪ͨÏÂÒ»¸ö¿Í»§¶Ë£¬¶ø²»ÊÇɾ³ý£¨»ò´´½¨£©ÈκÎ×Ó½Úµãʱ¶¼ÐèҪ֪ͨ¡£ÔÚÎÒÃǵÄÀý×ÓÖУ¬Èç¹û¿Í»§¶Ë´´½¨ÁËznode
/leader/lock-1¡¢/leader/lock-2ºÍ£¯leader/lock-3£¬ÄÇôֻÓе±/leader/lock-2Ïûʧʱ²ÅÐèҪ֪ͨ£¯leader/lock-3¶ÔÕյĿͻ§¶Ë£»/leader/lock-1Ïûʧ»òÓÐеÄznode
/leader/lock-4¼ÓÈëʱ£¬²»ÐèҪ֪ͨ¸Ã¿Í»§¶Ë¡£
3.2.2 ¿É»Ö¸´µÄÒì³£
(1) ÎÊÌâ
Õâ¸öÉêÇëËøµÄË㷨Ŀǰ»¹´æÔÚÁíÒ»¸öÎÊÌ⣬¾ÍÊDz»ÄÜ´¦ÀíÒòÁ¬½Ó¶ªÊ§¶øµ¼ÖµÄcreate²Ù×÷ʧ°Ü¡£ÈçǰËùÊö£¬ÔÚÕâÖÖÇé¿öÏ£¬ÎÒÃDz»ÖªµÀ²Ù×÷Êdzɹ¦»¹ÊÇʧ°Ü¡£ÓÉÓÚ´´½¨Ò»¸ö˳ÐòznodeÊÇ·ÇÃݵȲÙ×÷£¬ËùÒÔÎÒÃDz»Äܼòµ¥µØÖØÊÔ£¬ÒòΪÈç¹ûµÚÒ»´Î´´½¨ÒѾ³É¹¦£¬ÖØÊÔ»áʹÎÒÃǶà³öÒ»¸öÓÀԶɾ²»µôµÄ¹Â¶ùzriode(ÖÁÉÙµ½¿Í»§¶Ë»á»°½áÊøÇ°£©¡£²»ÐҵĽá¹ûÊǽ«»á³öÏÖËÀËø¡£
(2) ½â¾ö·½°¸
ÎÊÌâÔÚÓÚ£¬ÔÚÖØÐÂÁ¬½ÓÖ®ºó¿Í»§¶Ë²»Äܹ»ÅжÏËüÊÇ·ñÒѾ´´½¨¹ý×ӽڵ㡣½â¾ö·½°¸ÊÇÔÚznodeµÄÃû³ÆÖÐǶÈëÒ»¸öID£¬Èç¹û¿Í»§¶Ë³öÏÖÁ¬½Ó¶ªÊ§µÄÇé¿ö£¬ÖØÐÂÁ¬½ÓÖ®ºóËü±ã¿ÉÒÔ¶ÔËø½ÚµãµÄËùÓÐÓÚ½Úµã½øÐмì²é£¬¿´¿´ÊÇ·ñÓÐ×Ó½ÚµãµÄÃû³ÆÖаüº¬ÆäID¡£Èç¹ûÓÐÒ»¸ö×Ó½ÚµãµÄÃû³Æ°üº¬ÆäID£¬Ëü±ãÖªµÀ´´½¨²Ù×÷ÒѾ³É¹¦£¬²»ÐèÒªÔÙ´´½¨×ӽڵ㡣Èç¹ûûÓÐ×Ó½ÚµãµÄÃû³ÆÖаüº¬ÆäID£¬Ôò¿Í»§¶Ë¿ÉÒÔ°²È«µØ´´½¨Ò»¸öеÄ˳Ðò×ӽڵ㡣
¿Í»§¶Ë»á»°µÄIDÊÇÒ»¸ö³¤ÕûÊý£¬²¢ÇÒÔÚZooKeeper·þÎñÖÐÊÇΨһµÄ£¬Òò´Ë·Ç³£ÊʺÏÔÚÁ¬½Ó¶ªÊ§ºóÓÃÓÚʶ±ð¿Í»§¶Ë¡£¿ÉÒÔͨ¹ýµ÷ÓÃJava
ZooKeeperÀàµÄgetSessionld()·½·¨À´»ñµÃ»á»°µÄID¡£
ÔÚ´´½¨¶ÌÔÝ˳ÐòznodeʱӦµ±²ÉÓÃlock-<sessionld>-ÕâÑùµÄÃüÃû·½Ê½£¬ZooKeeperÔÚÆäβ²¿Ìí¼Ó˳ÐòºÅÖ®ºó£¬znodeµÄÃû³Æ»áÐÎÈçlock-<sessionld>-<sequenceNumber>¡£ÓÉÓÚ˳ÐòºÅ¶ÔÓÚ¸¸½ÚµãÀ´ËµÊÇΨһµÄ£¬µ«¶ÔÓÚ×Ó½ÚµãÃû²¢²»Î¨Ò»£¬Òò´Ë²ÉÓÃÕâÑùµÄÃüÃû·½Ê½¿ÉÒÔÚ´×Ó½ÚµãÔÚ±£³Ö´´½¨Ë³ÐòµÄͬʱÄܹ»È·¶¨×Ô¼ºµÄ´´½¨Õß¡£
3.2.3 ²»¿É»Ö¸´µÄÒì³£
Èç¹ûÒ»¸ö¿Í»§¶ËµÄZooKeeper»á»°¹ýÆÚ£¬ÄÇôËüËù´´½¨µÄ¶ÌÔÝznode½«»á±»É¾³ý£¬ÒѳÖÓеÄËø»á±»ÊÍ·Å£¬»òÊÇ·ÅÆúÁËÉêÇëËøµÄλÖá£Ê¹ÓÃËøµÄÓ¦ÓóÌÐòÓ¦µ±Òâʶµ½ËüÒѾ²»ÔÙ³ÖÓÐËø£¬Ó¦µ±ÇåÀíËüµÄ״̬£¬È»ºóͨ¹ý´´½¨²¢³¢ÊÔÉêÇëÒ»¸öеÄËø¶ÔÏóÀ´ÖØÐÂÆô¶¯¡£×¢Ò⣬Õâ¸ö¹ý³ÌÊÇÓÉÓ¦ÓóÌÐò¿ØÖƵ쬶ø²»ÊÇËø£¬ÒòÎªËøÊDz»ÄÜÔ¤ÖªÓ¦ÓóÌÐòÐèÒªÈçºÎÇåÀí×Ô¼ºµÄ״̬¡£
ËÄ¡¢ZooKeeperʵÏÖ¹²ÏíËø
ʵÏÖÕýÈ·µØÊµÏÖÒ»¸ö·Ö²¼Ê½ËøÊÇÒ»¼þ¼¬ÊÖµÄÊ£¬ÒòΪºÜÄѶÔËùÓÐÀàÐ͵ĹÊÕ϶¼½øÐÐÕýÈ·µÄ½âÊÍ´¦Àí¡£ZooKeeper´øÓÐÒ»¸öJavaWriteLock£¬¿Í»§¶Ë¿ÉÒԺܷ½±ãµØÊ¹ÓÃËü¡£¸ü¶à·Ö²¼Ê½Êý¾Ý½á¹¹ºÍÐÒéÀýÈç¡°ÆÁÕÏ¡±(bafrier)¡¢¶ÓÁкÍÁ½½×¶ÎÌá½»ÐÒé¡£ÓÐȤµÄÊÇËüÃǶ¼ÊÇͬ²½ÐÒ飬¼´Ê¹ÎÒÃÇʹÓÃÒì²½ZooKeeper»ù±¾²Ù×÷£¨Èç֪ͨ£©À´ÊµÏÖËüÃÇ¡£Ê¹ÓÃZooKeeper¿ÉÒÔʵÏֺܶ಻ͬµÄ·Ö²¼Ê½Êý¾Ý½á¹¹ºÍÐÒ飬ZooKeeperÍøÕ¾(http://hadoop.apache.org/zookeeper/)ÌṩÁËһЩÓÃÓÚʵÏÖ·Ö²¼Ê½Êý¾Ý½á¹¹ºÍÐÒéµÄα´úÂë¡£ZooKeeper±¾ÉíÒ²´øÓÐÒ»Ð©×Ø×¼·½·¨µÄʵÏÖ£¬·ÅÔÚ°²×°Î»ÖÃϵÄrecipesĿ¼ÖС£
4.1 ³¡¾°ÃèÊö
´ó¼ÒÒ²Ðí¶¼ºÜÊìϤÁ˶à¸öÏ̻߳òÕß¶à¸ö½ø³Ì¼äµÄ¹²ÏíËøµÄʵÏÖ·½Ê½ÁË£¬µ«ÊÇÔÚ·Ö²¼Ê½³¡¾°ÖÐÎÒÃÇ»áÃæÁÙ¶à¸öServerÖ®¼äµÄËøµÄÎÊÌâ¡£
¼ÙÉèÓÐÕâÑùÒ»¸ö³¡¾°£ºÁ½Ì¨server £ºserverA£¬serverBÐèÒªÔÚC»úÆ÷ÉϵÄ/usr/local/a.txtÎļþÉϽøÐÐд²Ù×÷£¬Èç¹ûÁ½Ì¨»úÆ÷ͬʱд¸ÃÎļþ£¬ÄÇô¸ÃÎļþµÄ×îÖÕ½á¹û¿ÉÄÜ»á²úÉúÂÒÐòµÈÎÊÌâ¡£×îÏÈÄÜÏëµ½µÄÊÇserverAÔÚдÎļþǰ¸æËßServerB
¡°ÎÒÒª¿ªÊ¼Ð´ÎļþÁË£¬ÄãÏȱðд¡±£¬µÈ´ýÊÕµ½ServerBµÄÈ·Èϻظ´ºóServerA¿ªÊ¼Ð´Îļþ£¬Ð´ÍêÎļþºóÔÙ֪ͨServerB¡°ÎÒÒѾдÍêÁË¡±¡£¼ÙÉèÔÚÎÒÃdz¡¾°ÖÐÓÐ100̨»úÆ÷ÄØ£¬ÖмäÈÎÒâһ̨»úÆ÷ͨÐÅÖжÏÁËÓÖ¸ÃÈçºÎ´¦Àí£¿ÈÝ´íºÍÐÔÄÜÎÊÌâÄØ£¿ÒªÄܽ¡×³£¬Îȶ¨£¬¸ß¿ÉÓò¢±£³Ö¸ßÐÔÄÜ£¬ÏµÍ³ÊµÏֵĸ´ÔӶȱȽϸߣ¬´ÓÍ·¿ª·¢ÕâÑùµÄϵͳ´ú¼ÛÒ²ºÜ´ó¡£ÐÒÔ˵ÄÊÇ£¬ÎÒÃÇÓÐÁË»ùÓÚgooglechubbyÔÀí¿ª·¢µÄ¿ªÔ´µÄZooKeeperϵͳ¡£½ÓÏÂÀ´±¾ÎĽ«½éÉÜÁ½ÖÖZooKeeperʵÏÖ·Ö²¼Ê½¹²ÏíËøµÄ·½·¨¡£
4.2 ÀûÓýڵãÃû³ÆµÄΨһÐÔÀ´ÊµÏÖ¹²ÏíËø
ZooKeeper±íÃæÉϵĽڵã½á¹¹ÊÇÒ»¸öºÍunixÎļþϵͳÀàËÆµÄСÐ͵ÄÊ÷×´µÄĿ¼½á¹¹£¬ZooKeeper»úÖÆ¹æ¶¨£ºÍ¬Ò»¸öĿ¼ÏÂÖ»ÄÜÓÐÒ»¸öΨһµÄÎļþÃû¡£
ÀýÈ磺
ÎÒÃÇÔÚZookeeperĿ¼/testĿ¼Ï´´½¨£¬Á½¸ö¿Í»§¶Ë´´½¨Ò»¸öÃûΪlock½Úµã£¬Ö»ÓÐÒ»¸öÄܹ»³É¹¦¡£
(1) Ë㷨˼·£ºÀûÓÃÃû³ÆÎ¨Ò»ÐÔ£¬¼ÓËø²Ù×÷ʱ£¬Ö»ÐèÒªËùÓпͻ§¶ËÒ»Æð´´½¨/Leader/lock½Úµã£¬Ö»ÓÐÒ»¸ö´´½¨³É¹¦£¬³É¹¦Õß»ñµÃËø¡£½âËøÊ±£¬Ö»Ðèɾ³ý/test/Lock½Úµã£¬ÆäÓà¿Í»§¶ËÔٴνøÈ뾺Õù´´½¨½Úµã£¬Ö±µ½ËùÓпͻ§¶Ë¶¼»ñµÃËø¡£
»ùÓÚÒÔÉÏ»úÖÆ£¬ÀûÓýڵãÃû³ÆÎ¨Ò»ÐÔ»úÖÆµÄ¹²ÏíËøËã·¨Á÷³ÌÈçͼËùʾ£º

4.3 ÀûÓÃ˳Ðò½ÚµãʵÏÖ¹²ÏíËø
Ê×ÏȽéÉÜһϣ¬ZookeeperÖÐÓÐÒ»ÖÖ½Úµã½Ð×ö˳Ðò½Úµã£¬¹ÊÃû˼Ò飬¼ÙÈçÎÒÃÇÔÚ/lock/Ŀ¼Ï´´½¨½Ú3¸öµã£¬ZooKeeper¼¯Èº»á°´ÕÕÌáÆð´´½¨µÄ˳ÐòÀ´´´½¨½Úµã£¬½Úµã·Ö±ðΪ/lock/0000000001¡¢/lock/0000000002¡¢/lock/0000000003¡£
ZooKeeperÖл¹ÓÐÒ»ÖÖÃûΪÁÙʱ½ÚµãµÄ½Úµã£¬ÁÙʱ½ÚµãÓÉij¸ö¿Í»§¶Ë´´½¨£¬µ±¿Í»§¶ËÓëZooKeeper¼¯Èº¶Ï¿ªÁ¬½Ó£¬¡£Ôò¸Ã½Úµã×Ô¶¯±»É¾³ý¡£
Ë㷨˼·£º¶ÔÓÚ¼ÓËø²Ù×÷£¬¿ÉÒÔÈÃËùÓпͻ§¶Ë¶¼È¥/lockĿ¼Ï´´½¨ÁÙʱ¡¢Ë³Ðò½Úµã£¬Èç¹û´´½¨µÄ¿Í»§¶Ë·¢ÏÖ×ÔÉí´´½¨½ÚµãÐòÁкÅÊÇ/lock/Ŀ¼ÏÂ×îСµÄ½Úµã£¬Ôò»ñµÃËø¡£·ñÔò£¬¼àÊÓ±È×Ô¼º´´½¨½ÚµãµÄÐòÁкÅСµÄ½Úµã£¨µ±Ç°ÐòÁÐÔÚ×Ô¼ºÇ°ÃæÒ»¸öµÄ½Úµã£©£¬½øÈëµÈ´ý¡£½âËø²Ù×÷£¬Ö»ÐèÒª½«×ÔÉí´´½¨µÄ½Úµãɾ³ý¼´¿É¡£¾ßÌåËã·¨Á÷³ÌÈçÏÂͼËùʾ:

4.4 ZooKeeperÌṩµÄÒ»¸öÐ´ËøÊµÏÖ
°´ÕÕZooKeeperÌṩµÄ·Ö²¼Ê½ËøµÄα´úÂ룬ʵÏÖÁËÒ»¸ö·Ö²¼Ê½ËøµÄ¼òµ¥²âÊÔ´úÂëÈçÏ£º
£¨1£©·Ö²¼Ê½Ëø£¬ÊµÏÖÁËLock½Ó¿Ú DistributedLock.java
package com.concurrent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
/**
DistributedLock lock = null;
try {
lock = new DistributedLock("127.0.0.1:2182","test");
lock.lock();
//do something...
} catch (Exception e) {
e.printStackTrace();
}
finally {
if(lock != null)
lock.unlock();
}
* @author xueliang
*
*/
public class DistributedLock implements Lock, Watcher{
private ZooKeeper zk;
private String root = "/locks";//¸ù
private String lockName;//¾ºÕù×ÊÔ´µÄ±êÖ¾
private String waitNode;//µÈ´ýǰһ¸öËø
private String myZnode;//µ±Ç°Ëø
private CountDownLatch latch;//¼ÆÊýÆ÷
private int sessionTimeout = 30000;
private List exception = new ArrayList();
/**
* ´´½¨·Ö²¼Ê½Ëø,ʹÓÃǰÇëÈ·ÈÏconfigÅäÖõÄzookeeper·þÎñ¿ÉÓÃ
* @param config 127.0.0.1:2181
* @param lockName ¾ºÕù×ÊÔ´±êÖ¾,lockNameÖв»Äܰüº¬µ¥´Êlock
*/
public DistributedLock(String config, String lockName){
this.lockName = lockName;
// ´´½¨Ò»¸öÓë·þÎñÆ÷µÄÁ¬½Ó
try {
zk = new ZooKeeper(config, sessionTimeout, this);
Stat stat = zk.exists(root, false);
if(stat == null){
// ´´½¨¸ù½Úµã
zk.create(root, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
}
} catch (IOException e) {
exception.add(e);
} catch (KeeperException e) {
exception.add(e);
} catch (InterruptedException e) {
exception.add(e);
}
}
/**
* zookeeper½ÚµãµÄ¼àÊÓÆ÷
*/
public void process(WatchedEvent event) {
if(this.latch != null) {
this.latch.countDown();
}
}
public void lock() {
if(exception.size() > 0){
throw new LockException(exception.get(0));
}
try {
if(this.tryLock()){
System.out.println("Thread " + Thread.currentThread().getId() + " " +myZnode + " get lock true");
return;
}
else{
waitForLock(waitNode, sessionTimeout);//µÈ´ýËø
}
} catch (KeeperException e) {
throw new LockException(e);
} catch (InterruptedException e) {
throw new LockException(e);
}
}
public boolean tryLock() {
try {
String splitStr = "_lock_";
if(lockName.contains(splitStr))
throw new LockException("lockName can not contains \\u000B");
//´´½¨ÁÙʱ×Ó½Úµã
myZnode = zk.create(root + "/" + lockName + splitStr, new byte[0],
ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(myZnode + " is created ");
//È¡³öËùÓÐ×Ó½Úµã
List subNodes = zk.getChildren(root, false);
//È¡³öËùÓÐlockNameµÄËø
List lockObjNodes = new ArrayList();
for (String node : subNodes) {
String _node = node.split(splitStr)[0];
if(_node.equals(lockName)){
lockObjNodes.add(node);
}
}
Collections.sort(lockObjNodes);
System.out.println(myZnode + "==" + lockObjNodes.get(0));
if(myZnode.equals(root+"/"+lockObjNodes.get(0))){
//Èç¹ûÊÇ×îСµÄ½Úµã,Ôò±íʾȡµÃËø
return true;
}
//Èç¹û²»ÊÇ×îСµÄ½Úµã£¬ÕÒµ½±È×Ô¼ºÐ¡1µÄ½Úµã
String subMyZnode = myZnode.substring(myZnode.lastIndexOf("/") + 1);
waitNode = lockObjNodes.get(Collections.binarySearch(lockObjNodes, subMyZnode) - 1);
} catch (KeeperException e) {
throw new LockException(e);
} catch (InterruptedException e) {
throw new LockException(e);
}
return false;
}
public boolean tryLock(long time, TimeUnit unit) {
try {
if(this.tryLock()){
return true;
}
return waitForLock(waitNode,time);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private boolean waitForLock(String lower, long waitTime) throws InterruptedException, KeeperException {
Stat stat = zk.exists(root + "/" + lower,true);
//ÅжϱÈ×Ô¼ºÐ¡Ò»¸öÊýµÄ½ÚµãÊÇ·ñ´æÔÚ,Èç¹û²»´æÔÚÔòÎÞÐèµÈ´ýËø,ͬʱע²á¼àÌý
if(stat != null){
System.out.println("Thread " + Thread.currentThread().getId() + " waiting for " + root + "/" + lower);
this.latch = new CountDownLatch(1);
this.latch.await(waitTime, TimeUnit.MILLISECONDS);
this.latch = null;
}
return true;
}
public void unlock() {
try {
System.out.println("unlock " + myZnode);
zk.delete(myZnode,-1);
myZnode = null;
zk.close();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
}
}
public void lockInterruptibly() throws InterruptedException {
this.lock();
}
public Condition newCondition() {
return null;
}
public class LockException extends RuntimeException {
private static final long serialVersionUID = 1L;
public LockException(String e){
super(e);
}
public LockException(Exception e){
super(e);
}
}
}
|
£¨2£©²¢·¢²âÊÔ¹¤¾ß ConcurrentTest.java
package com.concurrent; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; /** ConcurrentTask[] task = new ConcurrentTask[5]; for(int i=0;i<task.length;i++){ task[i] = new ConcurrentTask(){ public void run() { System.out.println("=============="); }}; } new ConcurrentTest(task); * @author xueliang * */ public class ConcurrentTest { private CountDownLatch startSignal = new CountDownLatch(1);//¿ªÊ¼·§ÃÅ private CountDownLatch doneSignal = null;//½áÊø·§ÃÅ private CopyOnWriteArrayList<Long> list = new CopyOnWriteArrayList<Long>(); private AtomicInteger err = new AtomicInteger();//Ô×ÓµÝÔö private ConcurrentTask[] task = null; public ConcurrentTest(ConcurrentTask... task){ this.task = task; if(task == null){ System.out.println("task can not null"); System.exit(1); } doneSignal = new CountDownLatch(task.length); start(); } /** * @param args * @throws ClassNotFoundException */ private void start(){ //´´½¨Ị̈߳¬²¢½«ËùÓÐÏ̵߳ȴýÔÚ·§ÃÅ´¦ createThread(); //´ò¿ª·§ÃÅ startSignal.countDown();//µÝ¼õËø´æÆ÷µÄ¼ÆÊý£¬Èç¹û¼ÆÊýµ½´ïÁ㣬ÔòÊÍ·ÅËùÓеȴýµÄÏß³Ì try { doneSignal.await();//µÈ´ýËùÓÐÏ̶߳¼Ö´ÐÐÍê±Ï } catch (InterruptedException e) { e.printStackTrace(); } //¼ÆËãÖ´ÐÐʱ¼ä getExeTime(); } /** * ³õʼ»¯ËùÓÐỊ̈߳¬²¢ÔÚ·§ÃÅ´¦µÈ´ý */ private void createThread() { long len = doneSignal.getCount(); for (int i = 0; i < len; i++) { final int j = i; new Thread(new Runnable(){ public void run() { try { startSignal.await();//ʹµ±Ç°Ïß³ÌÔÚËø´æÆ÷µ¹¼ÆÊýÖÁÁã֮ǰһֱµÈ´ý long start = System.currentTimeMillis(); task[j].run(); long end = (System.currentTimeMillis() - start); list.add(end); } catch (Exception e) { err.getAndIncrement();//Ï൱ÓÚerr++ } doneSignal.countDown(); } }).start(); } } /** * ¼ÆËãÆ½¾ùÏìӦʱ¼ä */ private void getExeTime() { int size = list.size(); List<Long> _list = new ArrayList<Long>(size); _list.addAll(list); Collections.sort(_list); long min = _list.get(0); long max = _list.get(size-1); long sum = 0L; for (Long t : _list) { sum += t; } long avg = sum/size; System.out.println("min: " + min); System.out.println("max: " + max); System.out.println("avg: " + avg); System.out.println("err: " + err.get()); } public interface ConcurrentTask { void run(); } } |
£¨3£©²âÊÔ ZkTest.java
package com.concurrent;
import com.concurrent.ConcurrentTest.ConcurrentTask;
public class ZkTest {
public static void main(String[] args) {
Runnable task1 = new Runnable(){
public void run() {
DistributedLock lock = null;
try {
lock = new DistributedLock("127.0.0.1:2182","test1");
//lock = new DistributedLock("127.0.0.1:2182","test2");
lock.lock();
Thread.sleep(3000);
System.out.println("===Thread " + Thread.currentThread().getId()
+ " running");
} catch (Exception e) {
e.printStackTrace();
}
finally {
if(lock != null)
lock.unlock();
}
}
};
new Thread(task1).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
ConcurrentTask[] tasks = new ConcurrentTask[60];
for(int i=0;i<tasks.length;i++){
ConcurrentTask task3 = new ConcurrentTask(){
public void run() {
DistributedLock lock = null;
try {
lock = new DistributedLock("127.0.0.1:2183","test2");
lock.lock();
System.out.println("Thread " + Thread.currentThread().getId()
+ " running");
} catch (Exception e) {
e.printStackTrace();
}
finally {
lock.unlock();
}
}
};
tasks[i] = task3;
}
new ConcurrentTest(tasks);
}
} |
4.5 ¸ü¶à·Ö²¼Ê½Êý¾Ý½á¹¹ºÍÐÒé
ʹÓÃZooKeeper¿ÉÒÔʵÏֺܶ಻ͬµÄ·Ö²¼Ê½Êý¾Ý½á¹¹ºÍÐÒ飬ÀýÈç¡°ÆÁÕÏ¡±(bafrier)¡¢¶ÓÁкÍÁ½½×¶ÎÌá½»ÐÒé¡£ÓÐȤµÄÊÇËüÃǶ¼ÊÇͬ²½ÐÒ飬¼´Ê¹ÎÒÃÇʹÓÃÒì²½ZooKeeper»ù±¾²Ù×÷£¨Èç֪ͨ£©À´ÊµÏÖËüÃÇ¡£
ZooKeeperÍøÕ¾(http://hadoop.apache.org/zookeeper)ÌṩÁËһЩÓÃÓÚʵÏÖ·Ö²¼Ê½Êý¾Ý½á¹¹ºÍÐÒéµÄα´úÂë¡£ZooKeeper±¾ÉíÒ²´øÓÐÒ»Ð©×Ø×¼·½·¨µÄʵÏÖ£¬·ÅÔÚ°²×°Î»ÖÃϵÄrecipesĿ¼ÖС£
Îå¡¢BooKeeper
5.1 BooKeeper¸ÅÊö
BooKeeper¾ßÓи±±¾¹¦ÄÜ£¬Ä¿µÄÊÇÌṩ¿É¿¿µÄÈÕÖ¾¼Ç¼¡£ÔÚBooKeeperÖУ¬·þÎñÆ÷±»³ÆÎªÕ˱¾£¨Bookies£©£¬ÔÚÕ˱¾Ö®ÖÐÓв»Í¬µÄÕË»§£¨Ledgers£©£¬Ã¿Ò»¸öÕË»§ÓÉÒ»ÌõÌõ¼Ç¼£¨Entry£©×é³É¡£Èç¹ûʹÓÃÆÕͨµÄ´ÅÅÌ´æ´¢ÈÕÖ¾Êý¾Ý£¬ÄÇôÈÕÖ¾Êý¾Ý¿ÉÄÜÔâµ½ÆÆ»µ£¬µ±´ÅÅÌ·¢Éú¹ÊÕϵÄʱºò£¬ÈÕÖ¾Ò²¿ÉÄܱ»¶ªÊ§¡£BooKeeperΪÿһ·ÝÈÕÖ¾ÌṩÁË·Ö²¼Ê½µÄ´æ´¢£¬²¢²ÉÓÃÁË´ó¶àÊý£¨quorum£¬Ïà¶ÔÓÚÈ«Ì壩µÄ¸ÅÄî¡£Ò²¾ÍÊÇ˵£¬Ö»Òª¼¯ÈºÖеĴó¶àÊý»úÆ÷¿ÉÓã¬ÄÇô¸ÃÈÕÖ¾Ò»Ö±ÓÐЧ¡£
BooKeeperͨ¹ý¿Í»§¶Ë½øÐвÙ×÷£¬¿Í»§¶Ë¿ÉÒÔ¶ÔBooKeeper½øÐÐÌí¼ÓÕË»§¡¢´ò¿ªÕË»§¡¢Ìí¼ÓÕË»§¼Ç¼¡¢¶ÁÈ¡ÕË»§¼Ç¼µÈ²Ù×÷¡£ÁíÍ⣬BooKeeperµÄ·þÎñÒÀÀµÓÚZooKeeper£¬¿ÉÒÔ˵BooKeeperÒÀÀµÓÚZooKeeperµÄÒ»ÖÂÐÔ¼°Æä·Ö²¼Ê½Ìص㣬ÔÚÆäÖ®ÉÏÌṩÁíÍâÒ»ÖÖ¿É¿¿ÐÔ·þÎñ¡£BooKeeperµÄ¼Ü¹¹ÈçÏÂͼËùʾ£º

5.2 BooKeeper½ÇÉ«
´ÓÉÏͼÖпÉÒÔ¿´³ö£¬BooKeeperÖÐ×ܹ²°üº¬ËÄÀà½ÇÉ«£º
¢Ù Õ˱¾£ºBookies
¢Ú ÕË»§£ºLedger
¢Û ¿Í»§¶Ë£ºClient
¢Ü ÔªÊý¾Ý¼°´æ´¢·þÎñ£ºMetadata Storage Service
ÏÂÃæ¼òµ¥½éÉÜÕâËÄÀà½ÇÉ«µÄ¹¦ÄÜ:
(1) Õ˱¾ BooKies
Õ˱¾ÊÇBooKeeperµÄ´æ´¢·þÎñÆ÷£¬Ëû´æ´¢µÄÊÇÒ»¸ö¸öµÄÕ˱¾£¬¿ÉÒÔ½«Õ˱¾Àí½âΪһ¸ö¸ö½Úµã¡£ÔÚÒ»¸öBooKeeperϵͳÖдæÔÚ¶à¸öÕ˱¾£¨½Úµã£©£¬Ã¿¸öÕË»§±»²»Í¬µÄÕ˱¾Ëù´æ´¢¡£ÈôҪдһÌõ¼Ç¼µ½Ö¸¶¨µÄÕË»§ÖУ¬¸Ã¼Ç¼½«±»Ð´µ½Î¬»¤¸ÃÕË»§ËùÓÐÕʱ¾½ÚµãÖС£ÎªÁËÌá¸ßϵͳµÄÐÔÄÜ£¬ÕâÌõ¼Ç¼²¢²»ÊÇÕæÕýµÄ±»Ð´Èëµ½ËùÓеĽڵãÖУ¬¶øÊÇÑ¡Ôñ¼¯ÈºµÄÒ»¸ö´ó¶àÊý¼¯½øÐд洢¡£¸Ãϵͳ¶ÀÓеÄÌØÐÔ£¬Ê¹µÃBooKeeperϵͳÓÐÁ¼ºÃµÄÀ©Õ¹ÐÔ¡£¼´£¬ÎÒÃÇ¿ÉÒÔͨ¹ý¼òµ¥µÄÌí¼Ó»úÆ÷½ÚµãµÄ·½·¨Ìá¸ßϵͳÈÝÁ¿¡£¡î¡î
(2) ÕË»§ Ledger
ÕË»§Öд洢µÄÊÇһϵÁмǼ£¬Ã¿Ò»Ìõ¼Ç¼°üº¬Ò»¶¨µÄ×ֶΡ£¼Ç¼ͨ¹ýд²Ù×÷Ò»´ÎÐÔдÈ룬ֻÄܽøÐи½¼Ó²Ù×÷²»ÄܽøÐÐÐ޸ġ£Ã¿Ìõ¼Ç¼°üº¬ÈçÏÂ×ֶΣº
µ±Âú×ãÏÂÁÐÁ½¸öÌõ¼þʱ£¬Ä³Ìõ¼Ç¼²Å±»ÈÏΪÊÇ´æ´¢³É¹¦£º

¢Ù ֮ǰËù¼Ç¼µÄÊý¾Ý±»Õ˱¾½ÚµãµÄ´ó¶àÊý¼¯Ëù´æ´¢¡£
¢Ú ¸Ã¼Ç¼±»Õ˱¾½ÚµãµÄ´ó¶àÊý¼¯Ëù´æ´¢¡£
(3) ¿Í»§¶Ë BooKeeper Client
¿Í»§¶Ëͨ³£ÓëBooKeeperÓ¦ÓóÌÐò½øÐн»»¥£¬ËüÔÊÐíÓ¦ÓóÌÐòÔÚϵͳÉϽøÐвÙ×÷£¬°üÀ¨´´½¨ÕË»§£¬Ð´ÕË»§µÈ¡£
(4) ÔªÊý¾Ý´æ´¢·þÎñ Metadata Storage Service
ÔªÊý¾ÝÐÅÏ¢´æ´¢ÔÚZooKeeper¼¯Èºµ±ÖУ¬Ëü´æ´¢¹ØÓÚÕË»§ºÍÕ˱¾µÄÐÅÏ¢¡£ÀýÈ磬Õ˱¾Óɼ¯ÈºÖеÄÄÄЩ½Úµã½øÐÐά»¤£¬ÕË»§ÓÉÄĸöÕ˱¾½øÐÐά»¤¡£Ó¦ÓóÌÐòÔÚʹÓÃÕ˱¾µÄʱºò£¬Ê×ÏÈÒª´´½¨Ò»¸öÕË»§¡£ÔÚ´´½¨ÕË»§Ê±£¬ÏµÍ³Ê×ÏȽ«¸ÃÕ˱¾µÄMetadataÐÅϢдÈëµ½ZooKeeperÖС£Ã¿Ò»¸öÕË»§ÔÚijһʱ¿ÌÖ»ÄÜÓÐÒ»¸öдʵÀý£¨·Ö²¼Ê½Ëø£©¡£ÔÚÆäËûʵÀý½øÐжÁ²Ù×÷֮ǰÊ×ÏÈÐèÒª½«Ð´ÊµÀý¹Ø±Õ¡£Èç¹ûд²Ù×÷ʵÀýÓÉÓÚ¹ÊÕÏδÄÜÕý³£¹Ø±Õ£¬ÄÇôÏÂÒ»¸ö³¢ÊÔ´ò¿ªÕË»§µÄʵÀý½«ÐèÒªÊ×ÏÈ¶ÔÆä½øÐлָ´£¬²¢ÕýÈ·¹Ø±Õд²Ù×÷¡£ÔÚ½øÐÐд²Ù×÷µÄͬʱÐèÒª½«×îºóÒ»´ÎµÄд¼Ç¼´æ´¢µ½ZooKeeperÖУ¬Òò´Ë»Ö¸´³ÌÐò½öÐèÒªÔÚZooKeeperÖв鿴¸ÃÕË»§Ëù¶ÔÓ¦µÄ×îºóÒ»Ìõд¼Ç¼£¬È»ºó½«ÆäÕýÈ·µÄдÈëµ½ÕË»§ÖУ¬ÔÙÔÚÕýÈ·¹Ø±Õд²Ù×÷¡£ÔÚBooKeeperÖиûָ´³ÌÐòÓÐϵͳ×Ô¶¯Ö´Ðв»ÐèÒªÓû§²ÎÓë¡£
|