写点什么

Hadoop 2.0 NameNode HA 和 Federation 实践

  • 2012-12-13
  • 本文字数:9179 字

    阅读完需:约 30 分钟

2013 年,InfoQ 将会密切关注大数据领域的最新进展,并在“大数据专栏“中向读者展示优秀的开发实践,欢迎大家向InfoQ 投稿和广大的开发者分享在大数据的开发经验和心得,投稿地址: editors@cn.infoq.com

一、背景

天云趋势在 2012 年下半年开始为某大型国有银行的历史交易数据备份及查询提供基于 Hadoop 的技术解决方案,由于行业的特殊性,客户对服务的可用性有着非常高的要求,而 HDFS 长久以来都被单点故障的问题所困扰,直到 Apache Hadoop 在 2012 年 5 月发布了 2.0 的 alpha 版本,其中 MRv2 还很不成熟,可 HDFS 的新功能已经基本可用,尤其是其中的的 High Availability(以下简称 HA) 和 Federation。Cloudera 也于 7 月制作了 CDH4.0.1,包含了 Hadoop 2.0 的诸多新功能和组件,于是我们就基于 CDH4.0.1 进行了 HA 和 Federation 的测试。

此工作由我和同事张军、钱兴会共同完成。

二、为什么需要 HA 和 Federation

1. 单点故障

在 Hadoop 2.0 之前,也有若干技术试图解决单点故障的问题,我们在这里做个简短的总结

  • Secondary NameNode。它不是 HA,它只是阶段性的合并 edits 和 fsimage,以缩短集群启动的时间。当 NameNode(以下简称 NN) 失效的时候,Secondary NN 并无法立刻提供服务,Secondary NN 甚至无法保证数据完整性:如果 NN 数据丢失的话,在上一次合并后的文件系统的改动会丢失。
  • Backup NameNode ( HADOOP-4539 )。它在内存中复制了 NN 的当前状态,算是 Warm Standby,可也就仅限于此,并没有 failover 等。它同样是阶段性的做 checkpoint,也无法保证数据完整性。
  • 手动把 name.dir 指向 NFS。这是安全的 Cold Standby,可以保证元数据不丢失,但集群的恢复则完全靠手动。
  • Facebook AvatarNode 。Facebook 有强大的运维做后盾,所以 Avatarnode 只是 Hot Standby,并没有自动切换,当主 NN 失效的时候,需要管理员确认,然后手动把对外提供服务的虚拟 IP 映射到 Standby NN,这样做的好处是确保不会发生脑裂的场景。其某些设计思想和 Hadoop 2.0 里的 HA 非常相似,从时间上来看,Hadoop 2.0 应该是借鉴了 Facebook 的做法。
  • 还有若干解决方案,基本都是依赖外部的 HA 机制,譬如 DRBD Linux HA VMware 的 FT 等等。

2. 集群容量和集群性能

单 NN 的架构使得 HDFS 在集群扩展性和性能上都有潜在的问题,当集群大到一定程度后,NN 进程使用的内存可能会达到上百 G,常用的估算公式为 1G 对应 1 百万个块,按缺省块大小计算的话,大概是 64T (这个估算比例是有比较大的富裕的,其实,即使是每个文件只有一个块,所有元数据信息也不会有 1KB/block)。同时,所有的元数据信息的读取和操作都需要与 NN 进行通信,譬如客户端的 addBlock、getBlockLocations,还有 DataNode 的 blockRecieved、sendHeartbeat、blockReport,在集群规模变大后,NN 成为了性能的瓶颈。Hadoop 2.0 里的 HDFS Federation 就是为了解决这两个问题而开发的。

三、Hadoop 2.0 里 HA 的实现方式

图片来源: HDFS-1623 设计文档

图片作者: Sanjay Radia, Suresh Srinivas

在这个图里,我们可以看出 HA 的大致架构,其设计上的考虑包括:

  • 利用共享存储来在两个 NN 间同步 edits 信息。
    以前的 HDFS 是 share nothing but NN,现在 NN 又 share storage,这样其实是转移了单点故障的位置,但中高端的存储设备内部都有各种 RAID 以及冗余硬件包括电源以及网卡等,比服务器的可靠性还是略有提高。通过 NN 内部每次元数据变动后的 flush 操作,加上 NFS 的 close-to-open,数据的一致性得到了保证。社区现在也试图把元数据存储放到 BookKeeper 上,以去除对共享存储的依赖,Cloudera 也提供了 Quorum Journal Manager 的实现和代码,这篇中文的 blog 有详尽分析:基于 QJM/Qurom Journal Manager/Paxos 的 HDFS HA 原理及代码分析

  • DataNode(以下简称 DN) 同时向两个 NN 汇报块信息。
    这是让 Standby NN 保持集群最新状态的必需步骤,不赘述。

  • 用于监视和控制 NN 进程的 FailoverController 进程
    显然,我们不能在 NN 进程内进行心跳等信息同步,最简单的原因,一次 FullGC 就可以让 NN 挂起十几分钟,所以,必须要有一个独立的短小精悍的 watchdog 来专门负责监控。这也是一个松耦合的设计,便于扩展或更改,目前版本里是用 ZooKeeper(以下简称 ZK) 来做同步锁,但用户可以方便的把这个 ZooKeeper FailoverController(以下简称 ZKFC) 替换为其他的 HA 方案或 leader 选举方案。

  • 隔离 (Fencing) ,防止脑裂,就是保证在任何时候只有一个主 NN,包括三个方面:

    • 共享存储 fencing,确保只有一个 NN 可以写入 edits。
    • 客户端 fencing,确保只有一个 NN 可以响应客户端的请求。
    • DataNode fencing,确保只有一个 NN 可以向 DN 下发命令,譬如删除块,复制块,等等。

四、Hadoop 2.0 里 Federation 的实现方式

图片来源: HDFS-1052 设计文档
图片作者: Sanjay Radia, Suresh Srinivas

这个图过于简明,许多设计上的考虑并不那么直观,我们稍微总结一下

  • 多个 NN 共用一个集群里 DN 上的存储资源,每个 NN 都可以单独对外提供服务
  • 每个 NN 都会定义一个存储池,有单独的 id,每个 DN 都为所有存储池提供存储
  • DN 会按照存储池 id 向其对应的 NN 汇报块信息,同时,DN 会向所有 NN 汇报本地存储可用资源情况
  • 如果需要在客户端方便的访问若干个 NN 上的资源,可以使用客户端挂载表,把不同的目录映射到不同的 NN,但 NN 上必须存在相应的目录

这样设计的好处大致有:

  • 改动最小,向前兼容
    • 现有的 NN 无需任何配置改动.
    • 如果现有的客户端只连某台 NN 的话,代码和配置也无需改动。
  • 分离命名空间管理和块存储管理
    • 提供良好扩展性的同时允许其他文件系统或应用直接使用块存储池
    • 统一的块存储管理保证了资源利用率
    • 可以只通过防火墙配置达到一定的文件访问隔离,而无需使用复杂的 Kerberos 认证
  • 客户端挂载表
    • 通过路径自动对应 NN
    • 使 Federation 的配置改动对应用透明

五、测试环境

以上是 HA 和 Federation 的简介,对于已经比较熟悉 HDFS 的朋友,这些信息应该已经可以帮助你快速理解其架构和实现,如果还需要深入了解细节的话,可以去详细阅读设计文档或是代码。这篇文章的主要目的是总结我们的测试结果,所以现在才算是正文开始。

为了彻底搞清 HA 和 Federation 的配置,我们直接一步到位,选择了如下的测试场景,结合了 HA 和 Federation:

这张图里有个概念是前面没有说明的,就是 NameService。Hadoop 2.0 里对 NN 进行了一层抽象,提供服务的不再是 NN 本身,而是 NameService(以下简称 NS)。Federation 是由多个 NS 组成的,每个 NS 又是由一个或两个 (HA)NN 组成的。在接下里的测试配置里会有更直观的例子。

图中 DN-1 到 DN-6 是六个 DataNode,NN-1 到 NN-4 是四个 NameNode,分别组成两个 HA 的 NS,再通过 Federation 组合对外提供服务。Storage Pool 1 和 Storage Pool 2 分别对应这两个 NS。我们在客户端进行了挂载表的映射,把 /share 映射到 NS1,把 /user 映射到 NS2,这个映射其实不光是要指定 NS,还需要指定到其上的某个目录,稍后的配置中大家可以看到。

下面我们来看看配置文件里需要做哪些改动,为了便于理解,我们先把 HA 和 Federation 分别介绍,然后再介绍同时使用 HA 和 Federation 时的配置方式,首先我们来看 HA 的配置:

对于 HA 中的所有节点,包括 NN 和 DN 和客户端,需要做如下更改:

HA,所有节点,hdfs-site.xml

复制代码
<property>
<name>dfs.nameservices</name>
<value>ns1</value>
<description> 提供服务的 NS 逻辑名称,与 core-site.xml 里的对应 </description>
</property>
<property>
<name>dfs.ha.namenodes.${NS_ID}</name>
<value>nn1,nn3</value>
<description> 列出该逻辑名称下的 NameNode 逻辑名称 </description>
</property>
<property>
<name>dfs.namenode.rpc-address.${NS_ID}.${NN_ID}</name>
<value>host-nn1:9000</value>
<description> 指定 NameNode 的 RPC 位置 </description>
</property>
<property>
<name>dfs.namenode.http-address.${NS_ID}.${NN_ID}</name>
<value>host-nn1:50070</value>
<description> 指定 NameNode 的 Web Server 位置 </description>
</property>

以上的示例里,我们用了 ${}来表示变量值,其展开后的内容大致如下:

dfs.ha.namenodes.ns1 nn1,nn3

dfs.namenode.rpc-address.ns1.nn1 host-nn1:9000

dfs.namenode.http-address.ns1.nn1 host-nn1:50070

dfs.namenode.rpc-address.ns1.nn3 host-nn3:9000

dfs.namenode.http-address.ns1.nn3 host-nn3:50070

与此同时,在 HA 集群的 NameNode 或客户端还需要做如下配置的改动:

HA,NameNode,hdfs-site.xml

复制代码
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>file:///nfs/ha-edits</value>
<description> 指定用于 HA 存放 edits 的共享存储,通常是 NFS 挂载点 </description>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>host-zk1:2181,host-zk2:2181,host-zk3:2181,</value>
<description> 指定用于 HA 的 ZooKeeper 集群机器列表 </description>
</property>
<property>
<name>ha.zookeeper.session-timeout.ms</name>
<value>5000</value>
<description> 指定 ZooKeeper 超时间隔,单位毫秒 </description>
</property>
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
<description> 指定 HA 做隔离的方法,缺省是 ssh,可设为 shell,稍后详述 </description>
</property>
HA,客户端,hdfs-site.xml
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
<description> 或者 false</description>
</property>
<property>
<name>dfs.client.failover.proxy.provider.${NS_ID}</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
<description> 指定客户端用于 HA 切换的代理类,不同的 NS 可以用不同的代理类
以上示例为 Hadoop 2.0 自带的缺省代理类 </description>
</property>

最后,为了方便使用相对路径,而不是每次都使用 hdfs://ns1 作为文件路径的前缀,我们还需要在各角色节点上修改 core-site.xml:

HA,所有节点,core-site.xml

复制代码
<property>
<name>fs.defaultFS</name>
<value>hdfs://ns1</value>
<description> 缺省文件服务的协议和 NS 逻辑名称,和 hdfs-site 里的对应
此配置替代了 1.0 里的 fs.default.name</description>
</property>

接下来我们看一下如果单独使用 Federation,应该如何配置,这里我们假设没有使用 HA,而是直接使用 nn1 和 nn2 组成了 Federation 集群,他们对应的 NS 的逻辑名称分别是 ns1 和 ns2。为了便于理解,我们从客户端使用的 core-site.xml 和挂载表入手:

Federation,所有节点,core-site.xml

复制代码
<xi:include href=“cmt.xml"/>
<property>
<name>fs.defaultFS</name>
<value>viewfs://nsX</value>
<description> 整个 Federation 集群对外提供服务的 NS 逻辑名称,
注意,这里的协议不再是 hdfs,而是新引入的 viewfs
这个逻辑名称会在下面的挂载表中用到 </description>
</property>

我们在上面的 core-site 中包含了一个 cmt.xml 文件,也就是 Client Mount Table,客户端挂载表,其内容就是虚拟路径到具体某个 NS 及其物理子目录的映射关系,譬如 /share 映射到 ns1 的 /real_share,/user 映射到 ns2 的 /real_user,示例如下:

Federation,所有节点,cmt.xml

复制代码
<configuration>
<property>
<name>fs.viewfs.mounttable.nsX.link./share</name>
<value>hdfs://ns1/real_share</value>
</property>
<property>
<name>fs.viewfs.mounttable.nsX.link./user</name>
<value>hdfs://ns2/real_user</value>
</property>
</configuration>

注意,这里面的 nsX 与 core-site.xml 中的 nsX 对应。而且对每个 NS,你都可以建立多个虚拟路径,映射到不同的物理路径。与此同时,hdfs-site.xml 中需要给出每个 NS 的具体信息:

Federation,所有节点,hdfs-site.xml

复制代码
<property>
<name>dfs.nameservices</name>
<value>ns1,ns2</value>
<description> 提供服务的 NS 逻辑名称,与 core-site.xml 或 cmt.xml 里的对应 </description>
</property>
<property>
<name>dfs.namenode.rpc-address.ns1</name>
<value>host-nn1:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.ns1</name>
<value>host-nn1:50070</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns2</name>
<value>host-nn2:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.ns2</name>
<value>host-nn2:50070</value>
</property>

可以看到,在只有 Federation 且没有 HA 的情况下,配置的 name 里只需要直接给出 ${NS_ID},然后 value 就是实际的机器名和端口号,不需要再.${NN_ID}。

这里有一个情况,就是 NN 本身的配置。从上面的内容里大家可以知道,NN 上是需要事先建立好客户端挂载表映射的目标物理路径,譬如 /real_share,之后才能通过以上的映射进行访问,可是,如果不指定全路径,而是通过映射 + 相对路径的话,客户端只能在挂载点的虚拟目录之下进行操作,从而无法创建映射目录本身的物理目录。所以,为了在 NN 上建立挂载点映射目录,我们就必须在命令行里使用 hdfs 协议和绝对路径:

复制代码
hdfs dfs -mkdir hdfs://ns1/real_share

上面这个问题,我在 EasyHadoop 的聚会上没有讲清楚,只是简单的说在 NN 上不要使用 viewfs:// 来配置,而是使用 hdfs://,那样是可以解决问题,但是是并不是最好的方案,也没有把问题的根本说清楚。

最后,我们来组合 HA 和 Federation,真正搭建出和本节开始处的测试环境示意图一样的实例。通过前面的描述,有经验的朋友应该已经猜到了,其实 HA+Federation 配置的关键,就是组合 hdfs-site.xml 里的 dfs.nameservices 以及 dfs.ha.namenodes.${NS_ID},然后按照 ${NS_ID}和 ${NN_ID}来组合 name,列出所有 NN 的信息即可。其余配置一样。

HA + Federation,所有节点,hdfs-site.xml

复制代码
<property>
<name>dfs.nameservices</name>
<value>ns1, ns2</value>
</property>
<property>
<name>dfs.ha.namenodes.ns1</name>
<value>nn1,nn3</value>
</property>
<property>
<name>dfs.ha.namenodes.ns2</name>
<value>nn2,nn4</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns1.nn1</name>
<value>host-nn1:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.ns1.nn1</name>
<value>host-nn1:50070</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns1.nn3</name>
<value>host-nn3:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.ns1.nn3</name>
<value>host-nn3:50070</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns2.nn2</name>
<value>host-nn2:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.ns2.nn2</name>
<value>host-nn2:50070</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns2.nn4</name>
<value>host-nn4:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.ns2.nn4</name>
<value>host-nn4:50070</value>
</property>

对于没有.${NS_ID},也就是未区分 NS 的项目,需要在每台 NN 上分别使用不同的值单独配置,尤其是 NFS 位置 (dfs.namenode.shared.edits.dir),因为不同 NS 必定要使用不同的 NFS 目录来做各自内部的 HA (除非 mount 到本地是相同的,只是在 NFS 服务器端是不同的,但这样是非常不好的实践);而像 ZK 位置和隔离方式等其实大可使用一样的配置。

除了配置以外,集群的初始化也有一些额外的步骤,譬如,创建 HA 环境的时候,需要先格式化一台 NN,然后同步其 name.dir 下面的数据到第二台,然后再启动集群 (我们没有测试从单台升级为 HA 的情况,但道理应该一样)。在创建 Federation 环境的时候,需要注意保持 ${CLUSTER_ID}的值,以确保所有 NN 能共享同一个集群的存储资源,具体做法是在格式化第一台 NN 之后,取得其 ${CLUSTER_ID}的值,然后用如下命令格式化其他 NN:

复制代码
hadoop namenode -format -clusterid ${CLUSTER_ID}

当然,你也可以从第一台开始就使用自己定义的 ${CLUSTER_ID}值。

如果是 HA + Federation 的场景,则需要用 Federation 的格式化方式初始化两台,每个 HA 环境一台,保证 ${CLUSTER_ID}一致,然后分别同步 name.dir 下的元数据到 HA 环境里的另一台上,再启动集群。

Hadoop 2.0 中的 HDFS 客户端和 API 也有些许更改,命令行引入了新的 hdfs 命令,hdfs dfs 就等同于以前的 hadoop fs 命令。API 里引入了新的 ViewFileSystem 类,可以通过它来获取挂载表的内容,如果你不需要读取挂载表内容,而只是使用文件系统的话,可以无视挂载表,直接通过路径来打开或创建文件。代码示例如下:

复制代码
ViewFileSystem fsView = (ViewFileSystem) ViewFileSystem.get(conf);
MountPoint[] m = fsView.getMountPoints();
for (MountPoint m1 : m)
System.out.println( m1.getSrc() );
// 直接使用 /share/test.txt 创建文件
// 如果按照之前的配置,客户端会自动根据挂载表找到是 ns1
// 然后再通过 failover proxy 类知道 nn1 是 Active NN 并与其通信
Path p = new Path("/share/test.txt");
FSDataOutputStream fos = fsView.create(p);

六、HA 测试方案和结果

Federation 的测试主要是功能性上的,能用就 OK 了,这里的测试方案只是针对 HA 而言。我们设计了两个维度的测试矩阵:系统失效方式,客户端连接模型

系统失效有两种:

  1. 终止 NameNode 进程:ZKFC 主动释放锁
    模拟机器 OOM、死锁、硬件性能骤降等故障
  2. NN 机器掉电:ZK 锁超时
    模拟网络和交换机故障、以及掉电本身

客户端连接也是两种:

  1. 已连接的客户端 (持续拷贝 96M 的文件,1M 每块)
    通过增加块的数目,我们希望客户端会不断的向 NN 去申请新的块;一般是在第一个文件快结束或第二个文件刚开始拷贝的时候使系统失效。
  2. 新发起连接的客户端 (持续拷贝 96M 的文件,100M 每块)
    因为只有一个块,所以在实际拷贝过程中失效并不会立刻导致客户端或 DN 报错,但下一次新发起连接的客户端会一开始就没有 NN 可连;一般是在第一个文件快结束拷贝时使系统失效。

针对每一种组合,我们反复测试 10-30 次,每次拷贝 5 个文件进入 HDFS,因为时间不一定掐的很准,所以有时候也会是在第三或第四个文件的时候才使系统失效,不管如何,我们会在结束后从 HDFS 里取出所有文件,并挨个检查文件 MD5,以确保数据的完整性。

测试结果如下:

  • ZKFC 主动释放锁
    • 5-8 秒切换 (需同步 edits)
    • 客户端偶尔会有重试 (~10%)
    • 但从未失败
  • ZK 锁超时
    • 15-20s 切换 (超时设置为 10s)
    • 客户端重试几率变大 (~75%)
    • 且偶有失败 (~15%),但仅见于已连接客户端
  • 可确保数据完整性
    • MD5 校验从未出错 + 失败时客户端有 Exception

我们的结论是:Hadoop 2.0 里的 HDFS HA 基本可满足高可用性

扩展测试

我们另外还 (试图) 测试 Append 时候 NN 失效的情形,因为 Append 的代码逻辑非常复杂,所以期望可以有新的发现,但是由于复杂的那一段只是在补足最尾部块的时候,所以必须在测试程序一运行起来就关掉 NN,测了几次,没发现异常情况。另外我们还使用 HBase 进行了测试,由于 WAL 只是 append,而且 HFile 的 compaction 操作又并不频繁,所以也没有遇到问题。

七、HA 推荐配置及其他

HA 推荐配置

  • ha.zookeeper.session-timeout.ms = 10000
    • ZK 心跳是 2000
    • 缺省的 5000 很容易因为网络拥塞或 NN GC 等导致误判
    • 为避免电源闪断,不要把 start-dfs.sh 放在 init.d 里
  • dfs.ha.fencing.methods = shell(/path/to/the/script)
    • STONITH (Shoot The Other Node In The Head) 不一定可行,当没有网络或掉电的时候,是没法 shoot 的
    • 缺省的隔离手段是 sshfence,在掉电情况下就无法成功完成,从而切换失败
    • 唯一能保证不发生脑裂的方案就是确保原 Active 无法访问 NFS
      • 通过 script 修改 NFS 上的 iptables,禁止另一台 NN 访问
      • 管理员及时介入,恢复原 Active,使其成为 Standby。恢复 iptables

客户端重试机制

代码可在 org.apache.hadoop.io.retry.RetryPolicies.FailoverOnNetworkExceptionRetry 里找到。目前的客户端在遇到以下 Exception 时启动重试:

复制代码
// 连接失败
ConnectException
NoRouteToHostException
UnKnownHostException
// 连到了 Standby 而不是 Active
StandbyException

其重试时间间隔的计算公式为:

RAND(0.5~1.5) * min (2^retryies * baseMillis, maxMillis)

baseMillis = dfs.client.failover.sleep.base.millis,缺省 500

maxMillis = dfs.client.failover.sleep.max.millis,缺省 15000

最大重试次数:dfs.client.failover.max.attempts,缺省 15

未尽事宜

关于那 15% 失败的情况,我们从日志和代码分析,基本确认是 HA 里的问题,就是 Standby NN 在变为 Active NN 的过程中,会试图重置文件的 lease 的 owner,从而导致 LeaseExpiredException: Lease mismatch,客户端遇到这个异常不会重试,导致操作失败。这是一个非常容易重现的问题,相信作者也知道,可能是为了 lease 安全性也就是数据完整性做的一个取舍吧:宁可客户端失败千次,不可 lease 分配错一次,毕竟,客户端失败再重新创建文件是一个很廉价且安全的过程。另外,与 MapReduce 2.0 (YARN) 的整合测试我们也没来得及做,原因是我们觉得 YARN 本身各个组件的 HA 还不完善,用它来测 HDFS 的 HA 有点本末倒置。

关于天云趋势

天云趋势由天云科技和趋势科技共同投资成立于 2010 年 3 月,趋势科技是 Hadoop 的重度使用者:2006 年开始使用, 用于处理 Web Reputation 和 Email Reputation 等、五个数据中心,近 1000 个节点、日均处理 3.6T 日志数据、亚洲最早的主要代码贡献者、HBase 0.92 新功能的主要开发者 (coprocessors, security);

天云趋势的 BigData 业务:TCloud BigData Platform; 集部署、监控、配置优化、数据处理以及扩展 SDK 库于一体的集群管理和开发平台;丰富的垂直行业开发经验, 包括电信、电力、银行等、为多家大型传统软件开发厂商提供咨询服务; Hadoop 管理员、开发者培训;也可为企业内部进行定制化培训,详情请访问: http://www.tcloudcomputing.com.cn

关于作者

孙振南,资深系统架构师。天云趋势技术总监。曾就职趋势科技 10 年。参与了云端网页评级、云端垃圾邮件过滤等核心业务系统的构建。作者博客

投稿原文地址: Hadoop 2.0 NameNode HA 和 Federation 实践

2012-12-13 00:0016748

评论

发布
暂无评论
发现更多内容

synchronized 优化手段之锁膨胀机制!

王磊

Java 并发 8月日更

Druid 通过 dsql 运行的时候提示错误 urllib2

HoneyMoose

netty系列之:netty初探

程序那些事

Java 响应式编程 Netty nio 程序那些事

Design for failure常见的12种设计思想

架构精进之路

降级 重试 容错 8月日更

kafka SpringBoot

Rubble

kafka springboot 8月日更

Druid 从控制台(Druid console)从 SQL 脚本转换为 JSON 格式的方法

HoneyMoose

【Maven技术专题】如何使用Assembly插件实现自定义打包

洛神灬殇

maven assembly 8月日更

多语言ASR?没有什么听不懂,15种语言我全都要

华为云开发者联盟

语言 ASR 多语言ASR 单语模型 Conformer

Springboot 配置文件、隐私数据脱敏的最佳实践(原理+源码)

程序员小富

Java springboot 数据安全 数据脱敏

基于docker的分布式性能测试框架功能验证(二)

FunTester

分布式 性能测试 接口测试 测试框架 测试开发

Druid 的几个查询实例

HoneyMoose

【设计模式】原型

Andy阿辉

C# 编程 后端 设计模式 8月日更

Rust从0到1-模式-可反驳性

rust 模式 Patterns Refutability 可反驳性

基于ECS快速搭建 Docker 环境

若尘

Docker 服务器 8月日更

索信达控股:银行4.0的AI世界——开启算法力的时代

索信达控股

人工智能 金融科技 银行

复杂多变场景下的Groovy脚本引擎实战

vivo互联网技术

敏捷开发 脚本语言

原来select语句在MySQL中是这样执行的!看完又涨见识了!这回我要碾压面试官!

冰河

MySQL 面试 精通MySQL SELECT查询流程 查询缓存

Python OpenCV 图像区域轮廓标记,可用于框选各种小纸条

梦想橡皮擦

8月日更

Python代码阅读(第1篇):列表映射后的平均值

Felix

Python 编程 Code Programing 阅读代码

鸿蒙内核之内存调测:动态内存池信息统计

华为云开发者联盟

鸿蒙 内存 动态内存池 内存信息

Druid 从控制台(Druid console)中删除过滤器和运行查询

HoneyMoose

【Flutter 专题】132 图解 PaginatedDataTable 分页表格

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 8月日更

分布式性能测试框架用例方案设想(二)

FunTester

分布式 性能测试 接口测试 测试框架 测试开发

深度学习中的分布式训练

安第斯智能云

人工智能 深度学习

重磅 | 用友《数字化中台》震撼上市!数智化转型和商业创新实践的企业级经验!

博文视点Broadview

百度爱番番移动端网页秒开实践

百度Geek说

大前端 优化 网页加速 移动端

docker入门:postgresql安装及可视化界面portainer使用

小鲍侃java

8月日更

十大排序算法--插入排序

Ayue、

排序算法 8月日更

手撸二叉树之对称二叉树

HelloWorld杰少

算法和数据结构 8月日更

一文带你搞定AOP切面

华为云开发者联盟

spring aop 切面编程 面向切面编程 切面

PostgreSQL 中如何控制行级安全和列级安全

Qunar技术沙龙

sql postgresql 运维 安全 权限

Hadoop 2.0 NameNode HA和Federation实践_DevOps & 平台工程_孙振南_InfoQ精选文章