Hadoop化繁為簡—hdfs的核心剖析
層層遞進-解開hdfs的面紗
1、hdfs是什麽?它與普通服務器的文件系統有什麽區別?它的特性有什麽?
2、hdfs的工作原理是怎樣的?
3、每臺機器都單獨啟動有什麽弊端?假設有1000臺機器需要啟動?該怎麽解決呢?
4、hdfs配置與使用
5、利用javaApi充當客戶端訪問hdfs
hdfs簡介
hdfs就是一個分布式文件系統。簡單說,就是一個“分魚展”的大硬盤,跟普通的文件系統沒什麽區別,只是它有多臺機器共同承擔存儲任務。
分魚展指的是hdfs的特性分別指分布式、冗余性、可拓展。
普通服務器文件系統:上傳文件到服務器
hdfs分布式文件系統:相當於一塊大硬盤、百度雲網盤(內部實現就是hdfs)。
hdfs工作原理
舉例:上傳一個1G的文件。
- 客戶端與Master(NameNode)建立連接。
- 把文件名、文件的分割的數據塊號告知Master(NameNode)。
- 告知客戶端,存儲數據Slave的ip、存儲位置、塊號。
- 客戶端寫文件到Slave1(也有可以是其他的Slave,Master根據機器的內存大小、存儲空間進行分配)。然後Slave1遠程存放數據以後,將會復制一份到Slave2、Slave3。
- 那什麽是塊呢?因為Master收到上傳文件以後,hdfs默認一塊128M(可修改)。那1G文件將會被分成10塊。
- Slave1、Slave2、Slave3都復制一份?那跟一臺服務器存儲又有什麽區別呢?假設有100臺Slave機器呢?
- hdfs默認是配置備份數據到3臺,可通過配置文件修改。
- 假設有100臺Slave(DataNode),1G分為10塊分別為B1、B2、......、B10,它內部是怎麽進行分配呢?
- hdfs系統根據內存和存儲空間。假設在Slave1、Slave2、Slave5存儲B1,Slave2、Slave8、Slave10存儲B2,Slave3、Slave12、Slave15存儲B3,依次類推。
分布式:別把hdfs理解得有多難,多抽象,只是數據從存儲到一臺機器上變成存儲到多臺機器上罷了。對於客戶端而言,它就是一塊硬盤,就是一臺機器文件系統,跟JavaIO並沒有很大差異。
冗余性:因為分布式很難控制,一不小心就宕了一臺機器呢?數據容易丟失,備份多份數據是非常有必要的,這也是hdfs的容錯性。
拓展性:拓展就是機器之間解耦,隨時拓展集群、增加機器維持服務的供給。假設服務器正常運行中,突然之間Slave1宕了,那麽怎麽辦?在我們潛意識當中,肯定分布式系統會自動去備份一份數據到另外一臺內存占用比較低的機器。在hadoop有一概念叫做“心跳”檢測,就是Master會每隔一段時間給集群發送一個消息,如果沒有回應就默認機器宕了,然後Master會把重新把宕了的機器數據重新分配備份到內存占有率比較低的機器。善於思考的大佬們又想了,假設Master宕了呢?這麽嚴重的問題,hadoop的開發者當然要考慮進去,在hadoop裏面有一個類似於NameNode東西叫做SecondaNameNode,它將會隔一段時間將NameNode的快照和日誌備份一遍到自己機器,並且通知NameNode更新日誌,當NameNode宕了,SecondaNameNode將會及時頂上。有分析很透徹的文章,我就不班門弄斧了。http://blog.csdn.net/xh16319/article/details/31375197
每臺機器都單獨啟動的弊端
1、回顧之前命令
查看結點啟動情況:jps
啟動|關閉NameNode:hadoop-daemon.sh start|stop namenode
啟動|關閉DataNode:hadoop-daemon.sh start|stop datanode
查看集群情況:hdfs dfsadmin -report或者利用網頁http://192.168.56.100:50070
2、集中式管理集群(註意:我們修改過的配置文件:/etc/hadoop/slaves)
slave1 slave2 slave3
3、啟動集群(如果沒有配置環境變量:start-dfs.sh、stop-dfs.sh在/usr/local/hadoop/sbin目錄下找)
切換至目錄/usr/local/hadoop/sbin
使用start-dfs.sh啟動集群
使用stop-dfs.sh關閉集群
問題:需要依次輸入遠程機器的登錄賬號密碼?這樣貌似作用不大啊?
答:在master機器上可以設置ssh遠程登錄的免密工作。ssh slave1輸入賬號密碼就能遠程登錄
cd
ls -la
cd .ssh
ssh-keygen -t rsa (四個回車)
#會用rsa算法生成私鑰id_rsa和公鑰id_rsa.pub
ssh-copy-id slave1
ssh-copy-id slave2
ssh-copy-id slave3
hdfs的使用
1、解釋hdfs最簡陋的/usr/local/hadoop/etc/hdfs-site.xml配置文件。註意:修改完配置以後,一定要對master進行 hadoop NameNode -format
<configuration> <!--文件的存儲位置--> <property> <name>dfs.name.dir</name> <value>/usr/local/hadoop/data</value> </property> <!--關閉dfs權限,以免待會不允許客戶端訪問--> <property> <name>dfs.permissions</name> <value>false</value> </property> <!--備份數據多少份,默認三份,我配置了兩份測試--> <property> <name>dfs.replication</name> <value>2</value> </property> <!--心跳檢測--> <property> <name>dfs.namenode.heartbeat.recheck-interval</name> <value>10000</value> </property> </configuration>
2、hdfs的使用(最好通過網頁查看 http:192.168.56.100:50070)
- hadoop fs -ls /
- hadoop fs -put file / (舉例:hadoop fs -put hello.txt /)
- hadoop fs -mkdir /dirname
- hadoop fs -text /filename
- hadoop fs -rm /filename
利用JavaAPI充當客戶端訪問hdfs集群
1、添加jar-pom.xml包
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ccut.aaron.test</groupId> <artifactId>HadoopHdfs</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>HadoopHdfs</name> <description/> <properties> <webVersion>3.0</webVersion> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>2.7.3</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.7.3</version> </dependency>
</dependencies> </project>
2、讀文件
public class ReadFile { public static void main(String[] args) throws MalformedURLException, IOException { URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory()); InputStream in = new URL("hdfs://192.168.56.100:9000/hei.txt").openStream(); IOUtils.copyBytes(in, System.out, 4096, true); } }
3、寫文件
public class WriteFile { public static void main(String[] args) throws IOException { Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://192.168.56.100:9000"); FileSystem fileSystem = FileSystem.get(conf); boolean b = fileSystem.exists(new Path("/hello")); System.out.println(b); boolean success = fileSystem.mkdirs(new Path("/mashibing")); System.out.println(success); success = fileSystem.delete(new Path("/mashibing"), true); System.out.println(success); FSDataOutputStream out = fileSystem.create(new Path("/hei.txt"), true); FileInputStream fis = new FileInputStream("f:/hei.txt"); IOUtils.copyBytes(fis, out, 4096, true); FileStatus[] statuses = fileSystem.listStatus(new Path("/")); //System.out.println(statuses.length); for(FileStatus status : statuses) { System.out.println(status.getPath()); System.out.println(status.getPermission()); System.out.println(status.getReplication()); } } }
Hadoop化繁為簡—hdfs的核心剖析