日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

zookeeper windows安裝和使用

系統(tǒng) 2869 0

zookeeper介紹
zookeeper是一個(gè)為分布式應(yīng)用提供一致性服務(wù)的軟件,它是開(kāi)源的Hadoop項(xiàng)目中的一個(gè)子項(xiàng)目,并且根據(jù)google發(fā)表的論文來(lái)實(shí)現(xiàn)的,接下來(lái)我們首先來(lái)安裝使用下這個(gè)軟件,然后再來(lái)探索下其中比較重要一致性算法。

zookeeper安裝和使用
zookeeper的安裝基本上可以按照 http://hadoop.apache.org/zookeeper/docs/current/ zookeeperStarted.html 這個(gè)頁(yè)面上的步驟完成安裝,這里主要介紹下部署一個(gè)集群的步驟,因?yàn)檫@個(gè)官方頁(yè)面似乎講得并不是非常詳細(xì)(Running Replicated Zookeeper)。

由于手頭機(jī)器不足,所以在一臺(tái)機(jī)器上部署了3個(gè)server,如果你手頭也比較緊,也可以這么做。那么我建了3個(gè)文件夾,如下
server1 server2 server3

然后每個(gè)文件夾里面解壓一個(gè)zookeeper的下載包,并且還建了幾個(gè)文件夾,總體結(jié)構(gòu)如下,最后那個(gè)是下載過(guò)來(lái)壓縮包的解壓文件
data dataLog logs zookeeper-3.3.2

那么首先進(jìn)入data目錄,創(chuàng)建一個(gè)myid的文件,里面寫入一個(gè)數(shù)字,比如我這個(gè)是server1,那么就寫一個(gè)1,server2對(duì)應(yīng)myid文件就寫入2,server3對(duì)應(yīng)myid文件就寫個(gè)3

然后進(jìn)入zookeeper-3.3.2/conf目錄,那么如果是剛下過(guò)來(lái),會(huì)有3個(gè)文件,configuration.xml, log4j.properties,zoo_sample.cfg,這3個(gè)文件我們首先要做的就是在這個(gè)目錄創(chuàng)建一個(gè)zoo.cfg的配置文件,當(dāng)然你可以把zoo_sample.cfg文件改成zoo.cfg,配置的內(nèi)容如下所示:

tickTime=2000
initLimit=5
syncLimit=2
dataDir=xxxx/zookeeper/server1/data
dataLogDir=xxx/zookeeper/server1/dataLog
clientPort=2181

server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890

標(biāo)紅的幾個(gè)配置應(yīng)該官網(wǎng)講得很清楚了,只是需要注意的是clientPort這個(gè)端口如果你是在1臺(tái)機(jī)器上部署多個(gè)server,那么每臺(tái)機(jī)器都要不同的clientPort,比如我server1是2181,server2是2182,server3是2183,dataDir和dataLogDir也需要區(qū)分下。

最后幾行唯一需要注意的地方就是 server.X 這個(gè)數(shù)字就是對(duì)應(yīng) data/myid中的數(shù)字。你在3個(gè)server的myid文件中分別寫入了1,2,3,那么每個(gè)server中的zoo.cfg都配server.1,server.2,server.3就OK了。因?yàn)樵谕慌_(tái)機(jī)器上,后面連著的2個(gè)端口3個(gè)server都不要一樣,否則端口沖突,其中第一個(gè)端口用來(lái)集群成員的信息交換,第二個(gè)端口是在leader掛掉時(shí)專門用來(lái)進(jìn)行選舉leader所用。

進(jìn)入zookeeper-3.3.2/bin 目錄中,./zkServer.sh start啟動(dòng)一個(gè)server,這時(shí)會(huì)報(bào)大量錯(cuò)誤?其實(shí)沒(méi)什么關(guān)系,因?yàn)楝F(xiàn)在集群只起了1臺(tái)server,zookeeper服務(wù)器端起來(lái)會(huì)根據(jù)zoo.cfg的服務(wù)器列表發(fā)起選舉leader的請(qǐng)求,因?yàn)檫B不上其他機(jī)器而報(bào)錯(cuò),那么當(dāng)我們起第二個(gè)zookeeper實(shí)例后,leader將會(huì)被選出,從而一致性服務(wù)開(kāi)始可以使用,這是因?yàn)?臺(tái)機(jī)器只要有2臺(tái)可用就可以選出leader并且對(duì)外提供服務(wù)(2n+1臺(tái)機(jī)器,可以容n臺(tái)機(jī)器掛掉)。

接下來(lái)就可以使用了,我們可以先通過(guò) zookeeper自帶的客戶端交互程序來(lái)簡(jiǎn)單感受下zookeeper到底做一些什么事情。進(jìn)入zookeeper-3.3.2/bin(3個(gè)server中任意一個(gè))下,./zkCli.sh –server 127.0.0.1:2182,我連的是開(kāi)著2182端口的機(jī)器。

?

說(shuō)明一下:myid 這個(gè)文件是沒(méi)有擴(kuò)展名的,分布啟動(dòng)后的效果

zookeeper windows安裝和使用

那么,首先我們隨便打個(gè)命令,因?yàn)閦ookeeper不認(rèn)識(shí),他會(huì)給出命令的help,如下圖
zookeeper windows安裝和使用
ls(查看當(dāng)前節(jié)點(diǎn)數(shù)據(jù)),
ls2(查看當(dāng)前節(jié)點(diǎn)數(shù)據(jù)并能看到更新次數(shù)等數(shù)據(jù)) ,
create(創(chuàng)建一個(gè)節(jié)點(diǎn)) ,
get(得到一個(gè)節(jié)點(diǎn),包含數(shù)據(jù)和更新次數(shù)等數(shù)據(jù)),
set(修改節(jié)點(diǎn))
delete(刪除一個(gè)節(jié)點(diǎn))

通過(guò)上述命令實(shí)踐,我們可以發(fā)現(xiàn),zookeeper使用了一個(gè)類似文件系統(tǒng)的樹(shù)結(jié)構(gòu),數(shù)據(jù)可以掛在某個(gè)節(jié)點(diǎn)上,可以對(duì)這個(gè)節(jié)點(diǎn)進(jìn)行刪改。另外我們還發(fā)現(xiàn),當(dāng)改動(dòng)一個(gè)節(jié)點(diǎn)的時(shí)候,集群中活著的機(jī)器都會(huì)更新到一致的數(shù)據(jù)。

zookeeper的數(shù)據(jù)模型
在簡(jiǎn)單使用了zookeeper之后,我們發(fā)現(xiàn)其數(shù)據(jù)模型有些像操作系統(tǒng)的文件結(jié)構(gòu),結(jié)構(gòu)如下圖所示
zookeeper windows安裝和使用

(1) 每個(gè)節(jié)點(diǎn)在zookeeper中叫做znode,并且其有一個(gè)唯一的路徑標(biāo)識(shí),如/SERVER2節(jié)點(diǎn)的標(biāo)識(shí)就為/APP3/SERVER2
(2) Znode可以有子znode,并且znode里可以存數(shù)據(jù),但是EPHEMERAL類型的節(jié)點(diǎn)不能有子節(jié)點(diǎn)
(3) Znode中的數(shù)據(jù)可以有多個(gè)版本,比如某一個(gè)路徑下存有多個(gè)數(shù)據(jù)版本,那么查詢這個(gè)路徑下的數(shù)據(jù)就需要帶上版本。
(4) znode 可以是臨時(shí)節(jié)點(diǎn),一旦創(chuàng)建這個(gè) znode 的客戶端與服務(wù)器失去聯(lián)系,這個(gè) znode 也將自動(dòng)刪除,Zookeeper 的客戶端和服務(wù)器通信采用長(zhǎng)連接方式,每個(gè)客戶端和 服務(wù)器通過(guò)心跳來(lái)保持連接,這個(gè)連接狀態(tài)稱為 session,如果 znode 是臨時(shí)節(jié)點(diǎn),這個(gè) session 失效,znode 也就刪除了
(5) znode 的目錄名可以自動(dòng)編號(hào),如 App1 已經(jīng)存在,再創(chuàng)建的話,將會(huì)自動(dòng)命名為 App2
(6) znode 可以被監(jiān)控,包括這個(gè)目錄節(jié)點(diǎn)中存儲(chǔ)的數(shù)據(jù)的修改,子節(jié)點(diǎn)目錄的變化等,一旦變化可以通知設(shè)置監(jiān)控的客戶端,這個(gè)功能是zookeeper對(duì)于應(yīng)用最重要的特性,通過(guò)這個(gè)特性可以實(shí)現(xiàn)的功能包括配置的集中管理,集群管理,分布式鎖等等。

通過(guò)java代碼使用zookeeper
Zookeeper的使用主要是通過(guò)創(chuàng)建其jar包下的Zookeeper實(shí)例,并且調(diào)用其接口方法進(jìn)行的,主要的操作就是對(duì)znode的增刪改操作,監(jiān)聽(tīng)znode的變化以及處理。

以下為主要的API使用和解釋

//創(chuàng)建一個(gè)Zookeeper實(shí)例,第一個(gè)參數(shù)為目標(biāo)服務(wù)器地址和端口,第二個(gè)參數(shù)為Session超時(shí)時(shí)間,第三個(gè)為節(jié)點(diǎn)變化時(shí)的回調(diào)方法
ZooKeeper zk =? new ? ZooKeeper( "127.0.0.1:2181" ,? 500000 , new ? Watcher() {
??????????? // 監(jiān)控所有被觸發(fā)的事件
????????????? public ? void ? process(WatchedEvent event) {
??????????? //dosomething
??????????? }
?????? });
//創(chuàng)建一個(gè)節(jié)點(diǎn)root,數(shù)據(jù)是mydata,不進(jìn)行ACL權(quán)限控制,節(jié)點(diǎn)為永久性的(即客戶端shutdown了也不會(huì)消失)
zk.create( "/root" ,? "mydata" .getBytes(),Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
?
//在root下面創(chuàng)建一個(gè)childone znode,數(shù)據(jù)為childone,不進(jìn)行ACL權(quán)限控制,節(jié)點(diǎn)為永久性的
zk.create( "/root/childone" , "childone" .getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
?
//取得/root節(jié)點(diǎn)下的子節(jié)點(diǎn)名稱,返回List<String>
zk.getChildren( "/root" , true );
?
//取得/root/childone節(jié)點(diǎn)下的數(shù)據(jù),返回byte[]
zk.getData( "/root/childone" ,? true ,? null );
?
//修改節(jié)點(diǎn)/root/childone下的數(shù)據(jù),第三個(gè)參數(shù)為版本,如果是-1,那會(huì)無(wú)視被修改的數(shù)據(jù)版本,直接改掉
zk.setData( "/root/childone" , "childonemodify" .getBytes(), - 1 );
?
//刪除/root/childone這個(gè)節(jié)點(diǎn),第二個(gè)參數(shù)為版本,-1的話直接刪除,無(wú)視版本
zk.delete( "/root/childone" , - 1 );
?
//關(guān)閉session
zk.close();

Zookeeper的主流應(yīng)用場(chǎng)景實(shí)現(xiàn)思路 除去官方示例)

(1)配置管理
集中式的配置管理在應(yīng)用集群中是非常常見(jiàn)的,一般商業(yè)公司內(nèi)部都會(huì)實(shí)現(xiàn)一套集中的配置管理中心,應(yīng)對(duì)不同的應(yīng)用集群對(duì)于共享各自配置的需求,并且在配置變更時(shí)能夠通知到集群中的每一個(gè)機(jī)器。

Zookeeper很容易實(shí)現(xiàn)這種集中式的配置管理,比如將APP1的所有配置配置到/APP1 znode下,APP1所有機(jī)器一啟動(dòng)就對(duì)/APP1這個(gè)節(jié)點(diǎn)進(jìn)行監(jiān)控(zk.exist(“/APP1″,true)),并且實(shí)現(xiàn)回調(diào)方法Watcher,那么在zookeeper上/APP1 znode節(jié)點(diǎn)下數(shù)據(jù)發(fā)生變化的時(shí)候,每個(gè)機(jī)器都會(huì)收到通知,Watcher方法將會(huì)被執(zhí)行,那么應(yīng)用再取下數(shù)據(jù)即可(zk.getData(“/APP1″,false,null));

以上這個(gè)例子只是簡(jiǎn)單的粗顆粒度配置監(jiān)控,細(xì)顆粒度的數(shù)據(jù)可以進(jìn)行分層級(jí)監(jiān)控,這一切都是可以設(shè)計(jì)和控制的。
(2)集群管理
應(yīng)用集群中,我們常常需要讓每一個(gè)機(jī)器知道集群中(或依賴的其他某一個(gè)集群)哪些機(jī)器是活著的,并且在集群機(jī)器因?yàn)殄礄C(jī),網(wǎng)絡(luò)斷鏈等原因能夠不在人工介入的情況下迅速通知到每一個(gè)機(jī)器。

Zookeeper同樣很容易實(shí)現(xiàn)這個(gè)功能,比如我在zookeeper服務(wù)器端有一個(gè)znode叫/APP1SERVERS,那么集群中每一個(gè)機(jī)器啟動(dòng)的時(shí)候都去這個(gè)節(jié)點(diǎn)下創(chuàng)建一個(gè)EPHEMERAL類型的節(jié)點(diǎn),比如server1創(chuàng)建/APP1SERVERS/SERVER1(可以使用ip,保證不重復(fù)),server2創(chuàng)建/APP1SERVERS/SERVER2,然后SERVER1和SERVER2都watch /APP1SERVERS這個(gè)父節(jié)點(diǎn),那么也就是這個(gè)父節(jié)點(diǎn)下數(shù)據(jù)或者子節(jié)點(diǎn)變化都會(huì)通知對(duì)該節(jié)點(diǎn)進(jìn)行watch的客戶端。因?yàn)镋PHEMERAL類型節(jié)點(diǎn)有一個(gè)很重要的特性,就是客戶端和服務(wù)器端連接斷掉或者session過(guò)期就會(huì)使節(jié)點(diǎn)消失,那么在某一個(gè)機(jī)器掛掉或者斷鏈的時(shí)候,其對(duì)應(yīng)的節(jié)點(diǎn)就會(huì)消失,然后集群中所有對(duì)/APP1SERVERS進(jìn)行watch的客戶端都會(huì)收到通知,然后取得最新列表即可。

另外有一個(gè)應(yīng)用場(chǎng)景就是集群選master,一旦master掛掉能夠馬上能從slave中選出一個(gè)master,實(shí)現(xiàn)步驟和前者一樣,只是機(jī)器在啟動(dòng)的時(shí)候在APP1SERVERS創(chuàng)建的節(jié)點(diǎn)類型變?yōu)镋PHEMERAL_SEQUENTIAL類型,這樣每個(gè)節(jié)點(diǎn)會(huì)自動(dòng)被編號(hào),例如

zk.create( "/testRootPath/testChildPath1" , "1" .getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
?
zk.create( "/testRootPath/testChildPath2" , "2" .getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
?
zk.create( "/testRootPath/testChildPath3" , "3" .getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
?
// 創(chuàng)建一個(gè)子目錄節(jié)點(diǎn)
zk.create( "/testRootPath/testChildPath4" , "4" .getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
?
System.out.println(zk.getChildren( "/testRootPath" ,? false ));

打印結(jié)果:[testChildPath10000000000, testChildPath20000000001, testChildPath40000000003, testChildPath30000000002]

zk.create( "/testRootPath" ,? "testRootData" .getBytes(),Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
?
// 創(chuàng)建一個(gè)子目錄節(jié)點(diǎn)
zk.create( "/testRootPath/testChildPath1" , "1" .getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
?
zk.create( "/testRootPath/testChildPath2" , "2" .getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
?
zk.create( "/testRootPath/testChildPath3" , "3" .getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
?
// 創(chuàng)建一個(gè)子目錄節(jié)點(diǎn)
zk.create( "/testRootPath/testChildPath4" , "4" .getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
?
System.out.println(zk.getChildren( "/testRootPath" ,? false ));

打印結(jié)果:[testChildPath2, testChildPath1, testChildPath4, testChildPath3]

我們默認(rèn)規(guī)定編號(hào)最小的為master,所以當(dāng)我們對(duì)/APP1SERVERS節(jié)點(diǎn)做監(jiān)控的時(shí)候,得到服務(wù)器列表,只要所有集群機(jī)器邏輯認(rèn)為最小編號(hào)節(jié)點(diǎn)為master,那么master就被選出,而這個(gè)master宕機(jī)的時(shí)候,相應(yīng)的znode會(huì)消失,然后新的服務(wù)器列表就被推送到客戶端,然后每個(gè)節(jié)點(diǎn)邏輯認(rèn)為最小編號(hào)節(jié)點(diǎn)為master,這樣就做到動(dòng)態(tài)master選舉。


淺析
 創(chuàng)建連接:
  1.獲取服務(wù)主機(jī)列表
  2.設(shè)置超時(shí)時(shí)間
  3.注冊(cè)客戶端事件
  4.以線程安全的方式創(chuàng)建請(qǐng)求連接(啟動(dòng)客戶端請(qǐng)求隊(duì)列,循環(huán)隊(duì)列基于socket通信、根據(jù)請(qǐng)求類型執(zhí)行不同的請(qǐng)求動(dòng)作)
  請(qǐng)求流程:
  構(gòu)造請(qǐng)求頭、構(gòu)造request,reponse、構(gòu)造響應(yīng)頭、構(gòu)造Packet對(duì)象,packet對(duì)象準(zhǔn)備好后,把整個(gè)對(duì)象放入一個(gè)outgoingQueue?
packet被放入outgoingQueue中,等待SendThread把packet對(duì)應(yīng)的內(nèi)容發(fā)送給server。server處理分3步在doio方法中ReadLength ReadConnectResult ReadResponse,直到ReadResponse方法中確定packet請(qǐng)求結(jié)束。
響應(yīng)流程:
  針對(duì)心跳的ping請(qǐng)求的resp,針對(duì)auth請(qǐng)求的resp,一般接口請(qǐng)求的resp,如果接口請(qǐng)求要求了watcher,當(dāng)watcher關(guān)注的內(nèi)容有變化時(shí)的notification
鎖相關(guān)部分API方法:
  創(chuàng)建節(jié)點(diǎn): create
  demo:zk.Create(Dir, severname.GetBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.Persistent);
  其中CreateMode分為4類Persistent、PersistentSequential、Ephemeral、EphemeralSequential
  PERSISTENT 創(chuàng)建持久化節(jié)點(diǎn),對(duì)應(yīng)機(jī)器關(guān)閉連接后節(jié)點(diǎn)/數(shù)據(jù)不會(huì)消失
  PERSISTENT_SEQUENTIAL 如果PATH是以’/’結(jié)尾則以這個(gè)PATH作為父節(jié)點(diǎn),創(chuàng)建一個(gè)子節(jié)點(diǎn),其子節(jié)點(diǎn)名字是一個(gè)按先后順序排列的數(shù)值;否則創(chuàng)建一個(gè)名字是‘/’后面字符加上先后順序排列的數(shù)值字符串的節(jié)點(diǎn),同樣創(chuàng)建持久節(jié)點(diǎn)
  EPHEMERAL 創(chuàng)建瞬時(shí)節(jié)點(diǎn),Zookeeper在感知連接機(jī)器宕機(jī)后會(huì)清除它創(chuàng)建的瞬時(shí)節(jié)點(diǎn)
  EPHEMERAL_SEQUENTIAL 穿件瞬時(shí)順序節(jié)點(diǎn),和PERSISTENT_SEQUENTIAL一樣,區(qū)別在于它是瞬時(shí)的
  刪除節(jié)點(diǎn) delete
  demo :zk.Delete(Dir, -1);
  前一個(gè)參數(shù)代表節(jié)點(diǎn)名稱(一般用作路徑),后一個(gè)是版本號(hào) -1表示全匹配
  查看節(jié)點(diǎn) exists
  demo : zk.Exists(Dir, new MyWatch2());
  獲取數(shù)據(jù) getData?
  demo :zk.GetData(Dir, new MyWatch2(), stat);
  獲取一個(gè)節(jié)點(diǎn)的數(shù)據(jù),可注入watcher   
  設(shè)置數(shù)據(jù) setData?
  demo : zk.SetData(Dir, new byte[1], 1);
  獲取下級(jí)節(jié)點(diǎn)集合 GetChildren
  demo :zk.GetChildren(Dir, true);
存儲(chǔ)
  znodes類似文件和目錄。但它不是一個(gè)典型的文件系統(tǒng),zookeeper數(shù)據(jù)保存在內(nèi)存中,這意味著zookeeper可以實(shí)現(xiàn)高吞吐量和低延遲。
watcher
  Zookeeper有兩種watches,一種是data watches,另一種是child watches。其中,getData()和exists()以及create()等會(huì)添加data watches,getChildren()會(huì)添加child watches。而delete()涉及到刪除數(shù)據(jù)和子節(jié)點(diǎn),會(huì)同時(shí)觸發(fā)data watches和child watches。
???? 詳細(xì)可以參考: http://www.geminikwok.com/2011/09/08/%E6%B5%85%E8%B0%88zookeeper-watch%E4%BA%8B%E4%BB%B6/
算法
  Paoxs算法 本篇中僅用單臺(tái)server做demo 改個(gè)時(shí)間詳細(xì)介紹下Paoxs  


總結(jié)

我們初步使用了一下zookeeper并且嘗試著描述了幾種應(yīng)用場(chǎng)景的具體實(shí)現(xiàn)思路,接下來(lái)的文章,我們會(huì)嘗試著去探究一下zookeeper的高可用性與leaderElection算法。

參考: http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/

http://hadoop.apache.org/zookeeper/docs/current/

http://rdc.taobao.com/team/jm/archives/448

zookeeper windows安裝和使用


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 田东县| 吕梁市| 乡宁县| 金门县| 淳化县| 将乐县| 漳浦县| 翁牛特旗| 来安县| 古田县| 林甸县| 定结县| 始兴县| 甘南县| 临潭县| 平乐县| 平乡县| 苍梧县| 甘泉县| 甘南县| 漳州市| 郎溪县| 彰化县| 北安市| 侯马市| 专栏| 沁源县| 武义县| 大田县| 通化县| 靖江市| 奈曼旗| 金塔县| 洛川县| 安溪县| 阿图什市| 潜山县| 昌宁县| 榆树市| 托克逊县| 孙吴县|