这些年来,各种计算框架、各种算法、各种应用场景不断推陈出新,让人眼花缭乱,但是大数据存储的王者依然是HDFS。
HDFS作为最早的大数据存储系统,存储着宝贵的数据资产,各种新的算法、框架要想得到人们的广泛使用,必须支持HDFS才能获取已经存储在里面的数据。所以大数据技术越发展,新技术越多,HDFS得到的支持越多,我们越离不开HDFS。HDFS也许不是最好的大数据存储技术,但依然最重要的大数据存储技术。
磁盘介质在存储过程中受环境或者老化影响,其存储的数据可能会出现错乱。HDFS的应对措施是,对于存储在DataNode上的数据块,计算并存储校验和(CheckSum)。在读取数据的时候,重新计算读取出来的数据的校验和,如果校验不正确就抛出异常,应用程序捕获异常后就到其他DataNode上读取备份数据。
如果DataNode监测到本机的某块磁盘损坏,就将该块磁盘上存储的所有BlockID报告给NameNode,NameNode检查这些数据块还在哪些DataNode上有备份,通知相应的DataNode服务器将对应的数据块复制到其他服务器上,以保证数据块的备份数满足要求。
DataNode会通过心跳和NameNode保持通信,如果DataNode超时未发送心跳,NameNode就会认为这个DataNode已经宕机失效,立即查找这个DataNode上存储的数据块有哪些,以及这些数据块还存储在哪些服务器上,随后通知这些服务器再复制一份数据块到其他服务器上,保证HDFS存储的数据块备份数符合用户设置的数目,即使再出现服务器宕机,也不会丢失数据。
NameNode是整个HDFS的核心,记录着HDFS文件分配表信息,所有的文件路径和数据块存储信息都保存在NameNode,如果NameNode故障,整个HDFS系统集群都无法使用;如果NameNode上记录的数据丢失,整个集群所有DataNode存储的数据也就没用了。
NameNode高可用容错能力非常重要。NameNode采用主从热备的方式提供高可用服务
集群部署两台NameNode服务器,一台作为主服务器提供服务,一台作为从服务器进行热备,两台服务器通过ZooKeeper选举,主要是通过争夺znode锁资源,决定谁是主服务器。而DataNode则会向两个NameNode同时发送心跳数据,但是只有主NameNode才能向DataNode返回控制信息。
正常运行期间,主从NameNode之间通过一个共享存储系统shared edits来同步文件系统的元数据信息。当主NameNode服务器宕机,从NameNode会通过ZooKeeper升级成为主服务器,并保证HDFS集群的元数据信息,也就是文件分配表信息完整一致。
和RAID在多个磁盘上进行文件存储及并行读写的思路一样,HDFS是在一个大规模分布式服务器集群上,对数据分片后进行并行读写及冗余存储。因为HDFS可以部署在一个比较大的服务器集群上,集群中所有服务器的磁盘都可供HDFS使用,所以整个HDFS的存储空间可以达到PB级容量。
DataNode负责文件数据的存储和读写操作,HDFS将文件数据分割成若干数据块(Block),每个DataNode存储一部分数据块,这样文件就分布存储在整个HDFS服务器集群中。应用程序客户端(Client)可以并行对这些数据块进行访问,从而使得HDFS可以在服务器集群规模上实现数据并行访问,极大地提高了访问速度。
在实践中,HDFS集群的DataNode服务器会有很多台,一般在几百台到几千台这样的规模,每台服务器配有数块磁盘,整个集群的存储容量大概在几PB到数百PB。
NameNode负责整个分布式文件系统的元数据(MetaData)管理,也就是文件路径名、数据块的ID以及存储位置等信息,相当于操作系统中文件分配表(FAT)的角色。HDFS为了保证数据的高可用,会将一个数据块复制为多份(缺省情况为3份),并将多份相同的数据块存储在不同的服务器上,甚至不同的机架上。这样当有磁盘损坏,或者某个DataNode服务器宕机,甚至某个交换机宕机,导致其存储的数据块不能访问的时候,客户端会查找其备份的数据块进行访问。
single-node in a pseudo-distributed mode
https://archive.cloudera.com/cdh5/cdh/5/hadoop-2.6.0-cdh5.7.0/hadoop-project-dist/hadoop-common/SingleCluster.html
yum -y install vim
http://mirror.cnop.net/jdk/linux/jdk-7u79-linux-x64.tar.gz
vim /etc/hostname vim /etc/hosts hadoop000 mkdir -p ~/app/tmp tar -xf jdk-7u79-linux-x64.tar.gz -C ~/app/ cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys vim ~/.bash_profile export JAVA_HOME=/home/hadoop/app/jdk1.7.0_79 export PATH=$JAVA_HOME/bin:$PATH source ~/.bash_profile java -version
https://archive.cloudera.com/cdh5/cdh/5/hadoop-2.6.0-cdh5.7.0.tar.gz
tar -xf hadoop-2.6.0-cdh5.7.0.tar.gz -C ~/app/ vim etc/hadoop/hadoop-env.sh export JAVA_HOME=/home/hadoop/app/jdk1.7.0_79
vim etc/hadoop/core-site.xml <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://hadoop000:8020</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/home/hadoop/app/tmp</value> </property> </configuration> vim etc/hadoop/hdfs-site.xml <configuration> <property> <name>dfs.replication</name> <value>1</value> </property> </configuration>
仅仅第一次执行即可,不需要重复执行
bin/hdfs namenode -format
启动
sbin/start-dfs.sh
检查状态
$ jps 11150 SecondaryNameNode 10996 DataNode 10881 NameNode 11253 Jps
或访问
http://localhost:50070
停止
sbin/stop-dfs.sh
vim ~/.bash_profile export HADOOP_HOME=/home/hadoop/app/hadoop-2.6.0-cdh5.7.0 export PATH=$HADOOP_HOME/bin:$PATH
mysql-connector-java-5.1.27-bin.jar
http://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.27/mysql-connector-java-5.1.27.jar