HDFS
hdfs是hadoop distributed filesystem的缩写,是hadoop生态系统最为重要的一个组件,处于hadoop生态的最底层,负责数据的存储。
hdfs能解决什么问题?
1.数据集的大小超过一台计算机的存储能力,对数据分区。
2.管理网络中多台计算机存储的文件系统。
特点:
1. hdfs以流式数据访问模式:一次写入,多次读取。
2. 存储超大文件,GB、TB甚至是PB的文件
3. 运行在商用硬件集群上。例如普通服务器,节点故障率高。
4. 不适合低时间延迟的数据访问
5. 不适合存储大量小文件:文件系统存储文件的总数受限于namanode的内存
6. 多用户写入,任意修改文件。HDFS中的文件可能只有一个write,写操作总是将数据添加到末尾。
HDFS数据块
1. 默认块大小64MB,但小于一个块大小的文件不会占用整个块的空间
2. HDFS块比磁盘的块大,目的是最小化寻址开销。
3. 可以存储大于任意一个磁盘容量的文件
4. 方便存储管理(元数据与数据分开管理,容易备份提供容错能力和提高可用性。)
5. hadoop fsck / -files -blocks 查看文件中的各个文件由哪些块构成
namenode和datanode
namenode与datanode
1. namenode管理者,datanode工作者
2. namenode管理着文件系统的命名空间,维护着文件系统树下的文件和目录
3. 命名空间镜像文件和编辑日志文件
4. 每个块所在数据节点信息,不永久保存,这些信息在系统启动时由数据节点重建。
5. Datanode存储文件数据块,并定期向namenode发送所存储的块的列表
Namenode容错
1. 第一种机制备份那些组成文件文件系统元数据持久状态的文件。将持久状态写入磁盘的同时,写入一个远程挂载的网络文件系统(NFS)。
2. 第二种方法运行SecondaryNamenode定期编辑日志合并空间镜像,保存空间镜像副本。
3. 第三种方法将NFS上namenode的元数据复制到namenode并作为新的主namenode
Namenode高可用
1. namenode之间通过高可用的共享存储事项编辑日志的共享。(zookeeper)
2. datanode需要同时向两个namenode发送数据块处理报告。
HDFS中的文件访问权限
一共提供三类权限:只读权限(r)、写入权限(w)、可执行权限(x)
访问一个目录的子项需要执行权限
读取文件列出目录内容需要读权限
写入一个文件,新建或一个文件或目录需要写权限
权限只能供合作团体中的用户使用,而不能用于一个不友好的环境中保护资源
超级用户是namenode进程的标识,对于超级用户,系统不会执行任务权限检查。
Hadoop文件系统接口
1. Http:第一种方法,直接访问,HDFS后台进程直接服务来自于客户端的请求。
第二种方法,通过一个或多个代理访问,客户端向代理发送http请求,代理通过RPC与Namenode,Datanode通信。
2.第一种情况中,有namenode内嵌的web服务器(50070)提供目录服务,目录裂变以XML或者JSON格式存储,文件数据由datanode的web服务器(50075)以数据流的形式传输。
3.WebHDFS实现对文件的系统操作(读写),包括Kerberos认证。Dfs.webhdfs.enable设置为true才能使用。
4. 使用代理服务器可以做到负载均衡,更加严格的防火墙策略和带宽限制策略。
5.HttpFS代理服务器具有读和写能力,提供了和WebHDFS一样的接口,使用HTTP REST API
Java API
1. Configuration对象封装了客户端或服务器端的配置,通过设置配置文件读取类路径来实现(conf/core-site.xml)
2. Public staic LocalFileSystem getLocal(Configuration conf) throws IOException获取本地文件系统实例。
3. FSDataInputStream支持随机访问,由此可以从流的任意位置读取文件,继承了Seekable接口。seek(long pos)定位到一个绝对位置,getPos()获取当前位置。PositonedReadable接口,从一个指定偏移量处读取文件的一部分。Int Read(long position, byte[] buffer, int offset, int length)从position处读取至多length字节的数据并存入缓冲区buffer指点偏移量offset处。返回值实际读到的字节数:readFully将制定length长度字节的数据读到buffer,所有读操作都将保存文件当前偏移量。
4. FSDataOutputStream, create()方法能够为需要写入且当前不存在的文件创建父目录。
Progressable用于传递回调接口,appen()方法在一个已有文件末尾追加数据,getPos()查询文件当前位置。
5.FileStatus[] globStatus(Path pathPattern, PathFilter filter)返回与路径匹配于指定模式的所有文件的FileStatus对象数组
Fs.globStatus(new Path(“/2007/*/*”), new RegexExcludeFilter(“^.*/2007/12/31$”))
listStatus(Path path, PathFilter filter)
剖析文件文件读取
1. 客户端通过FileSystem(DistributedFileSystem)对象的open()方法打开希望读取的文件
2. DistributedFileSystem向namenode获取块与datanode的对应关系。Datanode根据它们与客户端的距离排序。
3. DistributedFileSystem返回一个FSDataInputStream对象,进而封装成DFSInputStream对象,管理着namenode与datanode的IO
4. 客户端对输入流调用read方法,到达块的末端时,关闭与datanode的连接,寻找下一个datanode.
5. 客户端读取完成,FSDataInputStream调用close()
6. 遇到错误时,会寻找最邻近的另一个块,记住故障datanode。
剖析文件写入
1. 客户端通过FileSystem(DistributedFileSystem)对象的create()方法打开希望读取的文件
2. DistributedFileSystem向namenode,发送RPC调用,在文件系统中的命名空间中新建一个文件,此时文件中还没有数据块
3. Namenode执行各种检查,这个文件不存在以及客户端有新建该文件的权限。
4. DistributedFileSystem向客户端返回一个FSDataOutputStream对象,进而封装成DFSoutputStream对象,该对象负责datanode与namenode之间的通信。
5. DFSOutputStream将数据包写入数据队列(64KB)。
6. Datanode列表构成一个管线,依次写入数据。
7. DFSOutputStream也维护着一个确认队列,收到管道中所有节点的确认信息后,该数据包才会删除。
8. 客户端完成数据的写入后,对数据调用close()方法。
一致模型
1. 新建一个文件后,它能在命名空间中立即可见,但写入的内容并不保证立即可见。
2. FSDataOutputStream的sync()方法可以同步写入的数据。(close())。
Hadoop数据的完整性
1. io.bytes.per.checksum指定字节的数据计算校验和。默认情况下时512字节,CRC-32的校验和为4个字节。
2. datanode负责存储数据校验和,客户端读取数据时会和存储的校验和比较。
3. open()方法读取文件之前,将false值传递给FileSystem对象的setVerifyChecjsum()方法禁用校验。
4. -get –ignoreCrc -copyToLocal禁用检验
5. Hadoop的LocalFileSystem执行客户端的校验。RawLocalFileSystem实例的读操作禁用校验和。 Fs.file.impl设置为org.apache.hadoop.fs.RawLocalFileSystem
压缩
1. 好处:减少文件所需的磁盘空间,加快数据在网络中的传输。
2. Mapreduce处理的数据,压缩的格式需要支持切分。
3. 压缩Mapreduce作业的输出,应在作业配置过程中将mapred.output.compress设置为true,mapred.output.compression.codec 设置为使用压缩codec的类名。
FileOutputFormat.setCompressOutput(job, true)
FileOutputFormat.setOutputCompressorClass(job, GzipCodec.class)
4. Mapred.output.compression.type 默认为RECORD,即对每条记录进行压缩。BLOCK,针对一组记录进行压缩
5. Map任务进行压缩mapred.compress.map.output 设置为true
Mapred.map.output.compression.codec
序列化
1. 序列化是指将结构化对象转化为字节流以便在网络上传输或写到磁盘进行永久存储。
反序列化是指将字节流转回结构化对象的逆过程
2. Hadoop序列化格式Writable
3. Writable接口定义两个方法
Void write(DataInput out) throws IOExcepthion;
Void readFields(DataInput in) throws IOException;
4 创建Intwritable对象 Intwritable writable = new IntWritable(5);
writable.set(5);
WritableComparable接口和comparator
IntWritable实现原始的WritableComparable接口,该接口继承自Writable和java.lang.Comparable接口。类型比较很重要,在mapreduce的过程有基于键排序阶段。
WritableComparator 提供对原始compare()方法的一个默认实现,该方法能够反序列化将在流中进行比较的对象,并调用对象的compare()方法。