Big Data 大數據
1. 數據採集(多個數據源)
2. 數據存儲(分佈式存儲)
3. 數據分析(並行計算)
Hadoop
**apache軟件基金會的開源項目 提供了大數據集的存儲和大數據集的並行計算模型**
Apache Hadoop(http://hadoop.apache.org/)是⼀一款框架,允許使⽤用簡單的編程模 型跨計算機集羣分佈式處理理⼤大型數據集。Hadoop開源免費,具備穩定可靠、可擴展、分佈式計算等特性
並行計算:數據傳輸、計算容錯、分佈式集羣資源管理等
google:開源3個技術的技術論文
GFS google file system
MapReduce 並行計算框架
BigTable 大表
開源實現:
HDFS hadoop分佈式文件系統
MapReduce
HBase
生態體系
hadoop
hbase
kafka
hive
flume
hadoop體系架構
-
HDFS hadoop分佈式文件系統 具備可靠 高吞吐能力
-
Yarn 分佈式任務調度和資源管理平臺 類似於分佈式操作系統 對分佈式集羣中的計算資源進行管理
-
MapReduce 並行計算框架(模型) 用來開發並行計算任務做並行運算
HDFS提供數據 ----> MapReduce設計並行計算任務 ----> 提交到yarn集羣運行 ----> HDFS\存儲系統
HDFS 類似於FastDFS:解決大數據集的存儲問題
HDFS
HDFS是Hadoop的分佈式⽂文件系統( Hadoop Distributed File System ),類似於其它的分佈式⽂文件。HDFS⽀支持⾼高度容錯,可以部署在廉價的硬件設備上,特別適宜於⼤大型的數據集的分佈式存儲。
架構篇
HDFS採⽤用master/slave架構。⼀一個HDFS集羣是由⼀一個Namenode和⼀一定數⽬目的Datanodes組成。
Namenode是一箇中心服務器,負責管理理文件系統的名字空間(namespace)以及客戶端對⽂文件的訪問。集羣中的Datanode一般是一個節點一個,負責管理它所在節點上的存儲。HDFS暴露了文件系統的名字空間,⽤用戶能夠以⽂文件的形式在上⾯面存儲數據。從內部看,一個⽂文件其實被分成一個或多個數據塊,這些塊存儲在一組Datanode上。Namenode執行文件系統的名字空間操作,比如打開、關閉、重命名文件或目錄。它也負責確定數據塊到具體Datanode節點的映射。
Namenode : 存儲系統元數據、namespace、管理理datanode、接受datanode狀態彙報 Datanode: 存儲塊數據,響應客戶端的塊的讀寫,接收namenode的塊管理理指令 Datanode負責處理理⽂文件系統客戶端的讀寫請求。在Namenode的統一調度下進行數據塊的創建、刪除和複製。
Block: HDFS存儲數據的基本單位,默認值是128MB,實際塊⼤大⼩小0~128MB
Rack: 機架,對datanode所在主機的物理理標識,標識主機的位置,優化存儲和計算
HDFS常見問題
-
HDFS是否適合存儲小文件?
不適合1個文件1GB 10000個小文件1GB
磁盤空間 8個數據塊1GB 10000個數據塊1GB
元數據 1條 10000條a. 使用HDFS存儲小文件 會大量浪費NameNode的內存空間
b. 存放小文件會造成尋址的時間大於IO讀寫的時間 違背了HDFS設計原則 -
NameNode和SecondaryNameNode的聯繫?
結論:並不是主備的關係
SecondaryName實際上是輔助NameNode工作的,可以週期性合併fsimage和edits log文件,可以加速NameNode數據的恢復效率
Namenode主要維護兩個⽂文件,⼀一個是 fsimage ,⼀一個是 editlog
- fsimage保存了了最新的元數據檢查點,包含了了整個HDFS⽂文件系統的所有⽬目錄和⽂文件的信息。
對於⽂文件來說包括了了數據塊描述信息、修改時間、訪問時間等;對於⽬目錄來說包括修改時間、
訪問權限控制信息(⽬目錄所屬⽤用戶,所在組)等。 - editlog主要是在NameNode已經啓動情況下對HDFS進⾏行行的各種更更新操作進⾏行行記錄,HDFS客戶端執⾏行行所有的寫操作都會被記錄到editlog中。
爲了了避免editlog不不斷增⼤大,secondary namenode會週期性合併fsimage和edits成新的fsimage
![1552485979481](F:\文件資料\講課筆記\BigData訓練營\07Hadoop\day1 hdfs\assets\1552485979481.png)
環境搭建:
僞分佈式(Pseudo-Distributed)
[root@node1 ~]# rpm -ivh jdk-8u191-linux-x64.rpm
[root@node1 ~]# vi .bashrc
JAVA_HOME=/usr/java/latest
CLASSPATH=.
PATH=$PATH:$JAVA_HOME/bin
export JAVA_HOME
export CLASSPATH
export PATH
[root@node1 ~]# source .bashrc
-
關閉防火牆
systemctl stop firewalld (centos6 : service iptables stop) systemctl disable firewalld (centos6 : chkconfig iptables off)
-
配置主機名和IP映射關係
[root@node1 ~]# vi /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.186.128 主機名(hadoop) # 重啓jvm [root@node1 ~]# reboot
-
配置主機SSH免密碼登錄
# 生成公鑰祕鑰 [root@hadoop ~]# ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa # 將公鑰給服務者 [root@hadoop ~]# cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # 修改權限 [root@hadoop ~]# chmod 0600 ~/.ssh/authorized_keys
-
安裝Hadoop並且配置HADOOP_HOME環境變量量
[root@hadoop ~]# tar -zxf hadoop-2.6.0_x64.tar.gz -C /usr/ [root@hadoop ~]# yum install -y tree [root@hadoop ~]# tree -L 1 /usr/hadoop-2.6.0/ /usr/hadoop-2.6.0/ bin -- 基礎指令 hadoop、hdfs指令 etc -- 配置⽬目錄(重要) include lib libexec LICENSE.txt NOTICE.txt README.txt sbin -- 系統命令 start|stop-dfs|yarn.sh|hadoop-daemon.sh share -- hadoop依賴jar⽂文件 7 directories, 3 files
修改環境變量
[root@hadoop ~]# vi .bashrc
HADOOP_HOME=/usr/hadoop-2.6.0
JAVA_HOME=/usr/java/latest
CLASSPATH=.
PATH=JAVA_HOME/bin:HADOOP_HOME/sbin
export JAVA_HOME
export CLASSPATH
export PATH
export HADOOP_HOME
[root@hadoop ~]# source .bashrc
[root@hadoop ~]# hadoop classpath
/usr/hadoop-2.6.0/etc/hadoop:/usr/hadoop-
2.6.0/share/hadoop/common/lib/:/usr/hadoop-
2.6.0/share/hadoop/common/:/usr/hadoop-2.6.0/share/hadoop/hdfs:/usr/hadoop-
2.6.0/share/hadoop/hdfs/lib/:/usr/hadoop-2.6.0/share/hadoop/hdfs/:/usr/hadoop-
2.6.0/share/hadoop/yarn/lib/:/usr/hadoop-2.6.0/share/hadoop/yarn/:/usr/hadoop-
2.6.0/share/hadoop/mapreduce/lib/:/usr/hadoop-
2.6.0/share/hadoop/mapreduce/:/usr/hadoop-
2.6.0/contrib/capacity-scheduler/*.jar
**後續課程中Hbase、Hive、Spark On Yarn都需要識別系統的HADOOP_HOME****
- ##### 修改 etc/hadoop/core-site.xml
```xml
<property>
<name>fs.defaultFS</name>
<value>hdfs://主機名:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/usr/hadoop-2.6.0/hadoop-${user.name}</value>
</property>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
修改的主機名
[root@hadoop ~]# hdfs namenode -format
18/09/10 12:12:49 INFO namenode.NNConf: Maximum size of an xattr: 16384
18/09/10 12:12:49 INFO namenode.FSImage: Allocated new BlockPoolId: BP-
1855312329-
192.168.128.128-1536552769089
18/09/10 12:12:49 INFO common.Storage: Storage directory /usr/hadoop-
2.6.0/hadoop-root/dfs/name
has been successfully formatted.
18/09/10 12:12:49 INFO namenode.NNStorageRetentionManager: Going to retain 1
images with txid >=0
namenode格式化只需要在初次使⽤用hadoop的時候執行,以後⽆無需每次啓動執行
[root@hadoop ~]# start-dfs.sh
Starting namenodes on [centos]
centos: starting namenode, logging to /usr/hadoop-2.6.0/logs/hadoop-root-
namenode-centos.out
centos: starting datanode, logging to /usr/hadoop-2.6.0/logs/hadoop-root-
datanode-centos.out
Starting secondary namenodes [0.0.0.0]
The authenticity of host '0.0.0.0 (0.0.0.0)' can't be established.
RSA key fingerprint is 35:a8:db:4d:51:51:75:15:15:57:49:a8:3d:25:88:fa.
Are you sure you want to continue connecting (yes/no)? yes
0.0.0.0: Warning: Permanently added '0.0.0.0' (RSA) to the list of known hosts.
0.0.0.0: starting secondarynamenode, logging to /usr/hadoop-2.6.0/logs/hadoop-
root-
secondarynamenode-centos.out
[root@centos ~]# jps
2151 Jps
2049 SecondaryNameNode
1915 DataNode
1809 NameNode
常用指令
- 格式化⼀一個新的分佈式⽂文件系統
hdfs namenode -format
2.啓動 NameNode 守護進程和 DataNode 守護進程
sbin/start-dfs.s
Hadoop 守護進程的日誌寫⼊到 HADOOP_HOME/logs )
-
瀏覽 NameNode 的⽹網絡接口
http://ip地址:50070/
4.常⽤用的shell指令
hdfs dfs -help # 創建⽬目錄 hdfs dfs -mkdir -p path # 展示指令⽬目錄內容清單 hdfs dfs -ls path # ⽂文件上傳 hdfs dfs -put localsrc dst # ⽂文件下載 hdfs dfs -get src localdst # ⽂文件刪除 hdfs dfs -rm src # 查看內容 hdfs dfs -cat path hdfs dfs -tail path # 權限相關 hdfs dfs -chgrp [-R] GROUP PATH... hdfs dfs -chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH hdfs dfs -chown [-R] [OWNER][:[GROUP]] PATH # 操作相關 bin/hdfs dfs -mv src dstsrc bin/hdfs dfs -cp src dstsrc
JAVA客戶端
配置 注:Windows開發環境
-
解壓hadoop安裝包 hadoop-2.6.0_x64.tar.gz
-
配置HADOOP_HOME環境變量量
-
拷⻉貝winutil.exe和hadoop.dll⽂文件到hadoop的安裝bin⽬目錄下 hadoop_dll2.6.0_64bit.zip
-
配置主機名和IP的映射關係
C:\Windows\System32\drivers\etc --- hosts
#127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 #::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.186.128 node1
-
重啓開發⼯工具idea
Maven依賴
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.6.0</version>
</dependency>
-DHADOOP_USER_NAME=root
![1552486456439](F:\文件資料\講課筆記\BigData訓練營\07Hadoop\day1 hdfs\assets\1552486456439.png)
示例
package com.baizhi;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class BasicTest {
private FileSystem fileSystem = null ;
private Configuration configuration = null;
@Before
public void before() throws URISyntaxException, IOException {
configuration = new Configuration();
configuration.set("dfs.replication","1");
URI uri =new URI("hdfs://hadoop:9000");
fileSystem = FileSystem.get(uri,configuration);
}
/**
* 上傳
* @throws IOException
*/
@Test
public void testUpload() throws IOException {
// ⽅方式一
/* Path src = new Path("E:\\1.txt");
Path dst = new Path("/user/wang/2.txt");
fileSystem.copyFromLocalFile(src,dst);*/
// ⽅方式二
Path dst = new Path("/user/wang/3.txt");
FSDataOutputStream outputStream = fileSystem.create(dst);
FileInputStream inputStream = new FileInputStream("E:\\1.txt");
IOUtils.copyBytes(inputStream,outputStream,configuration);
}
/**
* ⽂文件下載
*/
@Test
public void testDownload() throws IOException {
// 方法一 (實現有問題)
/* Path src = new Path("/user/wang/3.txt");
Path dst = new Path("E:\\aa.txt");
fileSystem.copyToLocalFile(src,dst);
*/
// 方法二
FSDataInputStream inputStream = fileSystem.open(new Path("/user/wang/3.txt"));
FileOutputStream outputStream = new FileOutputStream("E:\\aa.txt");
IOUtils.copyBytes(inputStream,outputStream,configuration);
}
/**
* 展示⽂文件列列表清單
* @throws IOException
*/
@Test
public void testListFiles() throws IOException {
// 展示指令⽬目錄內容清單
RemoteIterator<LocatedFileStatus> remoteIterator=fileSystem.listFiles(new Path("/user/gaozhy"), true);
while(remoteIterator.hasNext()){
LocatedFileStatus next = remoteIterator.next();
System.out.println(next.getPath().toString());
}
}
/**
* 刪除
*/
@Test
public void testDeleteFile() throws IOException {
boolean isDeleted = fileSystem.delete(new Path("/user/gaozhy"), true);
System.out.println("刪除結果:"+isDeleted);
}
/**
* 追加
*/
@Test
public void testAppendFiles() throws IOException {
FSDataOutputStream outputStream = fileSystem.append(new Path("/user/install.log"));
FileInputStream inputStream = new FileInputStream("F:\\test.txt");
IOUtils.copyBytes(inputStream,outputStream,configuration);
}
/**
* 其它
*/
@Test
public void testOther() throws IOException {
// 權限操作
fileSystem.setPermission(new Path("/user/background.jpg"),new
FsPermission(FsAction.ALL, FsAction.READ_WRITE,FsAction.READ));
}
}
}