合理性:数据集大小超过单台计算机的存储容量,需要分布到不同单独的计算机
复杂性:涉及网络编程,存在任何分布式系统都存在的通用性问题,但是比客户、服务器模式简单,不用满足ACID等特性,因为只涉及文件读写而且允许时间很长
hadoop的hdfs特点:
1.超大文件,大的含义是至少几百MB
2.流式数据访问,一次访问多次读取,每次读取可能涉及数据集的大部分,读取全部数据的延迟比读取第一条记录的延迟重要
3.商用硬件,采用廉价硬件,软件层面控制故障恢复
4.适用的应用,hdfs是为了高吞吐数据量设计的,牺牲延迟,需要低延迟的访问不适合使用hdfs
5.文件数量问题,所有存储的文件在namenode的内存中,hdfs能存储的文件总数受限于namenode的内存
6.文件读写限制,只支持单个写入者,只支持“只添加”的方式写在文件末尾
hdfs文件块和磁盘块的区别:
磁盘块小,一般512字节,文件占用的磁盘块是磁盘块的整数倍,比如文件几千字节,分到不同的磁盘,最后一个即使用不到完整的512字节,也占用整个磁盘块不能给被人使用
hdfs文件块大,默认128MB,块大的目的是最小化寻址开销,对于大的文件,传输的时间对整体时间的影响远大于定位这个块开始位置需要的时间。一个hdfs块可以给多个文件使用,不是独占,比如一个文件在一个块里面占用了1个MB,只使用这1个MB的磁盘空间,查看块如下:
[root@master chapter2]# hdfs fsck / -blocks
Total size: 5486405 B
Total dirs: 22
Total files: 78
Total symlinks: 0
Total blocks (validated): 77 (avg. block size 71252 B)
Minimally replicated blocks: 77 (100.0 %)
Over-replicated blocks: 0 (0.0 %)
Under-replicated blocks: 77 (100.0 %)
Mis-replicated blocks: 0 (0.0 %)
Default replication factor: 3
Average block replication: 2.0
Corrupt blocks: 0
Missing replicas: 112 (42.105263 %)
Number of data-nodes: 2
Number of racks: 1
FSCK ended at Fri Sep 28 11:14:47 CST 2018 in 20 milliseconds
hdfs节点
1.namenode:管理节点,管理系统命名空间,维护文件树和数内的所有文件和目录,保存在本地磁盘
2.datanode:工作节点,存储和检索数据块,定期向namenode发送存储的块的列表
文件系统基本操作
1.文件上传和下载
上传命令hdfs dfs -copyFromLocal sample.txt /helloworld,将本地当前路径下sample.txt上传到hdfs的/helloworld目录下
下载命令hdfs dfs -copyToLocal /helloworld/sample.txt sample2.txt,将hdfs路径下的文件下载到本地当前路径
使用md5查看文件是没有被更改和损坏的:
[root@master chapter2]# md5sum sample.txt
582942545541e4bd2397d562895d9fc0 sample.txt
[root@master chapter2]# md5sum sample2.txt
582942545541e4bd2397d562895d9fc0 sample2.txt
2.查看hdfs的所有隐藏文件,如下:
[root@master chapter2]# hdfs dfs -ls /
Found 6 items
drwxr-xr-x - root supergroup 0 2018-10-16 15:49 /chapter2
drwxr-xr-x - root supergroup 0 2018-10-17 15:51 /helloworld
drwxr-xr-x - root supergroup 0 2018-09-21 15:54 /max_temperature
drwxr-xr-x - root supergroup 0 2018-09-25 19:31 /mkdirtest
drwx------ - root supergroup 0 2018-09-21 11:27 /tmp
drwxr-xr-x - root supergroup 0 2018-09-25 14:39 /user
3.可以使用java接口直接操作hdfs文件,常用的几个文件操作如下:
删除文件:
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class deldir {
public static void main(String args[]) throws IOException {
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
Path path = new Path("/mkdirtest");
fs.delete(path);
fs.close();
}
}
创建文件:
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class mkdir {
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
Path path = new Path("/mkdirtest");
fs.create(path);
fs.close();
}
}
读取文件:
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class read {
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
Path path = new Path("/mkdirtest/write.txt");
if (fs.exists(path))
{
FSDataInputStream is = fs.open(path);
FileStatus status = fs.getFileStatus(path);
byte[] buffer = new byte[Integer.parseInt(String.valueOf(status.getLen()))];
is.readFully(0, buffer);
is.close();
fs.close();
System.out.println(buffer.toString());
}
}
}
写入文件,注意若没有路径会创建,若有重名文件,那么直接覆盖
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class write {
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
Path path = new Path("/mkdirtest/write.txt");
FSDataOutputStream out = fs.create(path);
out.writeUTF("hello,world!\n");
fs.close();
}
}