當前位置:首頁 » 文件管理 » javahdfs文件上傳

javahdfs文件上傳

發布時間: 2023-12-09 06:46:42

Ⅰ HDFS文件

Hadoop支持的文件系統由很多(見下圖),HDFS只是其中一種實現。java抽象類 org.apache.hadoop.fs.FileSystem 定義了Hadoop中一個文件系統的客戶端介面,並且該抽象類有幾個具體實現。Hadoop一般使用URI(下圖)方案來選取合適的文件系統實例進行交互。

特別的,HDFS文件系統的操作可以使用 FsSystem shell 、客戶端(http rest api、Java api、C api等)。

FsSystem shell 的用法基本同本地shell類似,命令可參考 FsSystem shell

Hadoop是用Java寫的,通過Java Api( FileSystem 類)可以調用大部分Hadoop文件系統的交互操作。更詳細的介紹可參考 hadoop Filesystem 。

非Java開發的應用可以使用由WebHDFS協議提供的HTTP REST API,但是HTTP比原生的Java客戶端要慢,所以不到萬不得已盡量不要使用HTTP傳輸特大數據。通過HTTP來訪問HDFS有兩種方法:

兩種如圖

在第一種情況中,namenode和datanode內嵌的web服務作為WebHDFS的端節點運行(是否啟用WebHDFS可通過dfs.webhdfs.enabled設置,默認為true)。文件元數據在namenode上,文件讀寫操作首先被發往namenode,有namenode發送一個HTTP重定向至某個客戶端,指示以流的方式傳輸文件數據的目的或源datanode。

第二種方法依靠一個或多個獨立代理伺服器通過HTTP訪問HDFS。所有集群的網路通信都需要通過代理,因此客戶端從來不直接訪問namenode或datanode。使用代理後可以使用更嚴格的防火牆策略和帶寬策略。

HttpFs代理提供和WebHDFS相同的HTTP介面,這樣客戶端能夠通過webhdfs URI訪問介面。HttpFS代理啟動獨立於namenode和datanode的守護進程,使用httpfs.sh 腳本,默認在一個不同的埠上監聽(14000)。

下圖描述了

讀文件時客戶端與 HDFS 中的 namenode, datanode 之間的數據流動。

對上圖的解釋如下:

在讀取過程中, 如果 FSDataInputStream 在和一個 datanode 進行交流時出現了一個錯誤,他就去試一試下一個最接近的塊,他當然也會記住剛才發生錯誤的 datanode 以至於之後不會再在這個 datanode 上進行沒必要的嘗試。 DFSInputStream 也會在 datanode 上傳輸出的數據上核查檢查數(checknums).如果損壞的塊被發現了, DFSInputStream 就試圖從另一個擁有備份的 datanode 中去讀取備份塊中的數據。

在這個設計中一個重要的方面就是客戶端直接從 datanode 上檢索數據,並通過 namenode 指導來得到每一個塊的最佳 datanode。這種設計允許 HDFS 擴展大量的並發客戶端,因為數據傳輸只是集群上的所有 datanode 展開的。期間,namenode 僅僅只需要服務於獲取塊位置的請求(塊位置信息是存放在內存中,所以效率很高)。如果不這樣設計,隨著客戶端數據量的增長,數據服務就會很快成為一個瓶頸。

我們知道,相對於客戶端(之後就是 maprece task 了),塊的位置有以下可能性:

我們認為他們對於客戶端的帶寬遞減,距離遞增(括弧中表示距離)。示意圖如下:

如果集群中的機器都在同一個機架上,我們無需其他配置,若集群比較復雜,由於hadoop無法自動發現網路拓撲,所以需要額外配置網路拓撲。

基本讀取程序,將文件內容輸出到console

FileSystemCat

隨機讀取

展開原碼

下圖描述了寫文件時客戶端與 HDFS 中的 namenode, datanode 之間的數據流動。

對上圖的解釋如下:

如果在任何一個 datanode 在寫入數據的時候失敗了,接下來所做的一切對客戶端都是透明的:首先, pipeline 被關閉,在確認隊列中的剩下的包會被添加進數據隊列的起始位置上,以至於在失敗的節點下游的任 何節點都不會丟失任何的包。然後與 namenode 聯系後,當前在一個好的 datanode 會聯系 namenode, 給失敗節點上還未寫完的塊生成一個新的標識ID, 以至於如果這個失敗的 datanode 不久後恢復了,這個不完整的塊將會被刪除。失敗節點會從 pipeline 中移除,然後剩下兩個好的 datanode 會組成一個的新的 pipeline ,剩下的 這些塊的包(也就是剛才放在數據隊列隊首的包)會繼續寫進 pipeline 中好的 datanode 中。最後,namenode 注意到塊備份數小於規定的備份數,他就安排在另一個節點上創建完成備份,直接從已有的塊中復制就可以。然後一直到滿足了備份數( dfs.replication )。如果有多個節點的寫入失敗了,如果滿足了最小備份數的設置( dfs.namenode.repliction.min ),寫入也將會成功,然後剩下的備份會被集群非同步的執行備份,直到滿足了備份數( dfs.replication )。

創建目錄

文件壓縮有兩大好處:

Hadoop 對於壓縮格式的是自動識別。如果我們壓縮的文件有相應壓縮格式的擴展名(比如 lzo,gz,bzip2 等)。Hadoop 會根據壓縮格式的擴展名自動選擇相對應的解碼器來解壓數據,此過程完全是 Hadoop 自動處理,我們只需要確保輸入的壓縮文件有擴展名。

Hadoop中有多種壓縮格式、演算法和工具,下圖列出了常用的壓縮方法。

表中的「是否可切分」表示對應的壓縮演算法是否支持切分,也就是說是否可以搜索數據流的任意位置並進一步往下讀取數據,可切分的壓縮格式尤其適合MapRece。

所有的壓縮演算法都需要權衡空間/時間:壓縮和解壓縮速度更快,其代價通常是只能節省少量的空間。不同的壓縮工具有不同的特性:

更詳細的比較如下

1.壓縮性能比較

2.優缺點

另外使用hadoop原生(native)類庫比其他java實現有更快的壓縮和解壓縮速度。特徵比較如下:

使用容器文件格式結合壓縮演算法也能更好的提高效率。順序文件、Arvo文件、ORCFiles、Parqurt文件同時支持壓縮和切分。

壓縮舉例(Java)

壓縮

解壓縮

六、文件序列化

序列化是指將結構化數據轉換為位元組流以便在網路上傳輸或寫到磁碟進行永久存儲。反序列化獅子將位元組流轉換回結構化對象的逆過程。

序列化用於分布式數據處理的兩大領域:進程間通信和永久存儲。

對序列化的要求時是格式緊湊(高效使用存儲空間)、快速(讀寫效率高)、可擴展(可以透明地讀取老格式數據)且可以互操作(可以使用不同的語言讀寫數據)。

Hadoop使用的是自己的序列化格式 Writable ,它絕對緊湊、速度快,但不太容易用java以外的語言進行擴展或使用。

當然,用戶也可以使用其他序列化框架或者自定義序列化方式,如 Avro 框架。

Hadoop內部還使用了 Apache Thrift 和 Protocal Buffers 來實現RPC和數據交換。

Ⅱ 怎麼使用java代碼直接將從外部拿到的數據存入hdfs

存入HDFS有好幾種數據格式,我這里給你列出一種格式的存儲,sequence的

publicclassSeqWrite{

privatestaticfinalString[]data={"a,b,c,d,e,f,g","h,i,j,k,l,m,n","o,p,q,r,s,t","u,v,w,x,y,z","0,1,2,3,4","5,6,7,8,9"};

publicstaticvoidmain(String[]args)throwsIOException,Exception{

Configurationconfiguration=newConfiguration();
//這里是你主機的地址
configuration.set("fs.defaultFS","192.168.51.140");
//這個是存儲的路徑
Pathpath=newPath("/tmp/test1.seq");
Optionoption=SequenceFile.Writer.file(path);
OptionoptKey=SequenceFile.Writer.keyClass(IntWritable.class);
OptionoptValue=SequenceFile.Writer.valueClass(Text.class);
SequenceFile.Writerwriter=null;
IntWritablekey=newIntWritable(10);
Textvalue=newText();

writer=SequenceFile.createWriter(configuration,option,optKey,optValue);

for(inti=0;i<data.length;i++){
key.set(i);
value.set(data[i]);
writer.append(key,value);
writer.hsync();
Thread.sleep(10000L);
}

IOUtils.closeStream(writer);
}
}

Ⅲ 如何實現讓用戶在網頁中上傳下載文件到HDFS中

hadoop計算需要在hdfs文件系統上進行,文件上傳到hdfs上通常有三種方法:a hadoop自帶的dfs服務,put;b hadoop的API,Writer對象可以實現這一功能;c 調用OTL可執行程序,數據從資料庫直接進入hadoop

hadoop計算需要在hdfs文件系統上進行,因此每次計算之前必須把需要用到的文件(我們稱為原始文件)都上傳到hdfs上。文件上傳到hdfs上通常有三種方法:

a hadoop自帶的dfs服務,put;

b hadoop的API,Writer對象可以實現這一功能;

c 調用OTL可執行程序,數據從資料庫直接進入hadoop

由於存在ETL層,因此第三種方案不予考慮

將a、b方案進行對比,如下:

1 空間:方案a在hdfs上佔用空間同本地,因此假設只上傳日誌文件,則保存一個月日誌文件將消耗掉約10T空間,如果加上這期間的各種維表、事實表,將佔用大約25T空間

方案b經測試,壓縮比大約為3~4:1,因此假設hdfs空間為100T,原來只能保存約4個月的數據,現在可以保存約1年

2 上傳時間:方案a的上傳時間經測試,200G數據上傳約1小時

方案b的上傳時間,程序不做任何優化,大約是以上的4~6倍,但存在一定程度提升速度的餘地

3 運算時間:經過對200G數據,大約4億條記錄的測試,如果程序以IO操作為主,則壓縮數據的計算可以提高大約50%的速度,但如果程序以內存操作為主,則只能提高5%~10%的速度

4 其它:未壓縮的數據還有一個好處是可以直接在hdfs上查看原始數據。壓縮數據想看原始數據只能用程序把它導到本地,或者利用本地備份數據

壓縮格式:按照hadoop api的介紹,壓縮格式分兩種:BLOCK和RECORD,其中RECORD是只對value進行壓縮,一般採用BLOCK進行壓縮。

對壓縮文件進行計算,需要用SequenceFileInputFormat類來讀入壓縮文件,以下是計算程序的典型配置代碼:

JobConf conf = new JobConf(getConf(), log.class);
conf.setJobName(」log」);
conf.setOutputKeyClass(Text.class);//set the map output key type
conf.setOutputValueClass(Text.class);//set the map output value type

conf.setMapperClass(MapClass.class);
//conf.setCombinerClass(Rece.class);//set the combiner class ,if havenot, use Recuce class for default
conf.setRecerClass(Rece.class);
conf.setInputFormat(SequenceFileInputFormat.class);//necessary if use compress

接下來的處理與非壓縮格式的處理一樣

Ⅳ 關於用java寫程序把本地文件上傳到HDFS中的問題

將這FileSystem hdfs = FileSystem.get(config);
改成FileSystem hdfs = FileSystem.get(URI.create("hdfs://master:9000"),config)
上面那句取得的是本地文件系統對象,改成下面這個才是取得hdfs文件系統對象,當你要操作本地文件對象的時候就要用上面那句取得本地文件對象,我在2.7.4剛開始也是跟你一樣的錯誤,改為下面的就可以了

熱點內容
node調用python 發布:2024-02-24 06:11:55 瀏覽:123
山西中國網路時間伺服器雲空間 發布:2024-02-24 06:03:30 瀏覽:40
手機懸浮字體怎麼弄安卓 發布:2024-02-24 05:51:29 瀏覽:791
php提交表單自己 發布:2024-02-24 05:41:22 瀏覽:104
jquery多文件上傳 發布:2024-02-24 05:38:24 瀏覽:270
php獲取伺服器地址 發布:2024-02-24 05:36:08 瀏覽:123
現在學哪種編程語言好 發布:2024-02-24 05:35:28 瀏覽:262
flyme6雲存儲在哪裡 發布:2024-02-24 05:17:11 瀏覽:431
2b2t測試伺服器ip 發布:2024-02-24 05:02:50 瀏覽:903
SQL命令窗口 發布:2024-02-24 04:34:16 瀏覽:86