定義
Hdfs(Distributed File System):分佈式文件管理系統。它是一種允許文件通過網絡在多臺主機上分享的文件系統,可讓多機器上的多用戶分享文件和存儲空間。
特點:
- 通透性。讓實際上是通過網絡來訪問文件的動作,由程序與用戶看來,就像是訪問本地的磁盤一般。
- 容錯。即使系統中有某些節點宕機,整體來說系統仍然可以持續運作而不會有數據損失【通過副本機制實現】。
shell操作
- 調用文件系統(FS)Shell命令應使用 bin/hdfs dfs -xxx 的形式。
例如:/parent/child可以表示成hdfs://namenode:namenodePort/parent/child,或者更簡單的/parent/child(假設配置文件是namenode:namenodePort)大多數FS Shell命令的行爲和對應的Linux Shell命令類似。
命令 | 含義 |
---|---|
-ls | 路徑爲空,表示顯示usercurrentUser -h選項,表示文件大小顯示時,使用合適的單位 -R選項,表示遞歸顯示路徑的所有內容 |
-put | 從本地上傳文件(夾)到hdfs。如果hdfs已經存在同名的文件(夾),就報錯。-f選項,表示覆蓋hdfs的同名文件(夾) -p選項,表示上傳時保留文件原來的ownerid、groupid、accesstime、modification time屬性 |
-get | 從hdfs下載文件到本地 |
-mkdir | 建文件夾 -p選項,表示遞歸創建文件夾 |
-cp | 在hdfs中複製 |
-help | 顯示命令的幫助 |
hdfs體系結構
NameNode是整個文件系統的管理節點。它維護着整個文件系統的文件目錄樹,文件/目錄的元信息和每個文件對應的數據塊列表。接收用戶的操作請求。
DataNode:提供真實文件數據的存儲服務。文件塊(block):最基本的存儲單位。對於文件內容而言,一個文件的長度大小是size,那麼從文件的0偏移開始,按照固定的大小,順序對文件進行劃分並編號,劃分好的每一個塊稱一個Block。2.0以後HDFS默認Block大小是128MB,以一個256MB文件,共有256/128=2個Block。
hdfs java操作
- 常見的hdfs 操作:上傳,連接。
package deno;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class hdfswork {
public static void main(String[] args) throws IOException, URISyntaxException {
// 首先獲取hdfs集羣訪問地址,namenode的地址
URI uri = new URI("hdfs://192.168.148.128:9000");
// 創建一個配置文件對象
Configuration conf = new Configuration();
// 創建hdfs文件系統的對象
FileSystem fs = FileSystem.get(uri, conf);
// 使用一些方法
// 創建一個文件夾
// fs.create(new Path("/data"));
// 刪除一個文件夾
// fs.delete(new Path("/data"));
// 查看路徑信息
FileStatus[] fileStatuses = fs.listStatus(new Path("/data"));
for (FileStatus fileStatus : fileStatuses) {
if (fileStatus.isFile()) {
System.out.println(fileStatus.getPath());
}
}
// 讀取hdfs上文件
// FSDataInputStream in = fs.open(new Path("/data/city_id.txt"));
// BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
// String line = null;
//
// while ((line = bufferedReader.readLine()) != null) {
// System.out.println(line);
// }
// in.close();
}
}
2.hdfs的寫入操作
package deno;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class MapReduceWC {
//第一部分,寫map階段
//指定map輸出輸出的key和value的序列化類型。
public static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable> {
//map函數,處理每一行數據。一行數據是一個對象,調用一次map函數。
// context 這個參數是上下文的意思,裏面包括整個任務信息,可以執行數據寫入寫出
protected void map(LongWritable key, Text value,
org.apache.hadoop.mapreduce.Mapper<LongWritable, Text, Text, LongWritable>.Context context)
throws java.io.IOException, InterruptedException {
// 先將該行數據轉換成字符串類型
String line = value.toString();
// 將一行數據進行切分。按照數據的分隔符。
String[] split = line.split(",");
// 遍歷數組
for (String word : split) {
// 組建 k2和v2,單詞統計將 value寫死 是 1
// 數據通過context寫入到磁盤
context.write(new Text(word), new LongWritable(1L));
}
};
}
//shuffle 進行合併,分區,分組,排序。相同的k2的數據會被同一個reduce拉取。
//第二部分,寫Reduce階段
public static class MyReduce extends Reducer<Text, LongWritable, Text, LongWritable> {
// 同樣是有reduce函數
@Override
protected void reduce(Text k2, Iterable<LongWritable> v2s,
Reducer<Text, LongWritable, Text, LongWritable>.Context context)
throws IOException, InterruptedException {
// 將value加起來,聚合
long count = 0l;
for (LongWritable value : v2s) {
count += value.get();
}
// 將結果輸出,輸出到hdfs上
context.write(k2, new LongWritable(count));
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
// 設置配置參數
Configuration conf = new Configuration();
// 創建任務
Job job = Job.getInstance(conf, MapReduceWC.class.getSimpleName());
// 指定jar文件
job.setJarByClass(MapReduceWC.class);
// 指定輸入路徑,數據在hdfs上的輸入路徑,指定第一個參數是hdfs輸入路徑
FileInputFormat.addInputPath(job, new Path(args[0]));
// 指定map的類
job.setMapperClass(MyMapper.class);
// 指定map輸出的key和value的數據類型。
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
// 指定reduce類以及輸出數據類型。
job.setReducerClass(MyReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
// 指定輸出路徑hdfs
FileOutputFormat.setOutputPath(job, new Path(args[1]));
// 提交任務,如果是true,會返回任務執行的進度信息等。
job.waitForCompletion(true);
}
}