欧美在线观看视频网站,亚洲熟妇色自偷自拍另类,啪啪伊人网,中文字幕第13亚洲另类,中文成人久久久久影院免费观看 ,精品人妻人人做人人爽,亚洲a视频

一種基于HDFS系統(tǒng)的數(shù)據(jù)的存儲(chǔ)、讀取方法及其裝置與流程

文檔序號(hào):11234103閱讀:610來(lái)源:國(guó)知局
一種基于HDFS系統(tǒng)的數(shù)據(jù)的存儲(chǔ)、讀取方法及其裝置與流程

本發(fā)明涉及大數(shù)據(jù)處理領(lǐng)域,尤其涉及一種基于hdfs系統(tǒng)的數(shù)據(jù)的存儲(chǔ)、讀取方法及其裝置。



背景技術(shù):

在hdfs(hadoop分布式文件系統(tǒng))中,一般會(huì)采用n-wayreplication方式來(lái)做數(shù)據(jù)冗余。文件系統(tǒng)以數(shù)據(jù)塊(block)為單位管理文件內(nèi)容,一個(gè)文件被分割保存在若干個(gè)block上。當(dāng)應(yīng)用程序?qū)懳募r(shí),每寫(xiě)完一個(gè)block,hdfs會(huì)將該block的數(shù)據(jù)自動(dòng)復(fù)制到其他備份服務(wù)器上,保證每一個(gè)block有多個(gè)副本(默認(rèn)值為3),即使有兩臺(tái)服務(wù)器宕機(jī),數(shù)據(jù)依然可以訪(fǎng)問(wèn),備份方法如圖1所示。

如圖2所示,一個(gè)典型的hdfs集群由一個(gè)namenode(名字服務(wù)節(jié)點(diǎn))、一個(gè)secondarynamenode(備用名字服務(wù)節(jié)點(diǎn))和若干個(gè)datanode(數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn))組成。namenode提供元數(shù)據(jù)服務(wù),管理block的分配,維護(hù)整個(gè)文件系統(tǒng)的目錄樹(shù)結(jié)構(gòu),secondarynamenode在namenode發(fā)生故障時(shí)備用,作用與之相同。datanode則部署在hdfs集群中的其他服務(wù)器上,提供真正的數(shù)據(jù)存儲(chǔ)服務(wù)。hdfs將datanode上的磁盤(pán)空間分成n個(gè)block(數(shù)據(jù)塊)供應(yīng)用程序使用,block的大小默認(rèn)為64mb。

傳統(tǒng)hdfs系統(tǒng)采用上述方案讀寫(xiě)文件缺點(diǎn)是,一旦數(shù)據(jù)量達(dá)到pb以上級(jí)別,就需要非常多的備份服務(wù)器來(lái)做備份,給大數(shù)據(jù)用戶(hù)帶來(lái)極大的成本開(kāi)銷(xiāo)。這些成本不但包括磁盤(pán)容量、磁盤(pán)擴(kuò)展柜的成本,機(jī)房空間、機(jī)房電力消耗、以及空調(diào)和維護(hù)等都需要付出相應(yīng)的成本。除此之外,還需要額外的計(jì)算資源和網(wǎng)絡(luò)資源來(lái)負(fù)載i/o計(jì)算和數(shù)據(jù)網(wǎng)絡(luò)傳輸。這種成本開(kāi)銷(xiāo)會(huì)對(duì)沖大數(shù)據(jù)分析給 用戶(hù)帶來(lái)的價(jià)值和利益。所以亟需一種解決方案來(lái)大大減少hdfs系統(tǒng)的使用成本。



技術(shù)實(shí)現(xiàn)要素:

本發(fā)明實(shí)施例提供一種基于hdfs系統(tǒng)的數(shù)據(jù)的存儲(chǔ)、讀取方法及其裝置,用以解決傳統(tǒng)hdfs系統(tǒng)在數(shù)據(jù)量較大時(shí)占用的存儲(chǔ)容量大、成本高的問(wèn)題。

本發(fā)明方法包括:一種基于hdfs系統(tǒng)的數(shù)據(jù)存儲(chǔ)方法,該方法包括:接收待存儲(chǔ)文件的數(shù)據(jù)流并封裝為數(shù)據(jù)包;若所述待存儲(chǔ)文件為大文件,針對(duì)每個(gè)數(shù)據(jù)包,確定名字服務(wù)節(jié)點(diǎn)為所述數(shù)據(jù)包分配的數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊并存儲(chǔ)所述數(shù)據(jù)包,并將所述數(shù)據(jù)包緩存至編碼器的數(shù)據(jù)塊中;為每n個(gè)緩存了數(shù)據(jù)包的數(shù)據(jù)塊建立相同的索引,其中,針對(duì)同一數(shù)據(jù)包,存儲(chǔ)了所述數(shù)據(jù)包的所述數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊和所述編碼器的數(shù)據(jù)塊的索引相同;將編碼器的n個(gè)具有相同索引的數(shù)據(jù)塊進(jìn)行編碼,得到與所述索引對(duì)應(yīng)的m個(gè)校驗(yàn)編碼塊,n、m為正整數(shù),m<n;確定數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)上的存儲(chǔ)所述校驗(yàn)編碼塊的數(shù)據(jù)塊并存儲(chǔ)。

對(duì)應(yīng)地,本發(fā)明實(shí)施例還提供一種基于hdfs系統(tǒng)的數(shù)據(jù)讀取方法,該方法包括:接收文件的讀取請(qǐng)求,并根據(jù)所述讀取請(qǐng)求確定數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)上存儲(chǔ)所述文件的數(shù)據(jù)塊;若所述文件的數(shù)據(jù)塊中存在無(wú)法讀取的數(shù)據(jù)塊,則獲取與所述無(wú)法讀取的數(shù)據(jù)塊的索引相同的數(shù)據(jù)塊及對(duì)應(yīng)的校驗(yàn)編碼塊;對(duì)與所述無(wú)法讀取的數(shù)據(jù)塊的索引相同的數(shù)據(jù)塊及對(duì)應(yīng)的校驗(yàn)編碼塊進(jìn)行解碼,恢復(fù)出所述無(wú)法讀取的數(shù)據(jù)塊。

基于同樣的發(fā)明構(gòu)思,本發(fā)明實(shí)施例進(jìn)一步還提供一種基于hdfs系統(tǒng)的數(shù)據(jù)存儲(chǔ)裝置,該裝置包括:接收單元,用于接收待存儲(chǔ)文件的數(shù)據(jù)流并封裝為數(shù)據(jù)包;數(shù)據(jù)包存儲(chǔ)單元,用于若所述待存儲(chǔ)文件為大文件,針對(duì)每個(gè)數(shù)據(jù)包,確定名字服務(wù)節(jié)點(diǎn)為所述數(shù)據(jù)包分配的數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊并存儲(chǔ)所述數(shù)據(jù)包,并將所述數(shù)據(jù)包緩存至編碼器的數(shù)據(jù)塊中;建立索引單元,用于為每n 個(gè)緩存了數(shù)據(jù)包的數(shù)據(jù)塊建立相同的索引,其中,針對(duì)同一數(shù)據(jù)包,存儲(chǔ)了所述數(shù)據(jù)包的所述數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊和所述編碼器的數(shù)據(jù)塊的索引相同;編碼單元,用于將編碼器的n個(gè)具有相同索引的數(shù)據(jù)塊進(jìn)行編碼,得到與所述索引對(duì)應(yīng)的m個(gè)校驗(yàn)編碼塊,n、m為正整數(shù),m<n;校驗(yàn)編碼塊存儲(chǔ)單元,用于確定數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)上的存儲(chǔ)所述校驗(yàn)編碼塊的數(shù)據(jù)塊并存儲(chǔ)。

對(duì)應(yīng)地,本發(fā)明實(shí)施例進(jìn)一步提供一種基于hdfs系統(tǒng)的數(shù)據(jù)讀取裝置,該裝置包括:接收請(qǐng)求單元,用于接收文件的讀取請(qǐng)求,讀取單元,用于根據(jù)所述讀取請(qǐng)求確定數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)上存儲(chǔ)所述文件的數(shù)據(jù)塊;解碼單元,用于若所述文件的數(shù)據(jù)塊中存在無(wú)法讀取的數(shù)據(jù)塊,則獲取與所述無(wú)法讀取的數(shù)據(jù)塊的索引相同的數(shù)據(jù)塊及對(duì)應(yīng)的校驗(yàn)編碼塊;對(duì)與所述無(wú)法讀取的數(shù)據(jù)塊的索引相同的數(shù)據(jù)塊及對(duì)應(yīng)的校驗(yàn)編碼塊進(jìn)行解碼,恢復(fù)出所述無(wú)法讀取的數(shù)據(jù)塊。

本發(fā)明實(shí)施例一方面實(shí)時(shí)接收待存儲(chǔ)文件的數(shù)據(jù)流并封裝成若干數(shù)據(jù)包,若所述存儲(chǔ)文件為大文件,針對(duì)每個(gè)數(shù)據(jù)包,將該數(shù)據(jù)包存儲(chǔ)在名字服務(wù)節(jié)點(diǎn)為所述數(shù)據(jù)包分配的數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊中,同時(shí)將所述若干數(shù)據(jù)包緩存至編碼器的數(shù)據(jù)塊中,并為每n個(gè)緩存了數(shù)據(jù)包的數(shù)據(jù)塊建立相同的索引,而且針對(duì)同一數(shù)據(jù)包,存儲(chǔ)了所述數(shù)據(jù)包的所述數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊和所述編碼器的數(shù)據(jù)塊的索引相同。將編碼器的n個(gè)具有相同索引的數(shù)據(jù)塊進(jìn)行編碼,得到與所述索引對(duì)應(yīng)的m個(gè)校驗(yàn)編碼塊,并將所述m個(gè)校驗(yàn)編碼塊寫(xiě)入至所述名字服務(wù)節(jié)點(diǎn)分配的數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊中,校驗(yàn)編碼塊的作用是便于客戶(hù)端在讀取文件時(shí),若數(shù)據(jù)庫(kù)發(fā)生丟失,則在同一索引中的數(shù)據(jù)塊丟失個(gè)數(shù)小于m個(gè)時(shí),進(jìn)行編碼恢復(fù)。這樣,客戶(hù)端對(duì)于大數(shù)據(jù)的讀寫(xiě)過(guò)程,并不需要占用非常龐大的數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn),數(shù)據(jù)存儲(chǔ)量小,進(jìn)而降低了數(shù)據(jù)處理的成本。

附圖說(shuō)明

為了更清楚地說(shuō)明本發(fā)明實(shí)施例中的技術(shù)方案,下面將對(duì)實(shí)施例描述中所需要使用的附圖作簡(jiǎn)要介紹,顯而易見(jiàn)地,下面描述中的附圖僅僅是本發(fā)明的 一些實(shí)施例,對(duì)于本領(lǐng)域的普通技術(shù)人員來(lái)講,在不付出創(chuàng)造性勞動(dòng)的前提下,還可以根據(jù)這些附圖獲得其他的附圖。

圖1為現(xiàn)有技術(shù)提供地一種hdfs系統(tǒng)的備份方法;

圖2為現(xiàn)有技術(shù)提供地一種hdfs集群組網(wǎng);

圖3為本發(fā)明實(shí)施例提供一種基于hdfs系統(tǒng)的數(shù)據(jù)存儲(chǔ)方法流程示意圖;

圖4~圖7為現(xiàn)有技術(shù)的rs編碼原理示意圖;

圖8為本發(fā)明實(shí)施例提供一種rs算法編碼器補(bǔ)齊編碼的原理示意圖;

圖9為本發(fā)明實(shí)施例提供一種文件寫(xiě)入hdfs系統(tǒng)的步驟圖;

圖10為本發(fā)明實(shí)施例提供一種基于hdfs系統(tǒng)的數(shù)據(jù)讀取方法流程示意圖;

圖11為本發(fā)明實(shí)施例提供一種rs算法編碼器補(bǔ)齊解碼的原理示意圖;

圖12為本發(fā)明實(shí)施例地提供一種從hdfs系統(tǒng)讀取文件的步驟圖;

圖13為本發(fā)明實(shí)施例還提供一種基于hdfs系統(tǒng)的數(shù)據(jù)存儲(chǔ)裝置的示意圖;

圖14為本發(fā)明實(shí)施例進(jìn)一步地提供一種基于hdfs系統(tǒng)的數(shù)據(jù)讀取裝置。

具體實(shí)施方式

為了使本發(fā)明的目的、技術(shù)方案和優(yōu)點(diǎn)更加清楚,下面將結(jié)合附圖對(duì)本發(fā)明作進(jìn)一步地詳細(xì)描述,顯然,所描述的實(shí)施例僅僅是本發(fā)明一部份實(shí)施例,而不是全部的實(shí)施例?;诒景l(fā)明中的實(shí)施例,本領(lǐng)域普通技術(shù)人員在沒(méi)有做出創(chuàng)造性勞動(dòng)前提下所獲得的所有其它實(shí)施例,都屬于本發(fā)明保護(hù)的范圍。

本發(fā)明實(shí)施例通過(guò)rs編碼以降低存儲(chǔ)成本,改進(jìn)之后的hdfs系統(tǒng)主要是為處理大容量文件的流式數(shù)據(jù)而設(shè)計(jì)的,現(xiàn)有技術(shù)中也有利于rs編碼方案進(jìn)行hdfs系統(tǒng)改進(jìn)的方案,但是現(xiàn)有技術(shù)的方案不能實(shí)時(shí)的對(duì)數(shù)據(jù)塊進(jìn)行rs編碼,為了保證數(shù)據(jù)的安全性,現(xiàn)有技術(shù)的方案必須先以傳統(tǒng)的副本方式進(jìn)行存儲(chǔ),之后再利于rs編碼簡(jiǎn)化datanode上存儲(chǔ)的備份數(shù)據(jù)塊。利用傳統(tǒng)的副本方式 進(jìn)行存儲(chǔ),原因是基于大容量文件占用的block數(shù)目較多,在存儲(chǔ)過(guò)程中無(wú)法確定占用的block的確切數(shù)目,所以本發(fā)明實(shí)施例通過(guò)編碼器為每個(gè)block建立索引,然后分批生成校驗(yàn)編碼塊,通過(guò)校驗(yàn)編碼塊可以恢復(fù)出丟失的數(shù)據(jù)塊,就不必再為每個(gè)block建立備份,這樣就可以真正地降低存儲(chǔ)成本。

參見(jiàn)圖3所示,本發(fā)明實(shí)施例提供一種基于hdfs系統(tǒng)的數(shù)據(jù)存儲(chǔ)方法流程示意圖,具體地實(shí)現(xiàn)方法包括:

步驟s101,接收待存儲(chǔ)文件的數(shù)據(jù)流并封裝為數(shù)據(jù)包。

步驟s102,若所述待存儲(chǔ)文件為大文件,針對(duì)每個(gè)數(shù)據(jù)包,將所述數(shù)據(jù)包存儲(chǔ)至名字服務(wù)節(jié)點(diǎn)為所述數(shù)據(jù)包分配的數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊中,并將所述數(shù)據(jù)包緩存至編碼器的數(shù)據(jù)塊中。

步驟s103,為每n個(gè)緩存了數(shù)據(jù)包的數(shù)據(jù)塊建立相同的索引,其中,針對(duì)同一數(shù)據(jù)包,存儲(chǔ)了所述數(shù)據(jù)包的所述數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊和所述編碼器的數(shù)據(jù)塊的索引相同。

步驟s104,將編碼器的n個(gè)具有相同索引的數(shù)據(jù)塊進(jìn)行編碼,得到與所述索引對(duì)應(yīng)的m個(gè)校驗(yàn)編碼塊,n、m為正整數(shù),m<n。

步驟s105,確定數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)上的存儲(chǔ)所述校驗(yàn)編碼塊的數(shù)據(jù)塊并存儲(chǔ)。

需要說(shuō)明的是,若所述待存儲(chǔ)文件為大文件,將所述數(shù)據(jù)包緩存至編碼器的數(shù)據(jù)塊和生成校驗(yàn)編碼塊并存儲(chǔ)之間并沒(méi)有嚴(yán)格的先后順序,二者可以先后執(zhí)行,也可以并行執(zhí)行。

在步驟s104中,所述編碼器的編碼算法可選擇多種方式,比如rs編碼(reed-solomon,里所編碼),lt碼,raptor碼等,但本發(fā)明優(yōu)選實(shí)施例中選擇使用的rs編碼,雖然其需要建立比較長(zhǎng)的rs編碼,但其總體效能要優(yōu)于其他編碼方式。優(yōu)選的,rs編碼生成的校驗(yàn)編碼塊是通過(guò)范德門(mén)矩陣計(jì)算得到的。

其中rs編碼算法是由irvings.reed和gustavesolomon在1960年提出的,它是一類(lèi)糾錯(cuò)能力很強(qiáng)的多進(jìn)制bch碼,它不但可以糾正隨機(jī)錯(cuò)誤、突發(fā)錯(cuò)誤以及二者的組合,而且可以用來(lái)構(gòu)造其他碼類(lèi),因此rs碼在衛(wèi)星通信、數(shù)字電 視傳輸以及磁記錄系統(tǒng)等許多領(lǐng)域得到廣泛應(yīng)用。rs編碼算法原理是:rs碼可以將原始數(shù)據(jù)分成n份,根據(jù)算法生成m份校驗(yàn)數(shù)據(jù),并能用這n+m份中的任意n份數(shù)據(jù)還原出原始數(shù)據(jù)。即將原始的n份數(shù)據(jù)通過(guò)編碼變?yōu)閚+m份,之后可將n+m份數(shù)據(jù)可存放在不同的分布式節(jié)點(diǎn)上,如果有任意小于等于m份的數(shù)據(jù)失效,任然能夠通過(guò)剩下的數(shù)據(jù)解碼出原始數(shù)據(jù)。具體編解碼原理如下:

(1)使用vandermonde(范德蒙德)矩陣作為編碼矩陣,其中簡(jiǎn)單的范德蒙德矩陣形式如下:

.............................公式[1]

假設(shè)原始數(shù)據(jù)d為d1~dn,生成的校驗(yàn)數(shù)據(jù)為c1~cm,單位矩陣和范德蒙德矩陣進(jìn)行組合得到生成矩陣a,將原始數(shù)據(jù)d和生成矩陣a相乘則可得到編碼之后的存儲(chǔ)數(shù)據(jù),完成編碼。具體表現(xiàn)形式如圖4所示,其中b11~b35為范德蒙德矩陣的方子陣列。

(1)當(dāng)存儲(chǔ)的數(shù)據(jù)d1~dn,c1~cm中有些數(shù)據(jù)無(wú)法讀取時(shí),數(shù)據(jù)恢復(fù)過(guò)程如下:假設(shè)3個(gè)數(shù)據(jù)塊d1、d4、c2丟失,則可以將這3個(gè)數(shù)據(jù)塊對(duì)應(yīng)的生成矩陣a和存儲(chǔ)數(shù)據(jù)e中的行刪掉,得到新的n*n階生成矩陣a2和n*1階存儲(chǔ)數(shù)據(jù)e2,如圖5所示。

由于生成矩陣是有范德蒙矩陣和單元矩陣的組合,所以,矩陣a的任意n行子集都可以保證線(xiàn)性無(wú)關(guān)。需要恢復(fù)的數(shù)據(jù)可以通過(guò)a2的逆矩陣a2-1和矩陣e2的乘積得到,如圖6所示。由于任一矩陣與其逆矩陣相乘都會(huì)得到單位矩陣,那么d=a2-1*e2,如圖7所示。

我們現(xiàn)在常用的raid5和raid6算法只是范德蒙矩陣算法的一個(gè)子集而已。當(dāng)冗余數(shù)據(jù)只有一個(gè)的時(shí)候,就退化成了raid5算法,在實(shí)數(shù)域只需要將輸入數(shù)據(jù)累加就可以得到校驗(yàn)碼了。由上述rs編碼算法的編解碼原理可知, 若hdfs分布式存儲(chǔ)系統(tǒng)采用該算法,假設(shè)n=10,m=4,則原來(lái)需要備份3份數(shù)據(jù),現(xiàn)在根據(jù)rs(10,4)只需要1.4倍的數(shù)據(jù)容量就可以保證任何時(shí)候,只要能夠在服務(wù)器上讀到10份數(shù)據(jù)(即損失數(shù)據(jù)的份數(shù)小于等于4份),則能讀取出原來(lái)的數(shù)據(jù),大大降低了對(duì)存儲(chǔ)容量的占用,相應(yīng)其他的各種成本開(kāi)銷(xiāo)也可以等比例降低。

進(jìn)一步地,在編碼器進(jìn)行rs編碼時(shí),若n份數(shù)據(jù)的大小并不完全相等,也就是說(shuō)編碼器中每個(gè)數(shù)據(jù)塊的數(shù)據(jù)大小不相等,則還需要進(jìn)行補(bǔ)齊處理,以使生成的校驗(yàn)編碼塊更加準(zhǔn)確。具體地,將編碼器的每個(gè)數(shù)據(jù)塊的數(shù)據(jù)大小與第一閾值做比較,得到小于所述第一閾值的數(shù)據(jù)塊;將所述小于所述第一閾值的數(shù)據(jù)塊進(jìn)行數(shù)據(jù)補(bǔ)零以滿(mǎn)足所述第一閾值;將編碼器的數(shù)據(jù)大小均滿(mǎn)足所述第一閾值的n個(gè)數(shù)據(jù)塊進(jìn)行編碼,得到對(duì)應(yīng)的m個(gè)校驗(yàn)編碼塊。

考慮到hdfs是為支持大容量的流式數(shù)據(jù)操作而設(shè)計(jì)的,所以即使是一般的數(shù)據(jù)讀寫(xiě)操作,涉及到的數(shù)據(jù)量都是比較大的,單個(gè)文件包含的塊數(shù)量很大。為此,將hdfs上的文件劃分為block大小的多個(gè)分塊,文件的每個(gè)分塊默認(rèn)為64mb(一個(gè)map處理的數(shù)據(jù)大小)。與其他文件系統(tǒng)不同的是,hdfs中小于一個(gè)block大小的文件不會(huì)占據(jù)整個(gè)block的空間。本發(fā)明實(shí)施例中首先將文件劃分為segment(段),該segment相當(dāng)于segment_length個(gè)block的索引。每個(gè)segment由固定個(gè)數(shù)的連續(xù)的塊組成。對(duì)于特定的文件,除了最后一個(gè)segment,其余每個(gè)segment包含的塊個(gè)數(shù)是相同的,稱(chēng)為segment_length(段長(zhǎng)度)。然后以segment為單位應(yīng)用rs算法,有效的降低了計(jì)算強(qiáng)度。

其中,采用segment方式對(duì)hdfs系統(tǒng)處理的文件進(jìn)行分段編碼的具體方式為:初始化一個(gè)[n+m]*[64mb]的二維數(shù)組用于rs算法編碼器。其中,n=segment_length,m為需要的校驗(yàn)編碼塊份數(shù)。m=1時(shí),rs算法等同于raid5;m=2時(shí)則等同于raid6。rs算法編碼器結(jié)構(gòu)如圖8所示。

因?yàn)樵趯?shí)際的存儲(chǔ)過(guò)程中,單個(gè)的block的數(shù)據(jù)大小可能小于64mb,所以在進(jìn)行rs算法編碼時(shí),通過(guò)補(bǔ)零將各block補(bǔ)齊至64mb,得到的校驗(yàn)編碼塊 的大小都是64mb。由于每個(gè)block的大小信息都保存在namenode上,解碼時(shí)根據(jù)block的實(shí)際大小進(jìn)行解碼計(jì)算即可,補(bǔ)齊操作不影響解碼。另外,對(duì)于block數(shù)小于segment_length的segment,編碼時(shí)編碼器中未被賦值的數(shù)據(jù)塊保持初始值(全零),解碼時(shí)的情況與之類(lèi)似。rs算法編碼器通過(guò)如上方式以字節(jié)為單位并行計(jì)算校驗(yàn)值,結(jié)果合并組成校驗(yàn)編碼塊,使得計(jì)算強(qiáng)度變小、效率提高。

較佳地,針對(duì)所述數(shù)據(jù)包,確定所述名字服務(wù)節(jié)點(diǎn)為每個(gè)數(shù)據(jù)包分配的一個(gè)數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊信息;將每個(gè)數(shù)據(jù)包存儲(chǔ)在所述分配的一個(gè)數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊中。

與傳統(tǒng)的hdfs相比,應(yīng)用rs算法編碼的hdfs文件寫(xiě)入過(guò)程的主要區(qū)別在于引入了rs算法編碼器,編碼器主要是以segment為單位對(duì)block計(jì)算并存儲(chǔ)校驗(yàn)編碼塊。在本發(fā)明實(shí)施例中定義一個(gè)設(shè)定的數(shù)據(jù)結(jié)構(gòu),該數(shù)據(jù)結(jié)構(gòu)將segment與block和校驗(yàn)編碼塊的對(duì)應(yīng)關(guān)系,以及在segment中的相對(duì)位置等信息存儲(chǔ)在namenode上。其中,編碼器實(shí)現(xiàn)的rs算法編解碼對(duì)客戶(hù)端而言是透明的,客戶(hù)端無(wú)需對(duì)校驗(yàn)編碼塊進(jìn)行任何處理。具體地,本發(fā)明實(shí)施例進(jìn)一步地通過(guò)提供圖9所示的文件寫(xiě)入hdfs系統(tǒng)的過(guò)程進(jìn)行闡述,包括:

步驟一:client(客戶(hù)端)調(diào)用hdfs系統(tǒng)的distributedfilesystem對(duì)象的create方法,創(chuàng)建一個(gè)文件輸出流fsdataoutputstream對(duì)象。

步驟二:通過(guò)distributedfilesystem對(duì)象對(duì)namenode進(jìn)行rpc(遠(yuǎn)程調(diào)用),數(shù)據(jù)流被寫(xiě)入fsdataoutputstream對(duì)象的內(nèi)部存儲(chǔ)器中,數(shù)據(jù)流被封裝成一個(gè)個(gè)packet(數(shù)據(jù)包),最大的packet為65557字節(jié)。

步驟三:根據(jù)緩存的packet的大小判斷該數(shù)據(jù)流屬于大文件的數(shù)據(jù)流,因此選擇rs編碼存儲(chǔ)方案,啟動(dòng)編碼器。

步驟四:client遠(yuǎn)程調(diào)用namenode的addblock方法分配第一個(gè)block,包含blockid、datanode和租約(lease)等信息,其中,datanode的個(gè)數(shù)為1。

步驟五:初始化rs算法編碼器,數(shù)據(jù)流以packet(數(shù)據(jù)包)為單位緩存至 編碼器的第一個(gè)block,同時(shí)基于socket(連接套)連接發(fā)送到namenode指定的datanode。

步驟六:接收到packet后,datanode發(fā)送ack(回應(yīng)消息)。

步驟七:datanode成功接收到一個(gè)block后,對(duì)namenode進(jìn)行rpc(遠(yuǎn)程調(diào)用),分配下一個(gè)block及datanode等信息。

步驟八:數(shù)據(jù)流繼續(xù)以packet為單位緩存至編碼器的下一個(gè)block,同時(shí)基于socket連接發(fā)送到namenode指定的datanode。

步驟九:rs算法編碼器成功緩存了segment_length個(gè)block,開(kāi)始進(jìn)行rs算法編碼,生成m個(gè)校驗(yàn)編碼塊。將segment、block、校驗(yàn)編碼塊的相關(guān)信息存儲(chǔ)在namenode上。

步驟十:對(duì)namenode進(jìn)行遠(yuǎn)程調(diào)用,分配block并指定datanode。

步驟十一:校驗(yàn)編碼塊以packet為單位發(fā)送到namenode指定的datanode。

步驟十二:文件的每個(gè)packet寫(xiě)完以后,client調(diào)用fsdataoutputstream對(duì)象的關(guān)閉方法關(guān)閉數(shù)據(jù)流,然后通知namenode文件寫(xiě)入完成。

進(jìn)一步地,若所述待存儲(chǔ)文件為小文件,則為所述小文件數(shù)據(jù)流封裝得到的每個(gè)數(shù)據(jù)包分配至少三個(gè)數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊;將所述每個(gè)數(shù)據(jù)包寫(xiě)入到所述分配的至少三個(gè)數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊中。

也就是說(shuō),對(duì)于小于等于64mb的文件,不再使用編碼器為該文件計(jì)算校驗(yàn)編碼塊,而是仍然使用原來(lái)的副本機(jī)制(默認(rèn)值為3),第一個(gè)datanode接收完數(shù)據(jù)后,會(huì)通過(guò)同步方式把數(shù)據(jù)發(fā)送給其他datanode。這樣做是因?yàn)閷?duì)于較小的文件,本發(fā)明實(shí)施例提供的rs算法編碼方案并不能起到節(jié)省存儲(chǔ)空間的作用,反而降低了文件并行服務(wù)的能力,增加了block丟失時(shí)的恢復(fù)開(kāi)銷(xiāo)。

與上述文件的寫(xiě)入方法相對(duì)應(yīng),本發(fā)明實(shí)施例提供一種基于hdfs系統(tǒng)的數(shù)據(jù)讀取方法流程示意圖,參見(jiàn)圖10所示,具體地實(shí)現(xiàn)方法包括:

步驟s201,接收文件的讀取請(qǐng)求,并根據(jù)所述讀取請(qǐng)求確定數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)上存儲(chǔ)所述文件的數(shù)據(jù)塊。

步驟s202,若所述文件的數(shù)據(jù)塊中存在無(wú)法讀取的數(shù)據(jù)塊,則獲取與所述無(wú)法讀取的數(shù)據(jù)塊的索引相同的數(shù)據(jù)塊及對(duì)應(yīng)的校驗(yàn)編碼塊。

步驟s203,對(duì)與所述無(wú)法讀取的數(shù)據(jù)塊的索引相同的數(shù)據(jù)塊及對(duì)應(yīng)的校驗(yàn)編碼塊進(jìn)行解碼,恢復(fù)出所述無(wú)法讀取的數(shù)據(jù)塊。

具體地,所謂的索引可以指的是每個(gè)block所屬的segment,也就是說(shuō)對(duì)于某個(gè)segment的一組block及其校驗(yàn)編碼塊,如果只是校驗(yàn)編碼塊發(fā)生丟失,編碼器重新進(jìn)行編碼計(jì)算即可恢復(fù)出該校驗(yàn)編碼塊;如果datanode上有block發(fā)生丟失,只要丟失的block和校驗(yàn)編碼塊的總數(shù)不超過(guò)校驗(yàn)編碼塊的總數(shù),根據(jù)rs編碼算法,可以用該組segment剩余的block和校驗(yàn)編碼塊進(jìn)行恢復(fù),即解碼得到丟失的block和校驗(yàn)編碼塊。

例如,如圖11所示的解碼過(guò)程,當(dāng)索引segmenx其中一個(gè)block丟失和一個(gè)校驗(yàn)編碼塊丟失的情況下,恢復(fù)過(guò)程與編碼器一樣,預(yù)先初始一個(gè)[n+m-l]*[64mb]的二維數(shù)組用于rs算法解碼器。其中,n=segment_length,m為需要的校驗(yàn)編碼塊份數(shù),l為丟失的block和校驗(yàn)編碼塊的份數(shù),l<=m。同樣地,在進(jìn)行rs算法解碼時(shí),首先通過(guò)補(bǔ)零將存活的block補(bǔ)齊至64mb,然后根據(jù)丟失的block在其segment中的位置和namenode中記錄的block大小計(jì)算丟失的數(shù)據(jù)塊。解碼的過(guò)程實(shí)際是求解一元一次方程組,與上述使用范德蒙逆矩陣的計(jì)算方法是等價(jià)的?;謴?fù)丟失的block后,如果有丟失的校驗(yàn)編碼塊,則再進(jìn)行編碼計(jì)算出丟失的校驗(yàn)編碼塊。

考慮到rs算法編碼或者解碼都需要進(jìn)行大量的數(shù)學(xué)運(yùn)算,但普通的數(shù)學(xué)乘法會(huì)導(dǎo)致校驗(yàn)編碼塊容量的累加。為此需要在gf(2^8)有限域,即迦羅瓦域(galoisfield)上進(jìn)行四則運(yùn)算。任意兩個(gè)0~255之間的數(shù)字進(jìn)行四則運(yùn)算,結(jié)果仍在0~255之間且結(jié)果唯一,四則運(yùn)算滿(mǎn)足交換律和結(jié)合律。關(guān)于gf(2^8)有限域內(nèi)的計(jì)算方法不再贅述。在本發(fā)明實(shí)施例中,使用查表法進(jìn)行g(shù)f(2^8)域的乘除法運(yùn)算,以降低算法的計(jì)算強(qiáng)度。

與傳統(tǒng)的hdfs相比,應(yīng)用rs算法解碼的hdfs文件讀取過(guò)程的主要區(qū)別 在于引入了rs算法編碼器。當(dāng)某block無(wú)法讀取時(shí),先不返回讀寫(xiě)異常至client,而是初始化rs算法編碼器,根據(jù)該block所在segment的block和校驗(yàn)編碼塊信息,讀取存活的block和校驗(yàn)編碼塊,通過(guò)計(jì)算將block恢復(fù)。進(jìn)一步地,本發(fā)明實(shí)施例通過(guò)提供圖12所示的客戶(hù)端從hdfs系統(tǒng)讀取文件的過(guò)程進(jìn)行闡述,包括:

步驟一:client調(diào)用distributedfilesystem對(duì)象的創(chuàng)建方法,創(chuàng)建一個(gè)文件輸入流fsdatainputstream對(duì)象。

步驟二:client遠(yuǎn)程調(diào)用namenode,獲取關(guān)于文件輸入流對(duì)象的每個(gè)block的位置信息,包括:datanode列表、block大小等,并根據(jù)所述文件的大小,確定待讀取的文件為大文件。

步驟三:namenode返回要讀取的block所在的datanode信息。

步驟四:client從datanode讀取block數(shù)據(jù)。

步驟五:如果block讀寫(xiě)失敗,初始化rs算法編碼器,從namenode上獲取該block所在segment的block和校驗(yàn)編碼塊相關(guān)信息。

步驟六:遠(yuǎn)程調(diào)用namenode的openinfo方法,獲取存活的block和校驗(yàn)編碼塊的位置信息。

步驟七:namenode返回要讀取的存活數(shù)據(jù)塊所在的datanode信息。

步驟八:rs解碼器裝載存活的block或校驗(yàn)編碼塊。

步驟九:rs解碼器裝載所有存活的block和校驗(yàn)編碼塊后,如果滿(mǎn)足條件,根據(jù)rs算法恢復(fù)丟失的block,返回給client。

步驟十:遠(yuǎn)程調(diào)用namenode的addblock方法分配新的block,用于存放恢復(fù)出來(lái)的block,同時(shí)更新該block的位置信息。

步驟十一:以packet為單位將恢復(fù)出來(lái)的block發(fā)送到namenode指定的datanode。繼續(xù)讀取下一個(gè)block,直至全部讀取完成。

考慮到讀取文件的時(shí)候,如果發(fā)現(xiàn)文件的完整性遭到破壞,再檢查現(xiàn)有的數(shù)據(jù)情況,獲取足夠的數(shù)據(jù)塊和校驗(yàn)編碼塊進(jìn)行數(shù)據(jù)的恢復(fù)操作,對(duì)作業(yè)任務(wù) 的讀取過(guò)程會(huì)產(chǎn)生一定的影響。所以本發(fā)明實(shí)施例進(jìn)一步地在接收到文件讀取請(qǐng)求之前,對(duì)文件存儲(chǔ)在datanode上的數(shù)據(jù)塊進(jìn)行預(yù)檢查。具體地:設(shè)定進(jìn)行預(yù)檢查的觸發(fā)條件,包括:(1)對(duì)datablockscanner類(lèi)檢查到有數(shù)據(jù)塊不可用;(2)檢測(cè)到datanode掛掉或者磁盤(pán)不可用等事件;(3)client端發(fā)起數(shù)據(jù)完整性檢查。根據(jù)觸發(fā)條件,檢查文件segment的完整性,及時(shí)修復(fù)丟失的數(shù)據(jù)塊,保證文件的整體完整,減少對(duì)作業(yè)運(yùn)行時(shí)的影響。

另外,對(duì)于沒(méi)有做rs編碼處理的小文件,檢查副本數(shù)是否滿(mǎn)足條件,如果副本數(shù)夠,那么調(diào)用invalidateblock(函數(shù)接口),使該數(shù)據(jù)塊無(wú)效;如果副本數(shù)不夠,加block到corruptreplicasmap(函數(shù)接口)中,然后準(zhǔn)備對(duì)好數(shù)據(jù)塊進(jìn)行復(fù)制。

基于相同的技術(shù)構(gòu)思,本發(fā)明實(shí)施例還提供一種基于hdfs系統(tǒng)的數(shù)據(jù)存儲(chǔ)裝置,該裝置可執(zhí)行上述方法實(shí)施例。本發(fā)明實(shí)施例提供的裝置如圖13所示,包括:接收單元301、數(shù)據(jù)包存儲(chǔ)單元302、建立索引單元303、編碼單元304、校驗(yàn)編碼塊存儲(chǔ)單元305,其中:

接收單元301,用于接收待存儲(chǔ)文件的數(shù)據(jù)流并封裝為數(shù)據(jù)包;

數(shù)據(jù)包存儲(chǔ)單元302,用于若所述待存儲(chǔ)文件為大文件,針對(duì)每個(gè)數(shù)據(jù)包,將所述數(shù)據(jù)包存儲(chǔ)至名字服務(wù)節(jié)點(diǎn)為所述數(shù)據(jù)包分配的數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊中,并將所述數(shù)據(jù)包緩存至編碼器的數(shù)據(jù)塊中;

建立索引單元303,用于為每n個(gè)緩存了數(shù)據(jù)包的數(shù)據(jù)塊建立相同的索引,其中,針對(duì)同一數(shù)據(jù)包,存儲(chǔ)了所述數(shù)據(jù)包的所述數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊和所述編碼器的數(shù)據(jù)塊的索引相同;

編碼單元304,用于將編碼器的n個(gè)具有相同索引的數(shù)據(jù)塊進(jìn)行編碼,得到與所述索引對(duì)應(yīng)的m個(gè)校驗(yàn)編碼塊,n、m為正整數(shù),m<n;

校驗(yàn)編碼塊存儲(chǔ)單元305,用于確定數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)上的存儲(chǔ)所述校驗(yàn)編碼塊的數(shù)據(jù)塊并存儲(chǔ)。

較佳地,所述數(shù)據(jù)包存儲(chǔ)單元302具體用于:針對(duì)所述數(shù)據(jù)包,確定所述 名字服務(wù)節(jié)點(diǎn)為每個(gè)數(shù)據(jù)包分配的一個(gè)數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊信息;將每個(gè)數(shù)據(jù)包存儲(chǔ)在所述分配的一個(gè)數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊中。

進(jìn)一步地,所述編碼單元304具體用于:將編碼器的每個(gè)數(shù)據(jù)塊的數(shù)據(jù)大小與第一閾值做比較,得到小于所述第一閾值的數(shù)據(jù)塊;將所述小于所述第一閾值的數(shù)據(jù)塊進(jìn)行數(shù)據(jù)補(bǔ)零以滿(mǎn)足所述第一閾值;將編碼器的數(shù)據(jù)大小均滿(mǎn)足所述第一閾值的n個(gè)數(shù)據(jù)塊進(jìn)行編碼,得到對(duì)應(yīng)的m個(gè)校驗(yàn)編碼塊。

進(jìn)一步地,若所述待存儲(chǔ)文件為小文件,所述數(shù)據(jù)包存儲(chǔ)單元302還用于:為所述小文件數(shù)據(jù)流封裝得到的每個(gè)數(shù)據(jù)包分配至少三個(gè)數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊;將所述每個(gè)數(shù)據(jù)包寫(xiě)入到所述分配的至少三個(gè)數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊中。

與存儲(chǔ)裝置相對(duì)應(yīng),本發(fā)明實(shí)施例進(jìn)一步地提供一種基于hdfs系統(tǒng)的數(shù)據(jù)讀取裝置,該裝置可執(zhí)行上述方法實(shí)施例。本發(fā)明實(shí)施例提供的裝置如圖14所示,包括:接收請(qǐng)求單元401、讀取單元402、解碼單元403、其中:

接收請(qǐng)求單元401,用于接收文件的讀取請(qǐng)求,

讀取單元402,用于根據(jù)所述讀取請(qǐng)求確定數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)上存儲(chǔ)所述文件的數(shù)據(jù)塊;

解碼單元403,用于若所述文件的數(shù)據(jù)塊中存在無(wú)法讀取的數(shù)據(jù)塊,則獲取與所述無(wú)法讀取的數(shù)據(jù)塊的索引相同的數(shù)據(jù)塊及對(duì)應(yīng)的校驗(yàn)編碼塊;對(duì)與所述無(wú)法讀取的數(shù)據(jù)塊的索引相同的數(shù)據(jù)塊及對(duì)應(yīng)的校驗(yàn)編碼塊進(jìn)行解碼,恢復(fù)出所述無(wú)法讀取的數(shù)據(jù)塊。

進(jìn)一步地,還包括判斷單元404,用于根據(jù)所述文件的大小,確定待讀取的文件為大文件。

綜上所述,本發(fā)明實(shí)施例一方面實(shí)時(shí)接收待存儲(chǔ)文件的數(shù)據(jù)流并封裝成若干數(shù)據(jù)包,若所述存儲(chǔ)文件為大文件,針對(duì)每個(gè)數(shù)據(jù)包,將該數(shù)據(jù)包存儲(chǔ)在名字服務(wù)節(jié)點(diǎn)為所述數(shù)據(jù)包分配的數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊中,同時(shí)將所述若干數(shù)據(jù)包緩存至編碼器的數(shù)據(jù)塊中,并為每n個(gè)緩存了數(shù)據(jù)包的數(shù)據(jù)塊建立相同的索引,而且針對(duì)同一數(shù)據(jù)包,存儲(chǔ)了所述數(shù)據(jù)包的所述數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊 和所述編碼器的數(shù)據(jù)塊的索引相同。將編碼器的n個(gè)具有相同索引的數(shù)據(jù)塊進(jìn)行編碼,得到與所述索引對(duì)應(yīng)的m個(gè)校驗(yàn)編碼塊,并將所述m個(gè)校驗(yàn)編碼塊寫(xiě)入至所述名字服務(wù)節(jié)點(diǎn)分配的數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)塊中,校驗(yàn)編碼塊的作用是便于客戶(hù)端在讀取文件時(shí),若數(shù)據(jù)庫(kù)發(fā)生丟失,則在同一索引中的數(shù)據(jù)塊丟失個(gè)數(shù)小于m個(gè)時(shí),進(jìn)行編碼恢復(fù)。這樣,客戶(hù)端對(duì)于大數(shù)據(jù)的讀寫(xiě)過(guò)程,并不需要占用非常龐大的數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn),數(shù)據(jù)存儲(chǔ)量小,進(jìn)而降低了數(shù)據(jù)處理的成本。

本發(fā)明是參照根據(jù)本發(fā)明實(shí)施例的方法、設(shè)備(系統(tǒng))、和計(jì)算機(jī)程序產(chǎn)品的流程圖和/或方框圖來(lái)描述的。應(yīng)理解可由計(jì)算機(jī)程序指令實(shí)現(xiàn)流程圖和/或方框圖中的每一流程和/或方框、以及流程圖和/或方框圖中的流程和/或方框的結(jié)合??商峁┻@些計(jì)算機(jī)程序指令到通用計(jì)算機(jī)、專(zhuān)用計(jì)算機(jī)、嵌入式處理機(jī)或其他可編程數(shù)據(jù)處理設(shè)備的處理器以產(chǎn)生一個(gè)機(jī)器,使得通過(guò)計(jì)算機(jī)或其他可編程數(shù)據(jù)處理設(shè)備的處理器執(zhí)行的指令產(chǎn)生用于實(shí)現(xiàn)在流程圖一個(gè)流程或多個(gè)流程和/或方框圖一個(gè)方框或多個(gè)方框中指定的功能的裝置。

這些計(jì)算機(jī)程序指令也可存儲(chǔ)在能引導(dǎo)計(jì)算機(jī)或其他可編程數(shù)據(jù)處理設(shè)備以特定方式工作的計(jì)算機(jī)可讀存儲(chǔ)器中,使得存儲(chǔ)在該計(jì)算機(jī)可讀存儲(chǔ)器中的指令產(chǎn)生包括指令裝置的制造品,該指令裝置實(shí)現(xiàn)在流程圖一個(gè)流程或多個(gè)流程和/或方框圖一個(gè)方框或多個(gè)方框中指定的功能。

這些計(jì)算機(jī)程序指令也可裝載到計(jì)算機(jī)或其他可編程數(shù)據(jù)處理設(shè)備上,使得在計(jì)算機(jī)或其他可編程設(shè)備上執(zhí)行一系列操作步驟以產(chǎn)生計(jì)算機(jī)實(shí)現(xiàn)的處理,從而在計(jì)算機(jī)或其他可編程設(shè)備上執(zhí)行的指令提供用于實(shí)現(xiàn)在流程圖一個(gè)流程或多個(gè)流程和/或方框圖一個(gè)方框或多個(gè)方框中指定的功能的步驟。

盡管已描述了本發(fā)明的優(yōu)選實(shí)施例,但本領(lǐng)域內(nèi)的技術(shù)人員一旦得知了基本創(chuàng)造性概念,則可對(duì)這些實(shí)施例作出另外的變更和修改。所以,所附權(quán)利要求意欲解釋為包括優(yōu)選實(shí)施例以及落入本發(fā)明范圍的所有變更和修改。

顯然,本領(lǐng)域的技術(shù)人員可以對(duì)本發(fā)明進(jìn)行各種改動(dòng)和變型而不脫離本發(fā) 明的精神和范圍。這樣,倘若本發(fā)明的這些修改和變型屬于本發(fā)明權(quán)利要求及其等同技術(shù)的范圍之內(nèi),則本發(fā)明也意圖包含這些改動(dòng)和變型在內(nèi)。

當(dāng)前第1頁(yè)1 2 
網(wǎng)友詢(xún)問(wèn)留言 已有0條留言
  • 還沒(méi)有人留言評(píng)論。精彩留言會(huì)獲得點(diǎn)贊!
1
鄄城县| 正镶白旗| 拉萨市| 甘谷县| 临桂县| 南漳县| 新宁县| 信阳市| 禄劝| 鹿邑县| 四川省| 中西区| 钦州市| 郸城县| 辉县市| 若尔盖县| 鲜城| 元朗区| 汉阴县| 太和县| 汾西县| 固安县| 华亭县| 普兰县| 民乐县| 诸暨市| 英吉沙县| 宁远县| 蒲城县| 溆浦县| 江油市| 和平区| 洮南市| 利川市| 崇州市| 巫山县| 鄂托克旗| 江山市| 宜州市| 耿马| 淅川县|