找回密码
 注册
查看: 537|回复: 1

搭建Hadoop的HA高可用架构

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2022-11-15 10:00:32 | 显示全部楼层 |阅读模式
购买主题 本主题需向作者支付 2 金钱 才能浏览

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2022-11-15 10:00:33 | 显示全部楼层
一、高可用简介
  a9 g/ x0 f  t8 v/ r二、集群规划
& J3 D3 M4 Y/ L" A三、前置条件
$ n% w- ]" H5 q$ ~四、集群配置# M8 l$ d9 c- S1 H# @$ v
五、启动集群
# Z9 s$ W6 Y" \& u' c六、查看集群& l" k4 @  [0 ?2 ^7 [' x6 d
七、集群的二次启动5 r$ `" ]5 |, G% q" e! N
一、高可用简介
; Z4 i# e5 l7 o+ x  qHadoop 高可用 (High Availability) 分为 HDFS 高可用和 YARN 高可用,两者的实现基本类似,但 HDFS NameNode 对数据存储及其一致性的要求比 YARN ResourceManger 高得多,所以它的实现也更加复杂,故下面先进行讲解:
2 e7 R4 R! f+ |5 K$ D$ ~/ T  w; z$ j, b# I: v4 o; D" Q  z
1.1 高可用整体架构
# S; r" H+ ~( i# ?! l* V) ?- UHDFS 高可用架构如下:
8 \/ D( L% W, t5 @5 e: Y$ U+ m; R/ t( H, A6 U

  w7 c9 ]% a2 c$ x+ w- z图片引用自:https://www.edureka.co/blog/how- ... -high-availability/: U. X, t4 Y- O/ m6 ]. K

3 s5 o8 c9 H- y  d! c8 Q' LHDFS 高可用架构主要由以下组件所构成:
2 [: y. z9 a% X
) T. G+ v  d: o# f0 @' f2 O* b0 K+ VActive NameNode 和 Standby NameNode:两台 NameNode 形成互备,一台处于 Active 状态,为主 NameNode,另外一台处于 Standby 状态,为备 NameNode,只有主 NameNode 才能对外提供读写服务。' M; R- K, s5 W9 O! M+ g( ?* v
  L* n$ ?; W" |3 q- M
主备切换控制器 ZKFailoverController:ZKFailoverController 作为独立的进程运行,对 NameNode 的主备切换进行总体控制。ZKFailoverController 能及时检测到 NameNode 的健康状况,在主 NameNode 故障时借助 Zookeeper 实现自动的主备选举和切换,当然 NameNode 目前也支持不依赖于 Zookeeper 的手动主备切换。
+ f' g, ~/ t4 e0 t( H6 H
  [- b: K8 U1 C# ?( ~' FZookeeper 集群:为主备切换控制器提供主备选举支持。8 l. E, f" Q% L5 @
% P. ]* z1 Z& ]- C% b% T7 s& E, V9 c
共享存储系统:共享存储系统是实现 NameNode 的高可用最为关键的部分,共享存储系统保存了 NameNode 在运行过程中所产生的 HDFS 的元数据。主 NameNode 和 NameNode 通过共享存储系统实现元数据同步。在进行主备切换的时候,新的主 NameNode 在确认元数据完全同步之后才能继续对外提供服务。+ o: A/ b  l* y; L) Z: K: N

1 F" V) |( k5 |DataNode 节点:除了通过共享存储系统共享 HDFS 的元数据信息之外,主 NameNode 和备 NameNode 还需要共享 HDFS 的数据块和 DataNode 之间的映射关系。DataNode 会同时向主 NameNode 和备 NameNode 上报数据块的位置信息。# L( ]6 U  o8 `: m# v3 R
1 _( \: O7 b4 |" q9 W! u$ q+ r+ ]
1.2 基于 QJM 的共享存储系统的数据同步机制分析
# g) [" \; v6 O9 P; _+ Q1 A% S' P目前 Hadoop 支持使用 Quorum Journal Manager (QJM) 或 Network File System (NFS) 作为共享的存储系统,这里以 QJM 集群为例进行说明:Active NameNode 首先把 EditLog 提交到 JournalNode 集群,然后 Standby NameNode 再从 JournalNode 集群定时同步 EditLog,当 Active NameNode 宕机后, Standby NameNode 在确认元数据完全同步之后就可以对外提供服务。
2 Q+ g! R! x# x
7 X# ?: B' m% k5 o8 W' G' F) p1 o2 g需要说明的是向 JournalNode 集群写入 EditLog 是遵循 “过半写入则成功” 的策略,所以你至少要有 3 个 JournalNode 节点,当然你也可以继续增加节点数量,但是应该保证节点总数是奇数。同时如果有 2N+1 台 JournalNode,那么根据过半写的原则,最多可以容忍有 N 台 JournalNode 节点挂掉。
4 L- s. d% r. G4 Z& N) S# t. Q0 w9 m0 O! h

6 t$ S, C  f7 {1.3 NameNode 主备切换
  p0 B1 k2 I2 ONameNode 实现主备切换的流程下图所示:4 R( N! H4 E3 a: N/ U& P/ }/ I
7 r# _% O3 J8 d

% ]) o. p9 }2 {6 H1. 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 状态。
3 y: e$ h+ {5 V8 `/ P) e2 m1 H1.4 YARN高可用
1 Z( S+ l6 {! PYARN ResourceManager 的高可用与 HDFS NameNode 的高可用类似,但是 ResourceManager 不像 NameNode ,没有那么多的元数据信息需要维护,所以它的状态信息可以直接写到 Zookeeper 上,并依赖 Zookeeper 来进行主备选举。
. C- L! h3 B; ]9 m+ m: [. V5 b* w- T

- `. s' M% b. s0 [* ]  J二、集群规划
# m* d3 G. D7 i' F6 n按照高可用的设计目标:需要保证至少有两个 NameNode (一主一备) 和 两个 ResourceManager (一主一备) ,同时为满足“过半写入则成功”的原则,需要至少要有 3 个 JournalNode 节点。这里使用三台主机进行搭建,集群规划如下:
3 g! T: G, P7 W8 x% B5 v5 G, Q
: D8 D& v3 ~5 f8 w" K3 l3 ?* ^; T1 m$ i! L2 b6 p
三、前置条件7 [' t* I; j* W1 A/ M
所有服务器都安装有 JDK,安装步骤可以参见:Linux 下 JDK 的安装;
3 t4 @& L: @, N7 t3 N. H搭建好 ZooKeeper 集群,搭建步骤可以参见:Zookeeper 单机环境和集群环境搭建" M* D- p8 F: ^5 o
所有服务器之间都配置好 SSH 免密登录。6 z! @8 p( A7 b6 n- n
四、集群配置1 J% y6 H" X( X
4.1 下载并解压+ D+ G* H9 N+ N2 f* c! H+ \
下载 Hadoop。这里我下载的是 CDH 版本 Hadoop,下载地址为:http://archive.cloudera.com/cdh5/cdh/5/* V7 u" @) w# y9 h' h" I

; J$ v0 \  _9 x6 l" t# tar -zvxf hadoop-2.6.0-cdh5.15.2.tar.gz 1 B4 u4 a7 s8 L/ u. k$ s1 {2 Z
4.2 配置环境变量
1 Q: {1 `* r, H9 I. k6 L编辑 profile 文件:- Q3 `* M& s; K& Q
+ F: _: F5 L2 n$ j6 ^7 v' Z
# vim /etc/profile
1 C) \3 r0 S8 I3 L% Y增加如下配置:0 N6 k) `! W7 a6 r

! A6 A' ~- v+ J7 P* Z( Z! A8 J4 eexport HADOOP_HOME=/usr/app/hadoop-2.6.0-cdh5.15.2
5 a$ I6 l5 V5 L; t7 ?export  PATH=${HADOOP_HOME}/bin:$PATH# @9 |' N, v& |* b0 G
执行 source 命令,使得配置立即生效:8 G  y" H5 ~; P

' w! z9 a. ^5 x9 N( R# source /etc/profile6 ]$ A  e$ K* B& B6 s1 y$ g& P; C# b
4.3 修改配置) w3 X' E# Y4 d+ f/ I& [
进入 ${HADOOP_HOME}/etc/hadoop 目录下,修改配置文件。各个配置文件内容如下:
  \' K1 F. |' K' v- ?/ d) J' q3 _: x. b& e- e# d3 K6 i
1. hadoop-env.sh% Q9 a2 V& g8 z
# 指定JDK的安装位置
+ f# P1 ^7 o+ ]2 s. F6 Rexport JAVA_HOME=/usr/java/jdk1.8.0_201/
  _  N7 u9 E: G4 m2. core-site.xml
/ d* }. w, t, v( h/ c3 N; ]; F* |<configuration>9 f0 r& E$ Z0 Q* [0 z1 X5 [
    <property>
+ \* S4 a7 Z% M4 r        <!-- 指定 namenode 的 hdfs 协议文件系统的通信地址 -->
) g6 A' {5 H, F        <name>fs.defaultFS</name>
" H$ W2 \# k- s  _) t, ~. ~        <value>hdfs://hadoop001:8020</value>
( R% y8 `; Q% A: g& M7 J    </property>! n# C$ m) Q. b' `& z! b& x
    <property>
' D' B( L, U; I6 v        <!-- 指定 hadoop 集群存储临时文件的目录 -->
# ?+ t* Q, Q4 _, i* S6 J        <name>hadoop.tmp.dir</name>3 l8 p' ~% X/ V- p! {
        <value>/home/hadoop/tmp</value>' y5 P. W6 C: A( e$ d; S
    </property>
( w, X4 a/ H+ w' B1 |# F    <property>/ ^# ?. V4 k4 s1 ?- f  \
        <!-- ZooKeeper 集群的地址 -->
8 F, P2 b1 A% Y( @  u. w        <name>ha.zookeeper.quorum</name>
/ D3 @' F. J* I9 G% Z! D# z        <value>hadoop001:2181,hadoop002:2181,hadoop003:2181</value>
4 m& A$ e, q( r; H  [) l# d    </property>
; _5 w; k$ V+ U( c" G7 d8 w    <property>& Y6 W. d( F% Q8 w) _9 i( D
        <!-- ZKFC 连接到 ZooKeeper 超时时长 -->1 l! P* p% m  x5 T5 Z1 ]
        <name>ha.zookeeper.session-timeout.ms</name>' P  F' K9 m1 j1 ^
        <value>10000</value>
/ u. c# k& t9 P    </property>% @  v  f) a6 h. z" ?
</configuration>
3 Y8 V) J' Y. U/ ^. ?3. hdfs-site.xml
, B2 [- m& O6 E* T<configuration>
# t, {. t' W% X) |4 z" Z1 A. l/ {    <property>
# ^+ J4 U( U: y+ v. z        <!-- 指定 HDFS 副本的数量 -->+ f9 B+ d: e" M  ~
        <name>dfs.replication</name>" k8 |" _! t; y- S1 x
        <value>3</value>- d% ^1 u* K3 |" o
    </property>3 _- ^8 a# T( @& l0 g8 M
    <property>7 |2 j/ S! k, g# Y
        <!-- namenode 节点数据(即元数据)的存放位置,可以指定多个目录实现容错,多个目录用逗号分隔 -->
' n' j$ @! t  T! Z8 K  U* k        <name>dfs.namenode.name.dir</name>
" _' F1 ^$ q8 g" F$ |        <value>/home/hadoop/namenode/data</value>
8 S' s8 {9 G, H% G; ]/ V2 i) C/ u/ z    </property>
) g: B( i0 z3 v, ~    <property>
' h+ ]3 C$ u/ |5 H% M; `6 w1 \        <!-- datanode 节点数据(即数据块)的存放位置 -->6 z- t0 Q# J7 [4 v+ J5 u$ ~* X
        <name>dfs.datanode.data.dir</name>7 j( n3 e, D  [
        <value>/home/hadoop/datanode/data</value>3 l1 ]( y7 `8 |# p. K; ?5 T6 A
    </property>2 e( S" p5 q; j5 n
    <property>
$ T4 O1 O, _) P3 }, \( \        <!-- 集群服务的逻辑名称 -->8 l3 \) Z& O; j
        <name>dfs.nameservices</name>
) {) |3 i7 b8 C; b1 N4 P        <value>mycluster</value>, }) F( n: b5 F1 g4 E
    </property>
+ L3 N9 i7 `# X$ ]2 [    <property>/ w) W" |# l$ q. i3 ~+ \* e2 G8 |
        <!-- NameNode ID 列表-->  n3 W: M& d4 q2 V: o: V1 C
        <name>dfs.ha.namenodes.mycluster</name>/ Y% V: [! s0 ^! r: x+ V
        <value>nn1,nn2</value>9 H+ h9 H; G0 V/ ^2 G# p
    </property>
, H2 S& V6 C# A7 H    <property>
6 h- p3 }3 l' L9 h4 v        <!-- nn1 的 RPC 通信地址 -->5 p  ~, s4 u, N: a  Z: P! Y1 {
        <name>dfs.namenode.rpc-address.mycluster.nn1</name>5 j. j5 R( Y% G% A- s1 `9 _5 u4 E
        <value>hadoop001:8020</value>
1 H1 C' U: c6 y9 m, t    </property>) J( i# d3 p( e9 `! Y+ s
    <property>
" U# D* ?0 F3 I, H& `        <!-- nn2 的 RPC 通信地址 -->
1 \/ n$ p8 ?8 t9 O; t5 S        <name>dfs.namenode.rpc-address.mycluster.nn2</name>- i8 W, d5 j- {. _6 N
        <value>hadoop002:8020</value>6 G  `4 P( a5 ]0 B1 j5 [
    </property>
7 A# e& s& M  ~3 @    <property>
/ d5 E' v9 s5 S( F        <!-- nn1 的 http 通信地址 -->
) l$ l$ X' I" x) ^) O        <name>dfs.namenode.http-address.mycluster.nn1</name>; K) K. h' z  z0 a8 }1 n" {
        <value>hadoop001:50070</value>4 j( v3 r9 y/ I4 P0 |
    </property>: D0 s4 A+ Z& h6 a: u2 p
    <property>. ]" F/ H' ?) h6 V$ o7 [6 k0 h; m. p
        <!-- nn2 的 http 通信地址 -->
/ o, ~, c4 S/ u* X# e2 b% m        <name>dfs.namenode.http-address.mycluster.nn2</name>
1 z. m: g; B3 S6 r        <value>hadoop002:50070</value>2 c, d: J" [2 n' n* L8 }. J# C
    </property>
9 I2 G6 j/ _1 o    <property>% L6 i( N& \- m( y1 I0 {
        <!-- NameNode 元数据在 JournalNode 上的共享存储目录 -->& H+ H/ `8 ~0 z7 `0 G8 X( f
        <name>dfs.namenode.shared.edits.dir</name>
1 I+ R2 U" S. A+ I6 g        <value>qjournal://hadoop001:8485;hadoop002:8485;hadoop003:8485/mycluster</value>
1 W) ~0 a) s2 w3 S! Y4 R7 O, a5 L    </property>$ C3 M1 O2 E% B7 r+ D
    <property>+ Y3 B" E% U( _
        <!-- Journal Edit Files 的存储目录 -->
% E; g1 u, s. c+ x; g, _        <name>dfs.journalnode.edits.dir</name>
" {1 Z) U& e$ Z8 s        <value>/home/hadoop/journalnode/data</value>
6 r# f9 ~  \& z" a- _: n    </property>/ R- ~. G6 D3 C, h2 M. \' S
    <property>
3 G6 ~0 A/ ?$ D        <!-- 配置隔离机制,确保在任何给定时间只有一个 NameNode 处于活动状态 -->8 ~0 O4 t; F2 v$ y# |6 H7 O  D
        <name>dfs.ha.fencing.methods</name>
& J! W) \. ^: D, I        <value>sshfence</value>
& }0 A& ]$ D1 @, A# C$ N    </property>, y) o. L! T8 p4 y1 |% E3 h
    <property>
4 I5 F. J& O# z        <!-- 使用 sshfence 机制时需要 ssh 免密登录 -->
3 x" s7 a. k% g9 V        <name>dfs.ha.fencing.ssh.private-key-files</name>% v8 f/ e( ^( Z/ R. o
        <value>/root/.ssh/id_rsa</value>, B$ C2 r+ U/ E: B
    </property>
7 o- ^1 R2 T: ~$ m. {% ]# n    <property>
; d, E0 N: G# L/ t9 _. k        <!-- SSH 超时时间 -->  S; T3 x# U( b9 E6 L6 H
        <name>dfs.ha.fencing.ssh.connect-timeout</name>1 m- y0 I. W( I3 @
        <value>30000</value>7 Y0 `5 P+ B9 I# [" E$ r7 R/ l
    </property>5 A4 m5 u% o( h2 @3 O
    <property>
# ?( a0 P4 J/ B. `! r        <!-- 访问代理类,用于确定当前处于 Active 状态的 NameNode -->
9 a7 h9 i4 j4 p        <name>dfs.client.failover.proxy.provider.mycluster</name>: h; W5 l8 C" ^- t9 D
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>$ j8 o2 [! D4 b' e8 P  U; C7 T. Y
    </property>
2 S7 {% c7 V; X* w, R% q    <property>% q' k1 `; b" k. z6 o( T
        <!-- 开启故障自动转移 -->
6 _4 Y( }3 [4 U  U3 _7 p        <name>dfs.ha.automatic-failover.enabled</name># {) v" }1 t7 s6 O. }# m/ g
        <value>true</value>
( M1 P9 d. G6 h    </property>
- x6 @5 p/ p: e: B6 P</configuration>; [6 ^  u. f3 N  r& v) M& G
4. yarn-site.xml! {9 u6 N, Z  E: X8 v
<configuration>  Y$ X8 d( k( a& @( Q
    <property>
% l4 f$ O+ d' H        <!--配置 NodeManager 上运行的附属服务。需要配置成 mapreduce_shuffle 后才可以在 Yarn 上运行 MapReduce 程序。-->
2 Q1 `6 O1 [- ?* B! {5 j9 H        <name>yarn.nodemanager.aux-services</name>' z. v! {0 V4 X8 d
        <value>mapreduce_shuffle</value>
& @( b* M( F: N6 ?; C0 z7 q    </property>
6 C( F) c; O3 O0 g, c! e% r0 z3 w1 i    <property>
4 L$ A( u! R6 k8 l' b0 c        <!-- 是否启用日志聚合 (可选) -->
3 M  q" \' ?$ E0 C8 Q        <name>yarn.log-aggregation-enable</name>
+ j- ?- g! L' d3 }! y2 M        <value>true</value>
+ _' o+ w1 `% u3 q3 j+ ~% i    </property>
2 G0 I9 G$ s, v5 J9 _: }2 y( v6 a; L# K; x    <property>) L% L- U4 n" z' M$ g2 J
        <!-- 聚合日志的保存时间 (可选) -->  P' W3 m5 j9 b! h1 S2 W
        <name>yarn.log-aggregation.retain-seconds</name>) ]- T) j- F6 R
        <value>86400</value>3 R7 O9 Y1 U4 s0 L
    </property>; x/ L! d8 g! N1 u) O
    <property>
/ z% c! F- }! }0 D        <!-- 启用 RM HA -->
( y4 ~- m! Y* h' r# a1 m6 ~        <name>yarn.resourcemanager.ha.enabled</name>
0 T4 C: v  D3 S9 _& s) i+ R! I        <value>true</value>
7 i1 V) P0 q9 ?6 O8 g1 b    </property>- h8 G, ?8 U  t4 @7 A$ k
    <property>* @2 n- M' U+ ^7 ^
        <!-- RM 集群标识 -->
1 x& ?( F9 A; b! ]: B& _        <name>yarn.resourcemanager.cluster-id</name>/ a8 ]  ~/ h% u  R
        <value>my-yarn-cluster</value>
- ^; x+ F$ u% ?; d3 ]: |    </property>7 y, S6 S3 ^. T: i+ b
    <property>
8 R& C" O2 p& v& c* Q5 \3 x$ ^        <!-- RM 的逻辑 ID 列表 -->
; {/ X! a( m5 o$ f5 C% G        <name>yarn.resourcemanager.ha.rm-ids</name>
8 G; [4 h6 m, M6 g# V        <value>rm1,rm2</value>
/ F8 A7 N& }2 l% B$ ]    </property>% H7 Z0 D0 l! z  a, D7 `
    <property>
3 ]3 P  c. F! ?" I% H        <!-- RM1 的服务地址 -->) V. r' I8 E( X% s& ]" _/ q% h9 V
        <name>yarn.resourcemanager.hostname.rm1</name>
( t" I( g" j) m- ]        <value>hadoop002</value>. |" q! S4 i; \; ?1 V. D2 G8 ?
    </property>0 |5 w! \! ^( S6 g" u% V
    <property>
% f: H# t0 ~& o4 j: @        <!-- RM2 的服务地址 -->  m9 ^- Z( y  c( w0 {
        <name>yarn.resourcemanager.hostname.rm2</name>
! ?: s' u6 Y9 n. v# z0 x* c: r        <value>hadoop003</value>
1 Q+ R9 U7 l) y, f: a& U; t    </property>8 k& `6 v* x7 n- p3 {  T- z
    <property>
8 Z: k6 i, Z/ d2 g# }8 c: g# b        <!-- RM1 Web 应用程序的地址 -->
5 A) c9 v. D$ d3 J  P/ y: J( R$ @        <name>yarn.resourcemanager.webapp.address.rm1</name>
4 g9 E4 O/ S0 t2 j! j        <value>hadoop002:8088</value>1 `8 S7 p, Y. S, P1 g
    </property>& O4 d& M( z' D6 G
    <property>
7 N% `' e3 o7 W, A# O        <!-- RM2 Web 应用程序的地址 -->
7 g! C* a' Z1 r4 a        <name>yarn.resourcemanager.webapp.address.rm2</name>* W  a+ }! {3 O- w
        <value>hadoop003:8088</value>
  T9 S% N2 z; y, X# p" f    </property>8 N" W) B  x, n) z( K6 o
    <property>  \) J2 e8 f8 y0 Z$ E
        <!-- ZooKeeper 集群的地址 -->: P: u6 s$ i8 D0 ?. U  F& [& c
        <name>yarn.resourcemanager.zk-address</name>" W( r! J2 e# g) p: o
        <value>hadoop001:2181,hadoop002:2181,hadoop003:2181</value>
* J& o; m9 p& |: L/ }* s    </property>2 @* O  v0 W. R1 f. L
    <property>
! O9 F( A* {! s0 J$ B( J3 ?! N# H        <!-- 启用自动恢复 -->: V- y3 t) G8 J' v- T
        <name>yarn.resourcemanager.recovery.enabled</name>9 e) V* V6 d7 t3 ^9 `5 I
        <value>true</value>; E5 z+ C. b2 A0 c* k
    </property>
$ M2 W7 \) ]0 Z- W5 l, T- W    <property>
( a! D; T( k. ~; X3 E" \  j        <!-- 用于进行持久化存储的类 -->1 z! z* E* A  d1 o7 t; I
        <name>yarn.resourcemanager.store.class</name>8 L$ X  b$ z  z7 c
        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>. z( _' b& [) z* m4 p/ ^
    </property>. `. b2 u3 z/ |0 {
</configuration>* W. Q/ f4 }- y3 Z
5. mapred-site.xml
0 I& v5 a$ W+ \( H<configuration>1 s+ `; g% A+ G
    <property>
) z. S4 U5 B8 C% ^6 A0 Q& l2 o        <!--指定 mapreduce 作业运行在 yarn 上-->$ N8 ?* S) J0 \2 S6 o5 I7 X& k: y# p
        <name>mapreduce.framework.name</name>
% R' [( l- b4 A9 J        <value>yarn</value>1 T7 J0 h0 |( b
    </property>
: y3 C. l& I# U1 ?+ k- B  K</configuration>0 W% a) q# \7 k6 I1 N& Y* Q  C
5. slaves
$ `- B. S1 a3 `: ]配置所有从属节点的主机名或 IP 地址,每行一个。所有从属节点上的 DataNode 服务和 NodeManager 服务都会被启动。2 n. r0 l) i- N+ @/ {

! ~; b% F. i& F+ }% k0 G/ ^hadoop001+ y3 n9 D, a8 p2 B# V, |+ _9 w9 r- R
hadoop002
8 \3 h4 X  U. x) ?: F" a, ]hadoop003. r& x7 c  T  Z
4.4 分发程序
2 F+ t1 t# M/ b% T. Z将 Hadoop 安装包分发到其他两台服务器,分发后建议在这两台服务器上也配置一下 Hadoop 的环境变量。$ x* q3 J; P+ F5 K1 v# R) j
6 B" s* i8 N% D6 z
# 将安装包分发到hadoop0023 g) s$ q, V/ ~2 j$ {& F, _: B* }2 ~
scp -r /usr/app/hadoop-2.6.0-cdh5.15.2/  hadoop002:/usr/app/4 b- }5 U5 a3 B  [
# 将安装包分发到hadoop003; N, p8 P  F: q$ s: k* B
scp -r /usr/app/hadoop-2.6.0-cdh5.15.2/  hadoop003:/usr/app/
4 o( Y; Y& R$ E/ v% d( p: U五、启动集群! I9 e  Q6 s0 C' L3 Z, f& f
5.1 启动ZooKeeper8 A* d  e4 L3 `% G. ^7 q3 U6 P4 u
分别到三台服务器上启动 ZooKeeper 服务:  o, x1 [8 q( x
3 b; X/ D5 l* X! k
zkServer.sh start
; K( h0 ?+ U; P" u1 f, e1 Q7 ?5.2 启动Journalnode
8 r% H7 A7 z7 f2 [( U/ n分别到三台服务器的的 ${HADOOP_HOME}/sbin 目录下,启动 journalnode 进程:# y4 W8 Y4 m7 B

8 n, p& K1 l% E+ q# M# h' Ghadoop-daemon.sh start journalnode
+ v0 x+ e1 X2 M9 H" V) s8 h- M5.3 初始化NameNode
: a+ h( d$ I: N, T在 hadop001 上执行 NameNode 初始化命令:
5 y& m: I8 a! z
- P: w5 ^0 P  M0 R( f6 lhdfs namenode -format
# l( ~. N2 ]0 N' Q. A; ^8 v执行初始化命令后,需要将 NameNode 元数据目录的内容,复制到其他未格式化的 NameNode 上。元数据存储目录就是我们在 hdfs-site.xml 中使用 dfs.namenode.name.dir 属性指定的目录。这里我们需要将其复制到 hadoop002 上:6 d4 q1 }  K( l; b/ I9 l# W, |2 l

1 L0 u) ]4 s1 g( Q scp -r /home/hadoop/namenode/data hadoop002:/home/hadoop/namenode/
5 ]/ B* C* q! n" Y3 ?3 {* Y5.4 初始化HA状态
1 o# t0 c) z/ k% y# H在任意一台 NameNode 上使用以下命令来初始化 ZooKeeper 中的 HA 状态:
7 }  R* I% r3 F, N, k. U. r2 L) D* D% ]* o
hdfs zkfc -formatZK. |5 J% w# _  w9 y
5.5 启动HDFS% s8 S( @4 Z; n1 x; w
进入到 hadoop001 的 ${HADOOP_HOME}/sbin 目录下,启动 HDFS。此时 hadoop001 和 hadoop002 上的 NameNode 服务,和三台服务器上的 DataNode 服务都会被启动:
( Q- `5 k7 ]# z- b3 V7 [" s6 p% Z( b4 Q* x2 I# @
start-dfs.sh# B3 O$ v/ ^" k, n. ?* ~; R
5.6 启动YARN! B8 u/ C9 _7 Z+ {. f. l) |
进入到 hadoop002 的 ${HADOOP_HOME}/sbin 目录下,启动 YARN。此时 hadoop002 上的 ResourceManager 服务,和三台服务器上的 NodeManager 服务都会被启动:
0 \/ s- B8 m) ^; Q5 B
- M  F; _; `$ B1 Nstart-yarn.sh
6 {( \4 ^/ o8 G4 j) {( u需要注意的是,这个时候 hadoop003 上的 ResourceManager 服务通常是没有启动的,需要手动启动:8 r- U2 n+ h) z
& A: f5 n" Q4 i" ~9 @4 u
yarn-daemon.sh start resourcemanager
" j* N1 W7 e' h1 e( \& G4 o六、查看集群' V, L& ?" q3 K
6.1 查看进程
8 r) [1 Z4 ]$ b( ?/ H' q- s. K' T- u成功启动后,每台服务器上的进程应该如下:
/ h" z) `3 i2 u8 |2 {$ y- D/ [
5 [6 w4 @( X, p[root@hadoop001 sbin]# jps, F" ^4 _# w' k; Y- Y3 X7 M) b/ |
4512 DFSZKFailoverController
+ a6 |1 ^- R$ W" K. X" o3714 JournalNode# Y5 ^; X6 I/ [$ w' m& G
4114 NameNode8 T5 R6 f7 E/ T: k/ o/ @; v
3668 QuorumPeerMain/ S! N: B/ R5 H  u0 Z! }- Z1 E
5012 DataNode, \- f5 e" i0 z( q% {" a4 u' G$ y2 R
4639 NodeManager
* [( p" d# V4 L8 S! h0 q
6 q5 J7 E) V) c. s% O) s: x# Q/ t  B. j
[root@hadoop002 sbin]# jps' N: Y, K3 V* n# V
4499 ResourceManager
& h5 l- ]/ B, J, s, @! y- v4595 NodeManager
: Q$ {1 h& W0 Z6 q' K3 m3465 QuorumPeerMain& ?7 _$ N, Q: B
3705 NameNode
7 H4 F; U% B0 g- L" C9 |3915 DFSZKFailoverController
3 l9 Z; @( A1 e% b) x5211 DataNode
" q# f7 h9 C) f2 m; ]3533 JournalNode" k( l" k3 S# K) w- ]0 m6 f5 ?1 o

: a) M: K& U( M; o1 \
! t# f+ f( J: P+ _[root@hadoop003 sbin]# jps
0 Z% |$ h: S  s& G" s& x3491 JournalNode* A; }& \' m2 W+ K4 r- x
3942 NodeManager1 W5 B7 i" d" I. t$ S, H
4102 ResourceManager' B. M" O  p/ Y7 H# N3 \" o
4201 DataNode% I; J* B4 h& F3 o+ n5 r3 S
3435 QuorumPeerMain
& s  d: s4 j5 R& C( I' {6.2 查看Web UI
7 B' K1 w- S3 ?! p- q: BHDFS 和 YARN 的端口号分别为 50070 和 8080,界面应该如下:' I" I: }3 k* o  M' i2 Z3 j
5 q7 i0 C# T* Z7 A2 t
此时 hadoop001 上的 NameNode 处于可用状态:: Q. @* v# `0 H
. X( a2 X0 h+ g( X* s

# W$ ]) F0 B# v4 L4 T+ B8 V7 U& H而 hadoop002 上的 `NameNode` 则处于备用状态:$ Q& G$ C4 a9 T3 O* [; w8 I' c
; D* v* A; M0 t7 V0 R# C  H
( h( B& ]# }- B. l
hadoop002 上的 ResourceManager 处于可用状态:8 {- {% M/ l/ X" @
. X1 b3 c# O2 @) o$ V

7 I! Y& p4 C- D3 b& D6 b: u9 }$ d5 v8 x4 x4 }7 R
' g8 ?: V: M2 Z7 x+ x6 n7 z4 H: Z
hadoop003 上的 ResourceManager 则处于备用状态:- f/ u- f9 O0 q: F/ E6 w' x

% d: h9 X  k# C1 w7 ?6 M
4 d7 s9 b( h! W* X" I. l
9 X" _7 g5 q4 g( [0 w+ J# M: h- o5 _: @
同时界面上也有 Journal Manager 的相关信息:& d! M5 O5 Z4 ]* B

+ ~' r$ t. ^$ y, a
/ U! a8 i/ K5 N  X+ N4 K7 \3 F
! P0 e0 `4 L6 ?## 七、集群的二次启动5 k+ D7 f) z1 u- S( u/ h
上面的集群初次启动涉及到一些必要初始化操作,所以过程略显繁琐。但是集群一旦搭建好后,想要再次启用它是比较方便的,步骤如下(首选需要确保 ZooKeeper 集群已经启动):
& t8 B% b) M: c6 k; I5 @+ G+ ]5 h! g7 o0 |+ l$ L
在 hadoop001 启动 HDFS,此时会启动所有与 HDFS 高可用相关的服务,包括 NameNode,DataNode 和 JournalNode:+ q! d+ k2 J# g7 z+ h
$ f0 p- W3 N9 j' O% p
start-dfs.sh  A/ M) X! o5 F$ U
在 hadoop002 启动 YARN:
( J- C; a5 A2 R* t- w0 ?$ x& H& g  c6 G: `: x
start-yarn.sh
# n2 E6 |, F! j4 U这个时候 hadoop003 上的 ResourceManager 服务通常还是没有启动的,需要手动启动:' `, |) b. v; R# Y  ?0 x

9 _$ U, z- y2 Z" Z3 y. D' R6 o; jyarn-daemon.sh start resourcemanager
2 x: ~5 v1 A. {# q+ K3 j7 ?$ ^/ S& z8 E% N
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-12 04:07 , Processed in 0.018008 second(s), 25 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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