此外,有了可用性和扩展性,系统就稳定了吗?实际上不是这样。因为还有很多的突发问题。即使解决了可用性和扩展性,但突发问题还是可能会造成系统不可用,例如由于一些问题造成两台NameNode全部宕机。 首先看一下Flume的扩展性。我们人为的把它定义了两层。一个是FlumeLocal(主要解决一台机器的日志采集问题,简称Local),一个是FlumeCenter(主要从Local上收集数据,然后把数据写到HDFS上,简称Center),Local和Center之间是有一个HA的考虑的,就是Local需要在配置文件里指定两个Center去写入,一旦一个Center出现问题,数据可以马上从另一个Center流向HDFS。 此外,我们还开发了一个高可靠的Agent。业务系统中会把数据产生日志写到磁盘上,Agent保证数据从磁盘上实时可靠的收集给本地的Local,其中我们采用了检查点的技术来解决数据可靠性的问题。 这是Flume的典型架构。Local需要在配置文件里面指定死要连到哪几个Center上。如果说10台,可能还OK,100台也OK,如果一千台呢?如果发现两台Flume Center已经达到机器资源的上限,如何做紧急的扩容呢?所以从这个角度看Flume的扩展性是有问题的。 我们的解决方法是在Local和Center中间加了一个ZooKeeper,Local通过ZK动态发现Center,动态的发现下游有什么,就可以达到Center自动扩容的目标了。我们公司Local有两千多台,扩容一台Center仅需一分钟,这种架构实际上可以支持达到万台规模的,这是Flume扩展性的一些改进。 接下来看一下HDFS扩展性的问题。上面这张图展示了hdfs federation的架构,左侧是一个单namespace架构,即整个目录树在一个namespace中,整个集群的文件数规模受限制于单机内存的限制。federation的思想是把目录树拆分,形成不同的namespace,不同namespace由不同namenode管理,这样就打破了单机资源限制,从而达到了可扩展的目标,如右侧图。 但这个方案有一些隐藏的问题,不知道大家有没有注意到,比如这里每个Datanode都会与所有的NameNode去心跳,如果DataNode数量上万台,那么就可能会出现两个问题:第一,从主节点之间的心跳、块汇报成为瓶颈,第二,如果单个部门的数据规模过大那该怎么办? 针对从主节点之间交互的问题,我们可以进行拆分,控制一个NameNode管理的DateNode的数量,这样就可以避免主从节点交互开销过大的问题。针对单部门数据过大的话可以针对部门内数据进行进一步细拆,就OK了。或者可以考虑百度之前提供的一个方案,即把目录树和inode信息进行抽象,然后分层管理和存储。当然我们目前采用社区federation的方案。如果好好规划的话,也是可以到万台了。 不知道大家有没有在自己运营集群过程中遇到过一些问题,你们是怎么解决的,有些问题可能相当的棘手。突发问题是非常紧急而且重要的,需要在短时间内搞定。接下来我会分享三个例子。 第一个例子是HDFS的Active NN会不定期异常退出,触发HA切换,这就好像一个不定时炸弹一样。这个图展示了HDFS的HA的架构图,客户端进行变更操作(如创建文件)的话会发出请求给namenode,namenode请求处理完之后会进行持久化工作,会在本地磁盘存一份,同时会在共享存储存一份,共享存储是为了active和standby之间同步状态的,standby会周期从共享存储中拉取更新的数据应用到自己的内存和目录树当中,所有的DataNode都是双汇报的,这样两个namenode都会有最新的块信息。最上面的是两个Checker,是为了仲裁究竟谁是Active的。 还有一个过程,Standby NameNode会定期做checkpoint工作,然后在checkpoint做完之后会回传最新的fsimage给active,最终保存在active的磁盘中,默认情况下在回传过程会造成大量的网络和磁盘的压力,导致active的本地磁盘的Util达到100%,此时用户变更请求延迟就会变高。如果磁盘的Util100%持续时间很长就会导致用户请求超时,甚至Checher的检测请求也因排队过长而超时,最终然后触发Checker仲裁HA切换。 (责任编辑:本港台直播) |