前言
在企业里面,我们搭建一个服务一般都会考虑几个问题。首先是用途,比方说一般都有开发环境,测试环境以及生产环境(比较重要的服务一般还会有灰度环境)。这个用途一旦决定了,我们就可以考虑接下来的问题了。第二是架构,第三就是成本了。架构会直接决定所需要花费的机器成本和维护成本。好吧,好像有点扯远了。。。回到正题。这里我想要说明的事情是我当上大数据运维之后,遇到的坑其实都可以归根溯源到架构或者原理的理解上面。所以我特别想记录一下hdfs和yarn的架构,遇到坑的时候回想一下或许可以从这里找到解决问题的思路。
HDFS
hdfs包含两种角色,Namenode和Datanode。下面是一张官方架构图。
hdfs是典型的主从架构。在hdfs的内部,文件是会被划分成多个块,块被存储在一组slave里面(就是图里的绿色小方格)。
master负责管理文件系统的命名空间(比如打开文件,关闭文件以及重命名文件和文件夹),客户端对文件系统的访问权限以及块和slave的映射关系。
slave负责存储文件,处理客户端的读写请求并且根据master的指令对块进行创建,删除以及复制。
下面分几个方面描述一个hdfs这个分布式文件系统。
- 命名空间
像大多数文件系统一样,用户可以对文件(夹)进行增删改查。NN负责维护这些对命名空间进行操作的元数据信息。
- 数据复制
在HDFS的内部,文件会被分成大小相同的多个块进行存储,同时,为了实现容错,这些块会被复制多份并散落在不同的DN上进行存储。这个块大小和复制份数是可以由用户定义的。上面提到DN是存储这些块的,NN是负责管理块和DN的映射关系,那么,这里我们有两个东西,一个是心跳,另一个是块报告。DN周期性向NN发送心跳信息和块报告。心跳是告诉NN它还活着,块报告是告诉NN它有哪些块。详细如图所示。
那么,块是怎么存储会比较方便呢?这里面我们考虑两个东西。一个是高可用,另一个是读写性能。上面提到了,为了保证数据安全可靠,hdfs会将数据分割成多个大小相同的块并且对块进行复制之后分散存储。虽然这个做法满足了数据安全可靠的要求,但是此时我们遇到了另一个问题,读写效率。如果我们将块存储在不同机架,带宽会成为效率的瓶颈。但是都存在一个机架,那么安全可靠性就大大降低了。通常的做法是将复制因子设置为3,然后按照以下策略放置副本。
副本No.1:如果客户端正在这个DN上面写,那么就放在这个DN;否则,在这个机架任意选取一个DN
副本No.2:放在和第一份副本不同的机架上面的某个节点
副本No.3:放在第二份副本那个机架上的不同节点上面
总的来说,就是一个副本在一个节点,另一个副本在另一个机架的一个节点上,最后一个副本均匀分布在第二个副本那个机架的不同节点上。
使用这个策略我们提高了读写效率(降低机架之间传输的所需带宽)和不影响数据的安全可靠。同时,HDFS有一个就近读的策略,默认是会选取离接收读请求那个DN最近的块以降低带宽的开销。这是所谓的块选择。同时,这里有一个安全模式,当NN发现它安全的时候,它才会继续接受请求。那怎么判断安全呢?那就是副本数达到一个可承受的最小值。
- 元数据持久化
这里我们说两个文件,一个是EditlLog,另一个是FsImage。
EditLog:记录文件系统元数据的变化。比如新增一个文件之类。修改复制因子的操作这里也会记录
FsImage:保存整个文件系统的命名空间,包括文件的块映射以及文件系统的一些属性
其实EditLog是记录操作的,FsImage是保存被操作的文件系统的。那么这里我们有一个叫checkpoint的东西,它的工作原理是当NN启动的时候,会从磁盘读取EditLog和FsImage这两个文件,并将EditLog里面记录的操作应用到FsImage然后生成一个新版本的FsImage,然后会删掉这个EditLog。这个过程就是checkpoint了。
- 鲁棒性
磁盘故障,心跳信息与重复制
每个DN都会定期发送心跳信息到NN表示自己还活着。假设出现网络问题,NN会标记此DN已经失联,这时候便不再转发任何的IO请求给它,同时NN会触发re-replication。其实,磁盘只读,DN失联或者block损坏都是会令NN触发re-replication的。数据检验
NN会对新写入的文件做一个校验和然后存在一个隐藏文件里面,当客户端要读这个文件,NN会将从各个DN读回来的block的检验值和隐藏文件里面的进行对比。如果对,那么读出来,错误,就继续寻找其他无损的block。snapshot
其实就是用来回滚到你做这个快照的时候的状态。
- 数据写过程
数据块
HDFS天生就是用来处理大文件的。默认的块大小是64mb,可以在配置文件调节。写过程
写入数据的时候客户端会现将内容写到一个临时文件里,当临时文件超过块大小之后,客户端会通知NN。NN会修改文件系统层级并为其分配一个数据块,NN响应客户端的请求,告诉客户端放到哪个DN的哪个数据块里面去。然后客户端将临时文件的内容写到NN指定的DN。当一个文件写完了,剩下的临时文件会直接被发送到DN,然后客户端告诉NN搞定了。NN确认之后将文件状态从创建变为永久存储。(如果文件创建过程中NN故障了,那么文件就丢失了。)复制是管道式的
正如上面所说,写的过程里面客户端会获取一个可写的DN列表。这时候(假设复制因子是3),客户端将数据写到第一个DN。第一个DN接收数据并写到本地,然后将数据传输到列表里面的第二个DN,第二个DN和第三个DN同理。
- 空间回收
- 文件删除与恢复
文件被删之后并不是马上移除,而是被移动到trash目录,这时候是可以被恢复的。用户可以设置一个过期时间,时间一过,文件就会被NN移除了。文件移除与空间释放之间会有一个延时。
YARN
yarn有几个角色,都比较重要。我们先看图然后再总结一下角色的作用。
- ResourceManager
RM主要有两个组件,一个是scheduler,另一个是ApplicationManager。
scheduler
这个调度器主要作用是分配资源给任务,比如CPU,memory等等。最流行的有两种调度策略,分别是CapacityScheduler 和 FairScheduler。ApplicationManager
这个应用管家主要负责接受任务提交,为任务启动ApplicationMaster以及负责ApplicationMaster失败后的重启。
NodeManager
如其名,这个组件负责监控并且向RM汇报资源的使用情况。ApplicationMaster
每个任务的AM负责根据调度器的安排分配资源细节,跟踪状态并且监控任务过程。
其实,我们对着上面的这个框架图然后知道每个角色的作用就可以明白YARN架构的工作流程了。
好了,到这里的话我大致就讲完hadoop这个东东里面的主要部分了。我当时所在的团队使用的是CDH版本的hadoop,和社区版还是有一点区别的。但是里面的原理是一样的。
参考
http://archive.cloudera.com/cdh5/cdh/5/hadoop/