一、hadop的项目
Common:一系列组件和接品口,用于分布式文件系统和通用I/O(序列化,Java RPC 和持久化数据结构)
Avro:一种序列化系统,用于支技高效,跨语言的RPC和持久化的数据存储
MapRedue:分布式数据处理模型和执行环境,运行于大型商用机集群
HDFS:分布式文件系统,运行于大型商用机集群
Pig:数据流语言和运行环境,用以探究非常庞大的的数据集。Pig运行在MapReduce和HDFS集群上
Hive:一种分布式,按列存储的数据仓库。Hive管理HDFS中存储数据,并提供基于SQL的查询语言(由运行时引擎翻译成MapReduce作业)用以查询数据
HBase:一种分布式,按列存储的数据库。HBase使用HDFS作为底层存储,同时支MapReduce的批量式计算和点查询(随机读取)
Zookeeper:一种分布式,可用性高的协调服务。Zeekeeper提供分布式锁之类的基本服务用于构建分布式应用。
Sqooq:该工具用于在结构化数据存储(如关系型数据库)和HDFS之间高效批量传输数据。
Oozie:该服务用于运行和调度Hadoop作业(如MapReduce,Pig,Hive及sqoop)。
二、hadoop分布式文件系统
1、HDFS设计
存府超大文件
流式数据访问(一次写入多次读取)
商用硬件(不需要豪华配置)
低时间延迟的数据访问
大量的小文件
多用户写入,任意修改文件
2、数据块
磁盘一般512字节
HDFS默认64M
与其他文件系统不同的是,HDFS中小于一块大小的文件不会占据整个块的空间
HDFS的块比磁盘的块大,主要为了最小化寻址开销
块抽象好处。(一,一个文件的大小可以大于网络任意一个磁盘的容量。因为文件的所有块并不需要存储在同一个磁盘上。二,使用抽象块而非整个文件作为存储单元,简化了存储子系统的设计。三,块适用于数据备份,提供数据容错能力和提高可用性)
三、namenode和datanode
HDFS以管理者-工作者模式运行,一个NN和多个DN,NM管理文件系统的命名空间,维护着文件系统树及整棵树内的所有文件和目录。这些信息保存在(命名镜像文件)和(编辑日志文件);存储元数据与文件到数据块映射的地方
DN是文件系统工作节点,存储并检索数据块,定期向NN发送它们存储块列表。
NN很重要,如果运行NM服务器损块,文件系统上的所有文件将会丢失。所以对NM容错,提供两种机制。一,备份那些组成文件系统元数据持久状态文件。hadoop可以配置使NN在多个文件系统上保存元数据的持久状态。写操作实时同步,是原子操作。一般配置,将持久状态写入本地磁盘的同时,写入一个远程挂载的网络文件系统(NFS)。二;
运行一个辅助NN,但它不能被用作NN,这个辅助NN的重要作用是定期通过编辑日志合并命名空间镜像,以防止编辑日志过大。这个SNN一般在另一台单独的无力计算机上运行,以为他需要占用大量的cpu和NN相同容量的内存来执行合并操作。它会保存合并后的命名空间镜像的副本,并在NN发生故障时启用。但是SNN滞后与NN,所以如果NN全部失效,难免会丢失部分数据。在这种情况下,一般把存储在NFS上的NN元数据复制到SNN并作为新的NN运行。
四、网络拓扑与hadoop
将两个节点间带宽作为距离的衡量标准,以下场景,可以可用带宽依次递减
同一节点上进程
同一机架上的不同节点
同一数据中心不同机架上的节点
不同数据中心的节点
五、数据流
1、剖析文件读取
客户端调用FileSystem 对象的open()方法来打开希望读取的文件,
1.首先调用FileSystem对象的open方法,其实是一个DistributedFileSystem的实例
2.DistributedFileSystem通过rpc获得文件的第一批个block的locations,同一block按照重复数会返回多个locations,这些locations按照hadoop拓扑结构排序,距离客户端近的排在前面.
3.前两步会返回一个FSDataInputStream对象,该对象会被封装成DFSInputStream对象,DFSInputStream可以方便的管理datanode和namenode数据流。客户端调用read方法,DFSInputStream最会找出离客户端最近的datanode并连接(参考第一小节)。
4.数据从datanode源源不断的流向客户端。
5.如果第一块的数据读完了,就会关闭指向第一块的datanode连接,接着读取下一块。这些操作对客户端来说是透明的,客户端的角度看来只是读一个持续不断的流。
6.如果第一批block都读完了,DFSInputStream就会去namenode拿下一批blocks的location,然后继续读,如果所有的块都读完,这时就会关闭掉所有的流。
如果在读数据的时候,DFSInputStream和datanode的通讯发生异常,就会尝试正在读的block的排第二近的datanode,并且会记录哪个datanode发生错误,剩余的blocks读的时候就会直接跳过该datanode。DFSInputStream也会检查block数据校验和,如果发现一个坏的block,就会先报告到namenode节点,然后DFSInputStream在其他的datanode上读该block的镜像
该设计的方向就是客户端直接连接datanode来检索数据并且namenode来负责为每一个block提供最优的datanode,namenode仅仅处理block location的请求,这些信息都加载在namenode的内存中,hdfs通过datanode集群可以承受大量客户端的并发访问。
2、剖析文件写入
客户端通过调用DistributedFileSystem的create方法创建新文件
DistributedFileSystem通过RPC调用namenode去创建一个没有blocks关联的新文件,创建前,namenode会做各种校验,比如文件是否存在,客户端有无权限去创建等。如果校验通过,namenode就会记录下新文件,否则就会抛出IO异常.
前两步结束后会返回FSDataOutputStream的对象,象读文件的时候相似,FSDataOutputStream被封装成DFSOutputStream.DFSOutputStream可以协调namenode和datanode。客户端开始写数据到DFSOutputStream,DFSOutputStream会把数据切成一个个小packet,然后排成队列data quene。
DataStreamer会去处理接受data quene,他先问询namenode这个新的block最适合存储的在哪几个datanode里(参考第二小节),比如重复数是3,那么就找到3个最适合的datanode,把他们排成一个pipeline.DataStreamer把packet按队列输出到管道的第一个datanode中,第一个datanode又把packet输出到第二个datanode中,以此类推。
DFSOutputStream还有一个对列叫ack quene,也是有packet组成,等待datanode的收到响应,当pipeline中的所有datanode都表示已经收到的时候,这时akc quene才会把对应的packet包移除掉。
如果在写的过程中某个datanode发生错误,会采取以下几步:1) pipeline被关闭掉;2)为了防止防止丢包ack quene里的packet会同步到data quene里;3)把产生错误的datanode上当前在写但未完成的block删掉;4)block剩下的部分被写到剩下的两个正常的datanode中;5)namenode找到另外的datanode去创建这个块的复制。当然,这些操作对客户端来说是无感知的。
客户端完成写数据后调用close方法关闭写入流
DataStreamer把剩余得包都刷到pipeline里然后等待ack信息,收到最后一个ack后,通知datanode把文件标示为已完成。
六、hadoop的I/O操作
1、HDFS的数据完整性
HDFS对写入的所有数据计算校验和,并在读取数据时验证交验和,它针对每个由io.bytes.per.checksum指定字节的数据计算校验和。默认512字节,由于CRC-32校验和是4个字节,所以存储校验和的额外开销低于1%
客户端在读取数据块时,如果检测到错误,首先向namenode报告已损坏的数据块及其正在尝试读操作的这个datanode,再抛出ChecksumException异常。namenode将这个数据块复本标记为已损坏,因此,它将不会处理请求直接发送到这个节点,或尝试将这个复本复制到另一个datanode。之后,安排这个数据块的一个复本复制到另一个datanode。
2、序列化
序列化是指将结构化对象转化为字节流以便在网络上传输的或写到磁盘进行永久存储过程。反序列是指将字节流转回结果化的逆向过程。
序列化在分布式数据处理的两大领域常出现:进程间通信和永久存储。
hadoop中,系统中多个节点上进程间通信是通过“远程过程调用(remote procedure call,RPC)实现”,RPC序列化格式如下
紧凑
紧凑格式能充分利用网络带宽(数据中心最稀缺的资源)
快速
进程间通信形成了分布式系统的骨架,尽量减少序列化和反序列的性能开销
可扩展
满足新需求,协议不断变化
支持互操作
支技以不同语言写的客户端与服务器交互
hadoop使用自己序列化格式writable,紧凑,速度化。但不太容易用java以外语言进行扩燕尾服或使用。Writable是hadoop核心(大多数的MapReduce程序都为会键和值使用它)