易陆发现互联网技术论坛

 找回密码
 开始注册
查看: 532|回复: 1
收起左侧

搭建Hadoop的HA高可用架构

[复制链接]
发表于 2022-11-15 10:00:32 | 显示全部楼层 |阅读模式
购买主题 本主题需向作者支付 2 金钱 才能浏览
 楼主| 发表于 2022-11-15 10:00:33 | 显示全部楼层
一、高可用简介
( A& s- x6 C; Y% z% h二、集群规划
( i) ]( G$ a% T1 P三、前置条件/ ?9 A+ p4 }8 O+ L  |( r9 d
四、集群配置' R8 m! |) R$ l4 u% L* a
五、启动集群
, p+ Y" u5 w2 [- c4 o& w& d& r六、查看集群
& ^$ x9 H& |: J9 }七、集群的二次启动
9 g' r# d; o/ [, V6 _: d5 T. U一、高可用简介1 N7 p+ A) i- `! G
Hadoop 高可用 (High Availability) 分为 HDFS 高可用和 YARN 高可用,两者的实现基本类似,但 HDFS NameNode 对数据存储及其一致性的要求比 YARN ResourceManger 高得多,所以它的实现也更加复杂,故下面先进行讲解:/ r3 o* w; T# s6 p, \

6 L, r$ X3 L+ {1.1 高可用整体架构$ \$ }. j, _/ z# n" P4 `. i
HDFS 高可用架构如下:' m, z# f$ M; h( G( L$ |1 _

8 ~& {8 h& t: O
. G. L+ o" [& ]) W图片引用自:https://www.edureka.co/blog/how- ... -high-availability/
% p* M) d7 a  Z+ b2 T# D& {* b5 [
HDFS 高可用架构主要由以下组件所构成:
3 V4 z! W- s. {
0 S5 p! v" [  q6 L/ S. CActive NameNode 和 Standby NameNode:两台 NameNode 形成互备,一台处于 Active 状态,为主 NameNode,另外一台处于 Standby 状态,为备 NameNode,只有主 NameNode 才能对外提供读写服务。* x0 ?. p6 A6 Y8 Y% o, E8 M: M2 }
+ i. T1 w3 G6 x1 e9 |4 p6 R7 m
主备切换控制器 ZKFailoverController:ZKFailoverController 作为独立的进程运行,对 NameNode 的主备切换进行总体控制。ZKFailoverController 能及时检测到 NameNode 的健康状况,在主 NameNode 故障时借助 Zookeeper 实现自动的主备选举和切换,当然 NameNode 目前也支持不依赖于 Zookeeper 的手动主备切换。
. j' Q4 N: D6 h
/ {5 D% b% w) j4 Y* d) VZookeeper 集群:为主备切换控制器提供主备选举支持。. I% E0 G( w2 S4 n( o7 N
. \6 q7 L, e- U" X$ L' L' t, C: A
共享存储系统:共享存储系统是实现 NameNode 的高可用最为关键的部分,共享存储系统保存了 NameNode 在运行过程中所产生的 HDFS 的元数据。主 NameNode 和 NameNode 通过共享存储系统实现元数据同步。在进行主备切换的时候,新的主 NameNode 在确认元数据完全同步之后才能继续对外提供服务。. ~/ Z1 g( i. `
8 G; Y4 v3 V: v" ^- r9 M; S
DataNode 节点:除了通过共享存储系统共享 HDFS 的元数据信息之外,主 NameNode 和备 NameNode 还需要共享 HDFS 的数据块和 DataNode 之间的映射关系。DataNode 会同时向主 NameNode 和备 NameNode 上报数据块的位置信息。
9 w; T3 O9 E2 \! ^  z" Z5 m  u' }8 @* M( W4 w" F+ D" Z8 j
1.2 基于 QJM 的共享存储系统的数据同步机制分析
) U; V( N" D# a  t; R; _- {5 \目前 Hadoop 支持使用 Quorum Journal Manager (QJM) 或 Network File System (NFS) 作为共享的存储系统,这里以 QJM 集群为例进行说明:Active NameNode 首先把 EditLog 提交到 JournalNode 集群,然后 Standby NameNode 再从 JournalNode 集群定时同步 EditLog,当 Active NameNode 宕机后, Standby NameNode 在确认元数据完全同步之后就可以对外提供服务。
. \8 P$ q$ B& B& }" t9 h3 y/ r! j$ J) u% l+ s
需要说明的是向 JournalNode 集群写入 EditLog 是遵循 “过半写入则成功” 的策略,所以你至少要有 3 个 JournalNode 节点,当然你也可以继续增加节点数量,但是应该保证节点总数是奇数。同时如果有 2N+1 台 JournalNode,那么根据过半写的原则,最多可以容忍有 N 台 JournalNode 节点挂掉。
0 b$ b. H1 u1 T4 P
% S# O" ]& q2 d; t1 Q: @2 z. b1 Z' J$ v* R& G! [
1.3 NameNode 主备切换( ]5 \  M, t1 Q7 Y
NameNode 实现主备切换的流程下图所示:. [1 I  U7 G. t! G6 K+ I8 l: j

' P( z6 R: j. s% Y1 _* y$ m8 d( }+ D. c5 b# e% [
1. HealthMonitor 初始化完成之后会启动内部的线程来定时调用对应 NameNode 的 HAServiceProtocol RPC 接口的方法,对 NameNode 的健康状态进行检测。 2. HealthMonitor 如果检测到 NameNode 的健康状态发生变化,会回调 ZKFailoverController 注册的相应方法进行处理。 3. 如果 ZKFailoverController 判断需要进行主备切换,会首先使用 ActiveStandbyElector 来进行自动的主备选举。 4. ActiveStandbyElector 与 Zookeeper 进行交互完成自动的主备选举。 5. ActiveStandbyElector 在主备选举完成后,会回调 ZKFailoverController 的相应方法来通知当前的 NameNode 成为主 NameNode 或备 NameNode。 6. ZKFailoverController 调用对应 NameNode 的 HAServiceProtocol RPC 接口的方法将 NameNode 转换为 Active 状态或 Standby 状态。5 X* D  r' |" y0 v/ u3 J: ^* U
1.4 YARN高可用
. b' y& A& c% ~. W$ M' G4 i1 k7 x  AYARN ResourceManager 的高可用与 HDFS NameNode 的高可用类似,但是 ResourceManager 不像 NameNode ,没有那么多的元数据信息需要维护,所以它的状态信息可以直接写到 Zookeeper 上,并依赖 Zookeeper 来进行主备选举。3 `9 w" A: o: U$ C+ h7 |6 u) }
  B9 V6 x1 D1 z& B2 x6 j4 J

; e6 |' s: Q0 `二、集群规划
6 p+ \) o) ~1 C- c按照高可用的设计目标:需要保证至少有两个 NameNode (一主一备) 和 两个 ResourceManager (一主一备) ,同时为满足“过半写入则成功”的原则,需要至少要有 3 个 JournalNode 节点。这里使用三台主机进行搭建,集群规划如下:
5 @1 |, A# z9 r1 |4 a
  i. s: G9 F$ x7 R3 g/ D! n
5 C9 y$ o% k, O" U: k, u三、前置条件( G8 a2 }  n4 n9 p0 M! ]
所有服务器都安装有 JDK,安装步骤可以参见:Linux 下 JDK 的安装;2 I+ X$ s9 G+ O* v9 h
搭建好 ZooKeeper 集群,搭建步骤可以参见:Zookeeper 单机环境和集群环境搭建' C2 r5 z) S0 \  v5 B6 O# y: W( E, o! r
所有服务器之间都配置好 SSH 免密登录。  k3 n- `# Z% e' [) C. M
四、集群配置
/ `2 v' O# K6 a& p* ]4.1 下载并解压
' E4 h! _# \) x3 I- `8 y下载 Hadoop。这里我下载的是 CDH 版本 Hadoop,下载地址为:http://archive.cloudera.com/cdh5/cdh/5/, D) F0 C5 k4 Y. b
2 D2 g9 Y# z- V. S6 G0 [4 d4 f5 {
# tar -zvxf hadoop-2.6.0-cdh5.15.2.tar.gz 0 V6 R% g! Y( b5 c
4.2 配置环境变量
6 n& q3 G# l$ ^% [编辑 profile 文件:
& b, q" f1 }- t# T- W% S) ~6 g7 Q; q
# vim /etc/profile! e# [3 F$ t% m" f
增加如下配置:
: H+ K7 U" z* }3 ]0 w7 ?& D& V! {* K! N' o$ v
export HADOOP_HOME=/usr/app/hadoop-2.6.0-cdh5.15.2
! `( C' F! C( s2 f5 |export  PATH=${HADOOP_HOME}/bin:$PATH
2 E" `, w* Y4 H. S+ w9 B# u. c2 i执行 source 命令,使得配置立即生效:
& M# J& F7 V% e0 y) S
: z  [1 \7 o2 Z% ^% |- n! n: e# source /etc/profile+ z! v$ `5 m) P: X, `! p
4.3 修改配置5 f/ ^9 T! u6 X& n
进入 ${HADOOP_HOME}/etc/hadoop 目录下,修改配置文件。各个配置文件内容如下:) G+ P+ O0 T1 v( T
: `. c, u( N4 m5 R& e, r
1. hadoop-env.sh- O4 ~$ I$ W5 T  w: G
# 指定JDK的安装位置
/ v6 {8 O; v- G4 K$ O; g# ?6 B4 Uexport JAVA_HOME=/usr/java/jdk1.8.0_201/9 z7 ?, G6 C2 x- v) J& o% N8 b
2. core-site.xml
- m! l# w0 y) i9 m* Y<configuration>
" `. T  Z' j3 m) D7 o    <property>
3 ^4 V- j! E* C2 B7 w& R1 h        <!-- 指定 namenode 的 hdfs 协议文件系统的通信地址 -->
1 r+ ~: O% x9 O8 `6 G        <name>fs.defaultFS</name>
1 _$ v# R- ]8 B# y        <value>hdfs://hadoop001:8020</value>$ b3 O8 X# e6 Y4 l7 V, Q
    </property>2 i& y8 }( ~# n8 a" S+ k
    <property>
, p  y- S+ k: c# Z        <!-- 指定 hadoop 集群存储临时文件的目录 -->0 T3 f5 m2 N8 n% X* E
        <name>hadoop.tmp.dir</name>4 F) _4 _( }$ A+ }
        <value>/home/hadoop/tmp</value>
+ \' P' e8 C0 Y8 }$ Y    </property>
9 X0 }6 w$ V1 N) e7 e& [4 Z* s* D    <property>* y5 M) Y+ p6 w$ d. S5 e: d" _- x
        <!-- ZooKeeper 集群的地址 -->
/ k0 q( X3 r! @* f8 x4 T" j        <name>ha.zookeeper.quorum</name>' u/ W" r- z; D9 u! _8 j
        <value>hadoop001:2181,hadoop002:2181,hadoop003:2181</value>9 S) a  e" X9 @
    </property>
( s$ ~* O7 x: w) i    <property>
* Q: g8 _7 O! Y! C- {        <!-- ZKFC 连接到 ZooKeeper 超时时长 -->
4 x0 M% S) q5 p+ ^: f        <name>ha.zookeeper.session-timeout.ms</name>; s6 M) B# l3 X  A" z/ I
        <value>10000</value>* e" U. }* C/ b
    </property>) H2 b: y) j  ]5 {
</configuration>2 E! u: e7 |; ?- z
3. hdfs-site.xml  _- H' O" t9 n/ p; s+ G0 a1 z
<configuration>" L0 U  w! ]2 m  U2 b$ I. U6 T. a
    <property>3 i) O. b% \) K3 d5 u! m
        <!-- 指定 HDFS 副本的数量 -->
  W+ y+ x6 _6 L  E$ X        <name>dfs.replication</name>
+ k9 n1 ~; R# K( h) Z9 i        <value>3</value>  Z- a* t1 R  Q4 ~- B1 `. e6 E* E. x
    </property>' O3 I' u5 _) M
    <property>% y3 S7 O' t7 t- l8 J8 T+ v
        <!-- namenode 节点数据(即元数据)的存放位置,可以指定多个目录实现容错,多个目录用逗号分隔 -->
  s, `) h5 }6 ^9 o/ c# h; h0 ?        <name>dfs.namenode.name.dir</name>
6 s/ d# T  @2 f1 B  l2 U        <value>/home/hadoop/namenode/data</value>
# w5 L7 L5 u  E( X) [+ P9 b    </property>
+ T4 R! G5 j3 p1 j    <property>
; c7 H9 b6 ]+ M7 |3 f        <!-- datanode 节点数据(即数据块)的存放位置 -->
7 G$ M0 N8 Z+ a8 I- e5 F        <name>dfs.datanode.data.dir</name>
1 D) f+ K: d: h) R; A! G2 {        <value>/home/hadoop/datanode/data</value>" c/ i& G% \, X+ y0 ?2 d# v- E9 C
    </property>6 a( m6 |7 g0 x, K) C
    <property>
" L/ \* z# T9 U' E        <!-- 集群服务的逻辑名称 -->, E$ c2 N6 B) [+ R: M
        <name>dfs.nameservices</name>3 V8 u4 _# a% @5 Q0 v
        <value>mycluster</value>
$ g1 |* [6 F% M% K% W8 l8 M    </property>+ X  d4 n+ t% a# ?" t
    <property>6 }( X0 o" l: e
        <!-- NameNode ID 列表-->
# z1 ]8 Q( z4 c; a        <name>dfs.ha.namenodes.mycluster</name>
( r- R1 B1 e* X+ A7 I& \        <value>nn1,nn2</value>, d9 q9 N: j3 U& r& m0 e
    </property>
5 C: S$ U: z) D) ~; K    <property>
6 m, Q- M  R) K" C- y4 n        <!-- nn1 的 RPC 通信地址 -->4 I/ f8 b7 B  `  V* H3 v# i6 j1 i
        <name>dfs.namenode.rpc-address.mycluster.nn1</name>
6 Z1 p$ W! d- V  X5 g5 h( m        <value>hadoop001:8020</value>7 S# O3 m) F% \# s/ f3 E$ H7 C0 H
    </property>4 a+ m" T: F. @$ _) V( y+ ?$ `
    <property>  Z7 Z. V* i/ c' z; c$ E; A
        <!-- nn2 的 RPC 通信地址 -->
" N4 |- d6 i: M( q# a$ k* v9 C        <name>dfs.namenode.rpc-address.mycluster.nn2</name>( E4 }3 B$ Z( g; s7 t. I
        <value>hadoop002:8020</value>, v$ h3 z; r! `' B
    </property>( R0 ?9 b4 M: \
    <property>
; @( s- r% V: h9 x! Z        <!-- nn1 的 http 通信地址 -->5 R( N: e3 o3 x7 ~) _( H: o/ L. y# X
        <name>dfs.namenode.http-address.mycluster.nn1</name>
- S1 s! W! ~8 l. q# {% o        <value>hadoop001:50070</value>- ]2 _/ @8 e# f+ R9 {% |
    </property>
" u6 G4 p$ g8 }; e( g    <property>
- |" [% p2 x5 T3 ~5 h) R        <!-- nn2 的 http 通信地址 -->+ I  Q: _* y* P- ~8 |
        <name>dfs.namenode.http-address.mycluster.nn2</name>
6 d& F; @: C$ ?+ z, I* {; A" g0 G        <value>hadoop002:50070</value>4 b9 c7 ~7 y# K' P- P1 ^
    </property>
2 |+ S/ _0 {6 N3 ]" E    <property>& m: i6 p/ m' ]1 w) Z/ N9 O& ~
        <!-- NameNode 元数据在 JournalNode 上的共享存储目录 -->2 ^* V  o/ m8 |* p6 p
        <name>dfs.namenode.shared.edits.dir</name>4 _, S1 C; |% X% m3 Y2 [* _
        <value>qjournal://hadoop001:8485;hadoop002:8485;hadoop003:8485/mycluster</value>
+ q& b8 q3 `' i, b* c    </property>' M$ ~7 o3 }" L; \
    <property>
: u4 o$ U/ ?( ?$ t* g4 V        <!-- Journal Edit Files 的存储目录 -->5 p4 }7 u+ ?+ w) o
        <name>dfs.journalnode.edits.dir</name>3 h0 E1 z4 }* w/ E6 H: H
        <value>/home/hadoop/journalnode/data</value>4 r. U! \! d% ~) @
    </property>* Z9 k2 R" h, _# q; h" H9 v/ I
    <property>$ |% k* S7 _9 `6 L, I% l
        <!-- 配置隔离机制,确保在任何给定时间只有一个 NameNode 处于活动状态 -->% }, D2 q8 U4 n8 v8 t- [
        <name>dfs.ha.fencing.methods</name>1 u* y' Q, |. L/ Z
        <value>sshfence</value>
$ I; g5 O- k# Z. R& \0 }    </property>9 B- W% g! h3 ~
    <property>$ l: Y. a" Z+ S& N- V6 `; W& Z% q
        <!-- 使用 sshfence 机制时需要 ssh 免密登录 -->
/ n+ t2 W! `5 Q. H7 \& a6 A        <name>dfs.ha.fencing.ssh.private-key-files</name>
+ L1 q/ Q; M2 ?* s- g6 V3 F0 R9 f        <value>/root/.ssh/id_rsa</value>
) m8 k5 d; K9 o0 u: L1 d6 ^    </property>
" y/ x: `( k# |2 u* f    <property>
, R: ^; u. M9 U: p; k        <!-- SSH 超时时间 -->
9 J: w" O& z' H' k5 \        <name>dfs.ha.fencing.ssh.connect-timeout</name>
, j, d, |% S( s. m) G3 C8 h4 a: f        <value>30000</value>* `# u; A* M8 |( C' f- {- l
    </property>' h, q0 I# K( Y6 I
    <property>& y' E4 Q/ A- `0 V% R2 p3 w# r- b
        <!-- 访问代理类,用于确定当前处于 Active 状态的 NameNode -->
0 j  ^  K$ Z$ Y; q1 N1 T+ U# e        <name>dfs.client.failover.proxy.provider.mycluster</name>. ]( |2 _7 t; d7 q% X7 t$ I
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
9 S. Q! S6 @- `, B$ V( p    </property>
5 f- M# _; ^  O/ c    <property>
2 j) c9 }, N' L$ d/ c: @( _( D        <!-- 开启故障自动转移 -->
  |" _* l8 l: E2 a0 c; P+ A        <name>dfs.ha.automatic-failover.enabled</name>1 M# ?9 A5 z0 p# D1 t
        <value>true</value>
$ K/ L+ [( |+ U7 L8 q: e0 ^. V5 B7 T, D    </property>
/ c& j5 O9 g: V$ N, d) B) w</configuration>
: M9 m6 c8 J/ U* I% C" f6 U4. yarn-site.xml5 N# g' y7 t# Z9 T
<configuration>
& z& x( z  P# o( }& z: Q0 ^2 H    <property>) w( S$ `/ l; V0 v( A
        <!--配置 NodeManager 上运行的附属服务。需要配置成 mapreduce_shuffle 后才可以在 Yarn 上运行 MapReduce 程序。-->
* |0 d/ i. s+ T& E0 O9 N5 O        <name>yarn.nodemanager.aux-services</name>' V8 H/ _; n) a0 I, p
        <value>mapreduce_shuffle</value>, v; c9 A* ^3 t4 `  f2 T
    </property>  q2 c& b& x1 i& u- O. ^0 j
    <property>5 k9 i' f3 B4 S5 J! t# Q6 ]
        <!-- 是否启用日志聚合 (可选) -->
: `/ R& `6 c0 J' [. t: ~/ J9 C        <name>yarn.log-aggregation-enable</name>
, k) s0 T$ M8 x6 T9 T        <value>true</value>
! S+ J' B: L" ~7 {0 c, |, R, F- `; G; R    </property>
# f( ]/ V: h; I/ ]6 Z4 S# y# g9 q' F6 a    <property>
2 o! Y# E+ A; j; m/ }& g        <!-- 聚合日志的保存时间 (可选) -->' O; n: [- r- k( ~. t  A
        <name>yarn.log-aggregation.retain-seconds</name>
: e1 ^* U& S5 k2 S3 R0 U        <value>86400</value>' D: Y! n# _+ z/ ~9 T* C
    </property>9 N2 d$ n/ i) l7 J( I
    <property>% ~: W8 ]6 {9 q# F! t! Q
        <!-- 启用 RM HA -->6 r" j. f0 w. L+ k, v* G3 X' C
        <name>yarn.resourcemanager.ha.enabled</name>6 c0 |" }* e4 F$ v# \
        <value>true</value>; K& r$ W. p3 F7 {4 J, Z
    </property>
! \( w: B6 s9 K    <property>
) [) g; R& l# I# {, B; \3 B        <!-- RM 集群标识 -->
9 d% H( ~# [. E! v+ t7 n        <name>yarn.resourcemanager.cluster-id</name>
( |9 ~. s  M; I6 K        <value>my-yarn-cluster</value>
- L8 x& z, K! q7 n    </property>/ Z- Q5 `& t1 b$ a  x" S; J: u
    <property>" k! l3 ~: c* Q; I/ K" d) O* G
        <!-- RM 的逻辑 ID 列表 -->  `1 T1 ~9 [: Y0 O0 v0 ^
        <name>yarn.resourcemanager.ha.rm-ids</name>3 S, \  d6 y& d4 W
        <value>rm1,rm2</value>* F1 p) [: j4 y- B  U: f
    </property>
8 p* f& ^4 u; E- W, k! L    <property>9 _# k' V- x: C; M5 A
        <!-- RM1 的服务地址 -->
" P) f# j( V7 Q, i  o        <name>yarn.resourcemanager.hostname.rm1</name>& _% ]/ F' K0 o! k1 X
        <value>hadoop002</value>
( C: e& u  X. }8 m+ E" p! g+ p3 o    </property>* o( I8 @" s& }: n0 @" x9 s
    <property>
  d5 v; m( A1 {1 V        <!-- RM2 的服务地址 -->
& N8 L. M6 I$ @9 s  N        <name>yarn.resourcemanager.hostname.rm2</name>
7 I# X& u" s7 E2 k        <value>hadoop003</value>
" `, f8 z" I" |& Z0 X) H, ?    </property>5 D8 T/ ~7 Z9 h) `
    <property>9 G2 I) F8 h, f, v9 i, y
        <!-- RM1 Web 应用程序的地址 -->
# Q6 ]( N. C3 j: H        <name>yarn.resourcemanager.webapp.address.rm1</name>0 D) V: t/ b3 G
        <value>hadoop002:8088</value>0 c  D. v) X' R1 N9 W  Y: l, N
    </property>* B9 R& Y( U$ u8 F. {1 w8 O) l, R. F
    <property>
! |  ?3 @# O- u+ _        <!-- RM2 Web 应用程序的地址 -->& M6 Y) U1 e9 C& f4 B. C
        <name>yarn.resourcemanager.webapp.address.rm2</name>
+ J7 b" n) T* H        <value>hadoop003:8088</value>& N9 N4 m. r- J# |/ H% ~5 X& T
    </property>
' j! h1 t& v4 a) w+ A6 R    <property>$ ^! i5 m4 G1 Y; }8 \6 u
        <!-- ZooKeeper 集群的地址 -->; a$ W2 `6 n& b- W. h/ `
        <name>yarn.resourcemanager.zk-address</name>8 T  S& u. u5 Z/ \$ @# H
        <value>hadoop001:2181,hadoop002:2181,hadoop003:2181</value>
8 p! V+ q- v" C/ ^    </property>6 V- n5 h. u) V; d
    <property>
: Q- Y8 T8 `; d6 h: E        <!-- 启用自动恢复 -->6 c$ w/ {# Q1 ?- Y$ n4 v
        <name>yarn.resourcemanager.recovery.enabled</name>
3 {& ~; d/ N1 N" S$ Y9 b) M        <value>true</value>
% o- d. T) P3 h7 o+ n0 d    </property>
/ S9 L; T5 q6 J, g2 ]6 g3 U    <property>% b7 H7 a: ]4 G3 Z& R" Z1 q2 [( U
        <!-- 用于进行持久化存储的类 -->/ q3 t; ~4 |! ~* X5 t4 t" g% a& w
        <name>yarn.resourcemanager.store.class</name>
1 f% z! c4 M. t+ r8 R' J        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
+ E0 ]* i& e% B    </property>
9 ^1 H* @" v# U7 x$ V</configuration>
( o: s3 @5 s/ v7 C- M; t5. mapred-site.xml+ N% Y' r" D9 @6 I7 Q" b' Q) b
<configuration>
( U* m0 S8 ?- C9 F6 R    <property>
1 f. J  r9 a- g7 F4 ^/ |        <!--指定 mapreduce 作业运行在 yarn 上-->
4 e9 ~' E1 ^/ F/ k- _        <name>mapreduce.framework.name</name>
* L0 x; C! q" l* |1 B) v        <value>yarn</value>7 M$ N9 m; }  p& t) }/ B6 G3 {
    </property>& V' c5 f6 K7 a, c2 A
</configuration>/ b3 n1 c" e4 {, f# E2 j9 ?
5. slaves
" C0 ~" V/ }4 ]1 Q: f1 G( A2 k配置所有从属节点的主机名或 IP 地址,每行一个。所有从属节点上的 DataNode 服务和 NodeManager 服务都会被启动。. f# @4 p' q9 J( g

5 a0 V+ l% a$ Y1 \# O% Phadoop001, N0 U' z$ O; |3 c8 ]& X
hadoop002
" f* v6 K) B6 F9 T5 _) _) uhadoop003" ?" @9 Q6 j, V1 t/ Q% q- i
4.4 分发程序
! \/ d- ?# H" c4 H- U. b$ `将 Hadoop 安装包分发到其他两台服务器,分发后建议在这两台服务器上也配置一下 Hadoop 的环境变量。
" w7 F$ {+ y+ z' }3 c$ v2 I: G* K; ~4 c3 Q& G' Y
# 将安装包分发到hadoop002
. w! \8 V5 G  l' W) g# X  Wscp -r /usr/app/hadoop-2.6.0-cdh5.15.2/  hadoop002:/usr/app/
% F" A! v/ t3 f& a. U( r# 将安装包分发到hadoop003
) l- e, N% G# ?, \; M3 ~scp -r /usr/app/hadoop-2.6.0-cdh5.15.2/  hadoop003:/usr/app/
) ?/ e9 h6 n+ Q6 {" S五、启动集群: b; J* x6 @( p$ ^
5.1 启动ZooKeeper- u1 \. o- ~. [' N% }$ Q
分别到三台服务器上启动 ZooKeeper 服务:
! F+ k' X3 {, r* o) V, I5 U& d6 y! C- J# K4 b8 _9 g
zkServer.sh start, s+ m" h: ~3 n( }- f% m6 B0 C
5.2 启动Journalnode, U; T5 p4 }9 Z9 Y3 M. G8 n
分别到三台服务器的的 ${HADOOP_HOME}/sbin 目录下,启动 journalnode 进程:6 [1 V. x) r9 x6 D

) |% A1 J8 g: u5 khadoop-daemon.sh start journalnode
$ m1 ?( x; {$ p! S) @% d% E$ I5.3 初始化NameNode
- h5 r# w& F( Y( ]# O; S/ [* J4 C在 hadop001 上执行 NameNode 初始化命令:0 e1 I3 e* c7 s; k3 _8 R! d: M
% L! m+ E+ w; t
hdfs namenode -format' ~, l/ [/ `( c7 o
执行初始化命令后,需要将 NameNode 元数据目录的内容,复制到其他未格式化的 NameNode 上。元数据存储目录就是我们在 hdfs-site.xml 中使用 dfs.namenode.name.dir 属性指定的目录。这里我们需要将其复制到 hadoop002 上:
$ E. A  R4 U6 o9 ?' {$ V# l8 Y0 n( o( _/ }
scp -r /home/hadoop/namenode/data hadoop002:/home/hadoop/namenode/3 K) C" H+ K3 x2 ^% e5 Y% h
5.4 初始化HA状态' x0 C# s8 \0 r2 @8 T
在任意一台 NameNode 上使用以下命令来初始化 ZooKeeper 中的 HA 状态:' X( T7 N# @1 ~5 e  m
. U0 r% }6 J. m
hdfs zkfc -formatZK
; t, L  l: f) \2 h2 C! [5.5 启动HDFS& b) V, g+ q4 i  w; q/ F
进入到 hadoop001 的 ${HADOOP_HOME}/sbin 目录下,启动 HDFS。此时 hadoop001 和 hadoop002 上的 NameNode 服务,和三台服务器上的 DataNode 服务都会被启动:
( F2 v/ P# Y5 W7 G: }7 |, o& c% y6 |
start-dfs.sh! n( Q4 f) L, D" q; {& e
5.6 启动YARN' L2 f, q' o% a* J8 n5 T' {3 t
进入到 hadoop002 的 ${HADOOP_HOME}/sbin 目录下,启动 YARN。此时 hadoop002 上的 ResourceManager 服务,和三台服务器上的 NodeManager 服务都会被启动:
7 R0 Y' J  _4 K) Z6 T6 {* S1 S
3 c/ P0 r2 l' ], {, }5 Istart-yarn.sh
- j5 \. U; v# h' A1 L! R3 A需要注意的是,这个时候 hadoop003 上的 ResourceManager 服务通常是没有启动的,需要手动启动:( O2 \3 _# a. P4 N8 D

1 l2 s8 E, ?+ syarn-daemon.sh start resourcemanager
  i& I! E# [- X9 `六、查看集群
/ H3 Y1 x3 M7 q, V  m" _# _6.1 查看进程* g7 i7 z& ^- }& @: T1 N
成功启动后,每台服务器上的进程应该如下:
% @0 r0 E; `/ |3 e+ [* E
! v( S7 @- A" D! Q  r( r1 @[root@hadoop001 sbin]# jps
% {7 Y7 o6 d! |/ }7 c2 Z6 l% ^5 X4512 DFSZKFailoverController3 {0 M% j2 b2 p; e7 ~
3714 JournalNode4 N  p5 P1 V6 m- g7 y, a# S7 s6 N
4114 NameNode5 x3 d- b; I1 ?" i6 @5 u; C
3668 QuorumPeerMain
; e% y. Q9 x; [+ @6 g5 ?5012 DataNode
0 a  ]" Q2 j  u$ r/ V4639 NodeManager
: J9 s* H* y) e: i& d8 {+ S, b" g
1 @' o4 Y8 c5 ?0 {% w0 H+ o& P
. f4 j* |5 J7 b: W! Y- {[root@hadoop002 sbin]# jps: q' ~: N/ w: \' S+ z! k7 s1 O; S/ a
4499 ResourceManager
: V% W. u9 J* Q, ?4595 NodeManager
4 L8 `0 V4 t+ _4 {* ~' \0 @$ m4 Q3465 QuorumPeerMain* }6 b+ w2 c3 ]: Z/ x# c
3705 NameNode1 a5 I/ g. A( G6 c% K
3915 DFSZKFailoverController1 p' I3 y8 y+ G6 x5 s5 S6 g- G3 N6 \
5211 DataNode& u8 A' a" ^# H& z
3533 JournalNode- Y# [. P. [8 Z+ {% y

& l9 J7 ~* G0 T! g/ Y5 g. U. A( P0 z/ `
[root@hadoop003 sbin]# jps
& y( t1 v! @3 l- t0 I7 X3491 JournalNode' r: M( [; X0 Y. p# i( Q. \
3942 NodeManager
3 q5 a: U2 H; o0 T2 ~. z8 E' i4102 ResourceManager
& p: N3 R6 N( S2 _1 r; J% Q4201 DataNode
6 B. k2 }2 p; W8 ]3435 QuorumPeerMain( U& c" p* ~1 d- i- k: ?
6.2 查看Web UI
4 C' k! F: k% U) g: c; M; FHDFS 和 YARN 的端口号分别为 50070 和 8080,界面应该如下:
: T" B- Q  t" p% _# P. E5 M2 o, Y9 q# g  Y
此时 hadoop001 上的 NameNode 处于可用状态:0 ~/ i% s! F3 Q! x) B9 }& V9 ]. B
, S( W0 L' x0 z0 @
! \5 j/ h+ G) K3 R& I
而 hadoop002 上的 `NameNode` 则处于备用状态:2 z* p& ?+ k! e6 r6 ?' ~1 E

2 H3 Q$ D3 n: H$ ]2 h# `1 b( v9 b$ V2 R* y+ n, a( I) P0 \
hadoop002 上的 ResourceManager 处于可用状态:
" B& G. J5 L* B
- g" ~5 I( t* d! ~. |1 {3 j4 U
  [) K# o( e; e9 @2 C
+ j; F3 t7 w! G
# e9 s9 m- f1 ohadoop003 上的 ResourceManager 则处于备用状态:
1 R) S# v1 h/ l" B7 {6 a  W# u4 H4 G! X; Q/ |; p

3 p2 F& [3 v9 s1 L) }% |# E& W( v# J4 z1 i% E- L* P6 o5 m+ V
9 }$ r& B! G, _" G3 U7 E' u9 K
同时界面上也有 Journal Manager 的相关信息:0 C$ i# `1 {, K7 u8 X
5 f0 M- f, i! ], }5 I! m3 t0 }. j

8 x/ @* M2 |+ O% \8 B" c4 z# m; q7 y  ^
## 七、集群的二次启动
' \+ f5 l7 @7 \+ _$ ^- M上面的集群初次启动涉及到一些必要初始化操作,所以过程略显繁琐。但是集群一旦搭建好后,想要再次启用它是比较方便的,步骤如下(首选需要确保 ZooKeeper 集群已经启动):. B( J; K* c+ N% F7 ^* S

. T7 x" M  U, a# d* L! G在 hadoop001 启动 HDFS,此时会启动所有与 HDFS 高可用相关的服务,包括 NameNode,DataNode 和 JournalNode:
9 V$ k. r9 P& }" n3 C2 T5 P( H7 H, k$ h- _
start-dfs.sh
9 P# U. ]3 {$ C$ }在 hadoop002 启动 YARN:" t7 K1 N& J" Z* r6 d( r

; ^. N4 C  x, j5 f, M- Z7 Q) ^, fstart-yarn.sh2 P" q# e- o6 g& Z# Q- @2 R& Z/ G
这个时候 hadoop003 上的 ResourceManager 服务通常还是没有启动的,需要手动启动:  n3 f( [; v' C$ P& |0 {1 T$ o
! i9 F  L# ]; q4 Z6 ]
yarn-daemon.sh start resourcemanager( P1 {3 Z8 V: j$ S1 q- U* p

; {) W4 J1 o/ g% F
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

站长推荐上一条 /4 下一条

北京云银创陇科技有限公司以云计算运维,代码开发

QQ|返回首页|Archiver|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )点击这里给我发消息

GMT+8, 2026-4-9 00:04 , Processed in 0.059460 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

快速回复 返回顶部 返回列表