找回密码
 注册
查看: 536|回复: 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 | 显示全部楼层
一、高可用简介3 s" M9 D' M4 ^. t" v; V3 F/ p
二、集群规划( F# E/ t' C3 ^$ h
三、前置条件' @. r4 g( b( Y3 s9 c5 [5 t, a% L
四、集群配置/ Y/ o* p5 h9 c& Y7 K, K  F4 ?4 o
五、启动集群8 G7 S) a& J, [% J1 C( p6 N
六、查看集群
& @" z' a2 A9 y4 u) j七、集群的二次启动
! {! o. l6 d1 Q+ ^% S- V$ n一、高可用简介/ y  a4 E3 `0 o* f
Hadoop 高可用 (High Availability) 分为 HDFS 高可用和 YARN 高可用,两者的实现基本类似,但 HDFS NameNode 对数据存储及其一致性的要求比 YARN ResourceManger 高得多,所以它的实现也更加复杂,故下面先进行讲解:; i! |6 U( L  A9 z: v! I9 v
5 d& h, f( @2 v" i+ L
1.1 高可用整体架构& k( L/ V6 d5 ]( b! y5 ~
HDFS 高可用架构如下:
9 |% Q1 T2 R6 d, Q& i7 D+ h9 \# g  Y% @5 k* w% Q

% k+ G" D  h# s6 t: \/ G; H) |图片引用自:https://www.edureka.co/blog/how- ... -high-availability/2 m7 F: I. X. n! I" J

" _6 v+ h% e5 `+ L  c  VHDFS 高可用架构主要由以下组件所构成:8 U& j# f( V6 T  }$ V, [% ?2 n: a

. L. g- X1 j9 OActive NameNode 和 Standby NameNode:两台 NameNode 形成互备,一台处于 Active 状态,为主 NameNode,另外一台处于 Standby 状态,为备 NameNode,只有主 NameNode 才能对外提供读写服务。
! Y) S6 g6 e( A
* ~) k+ J$ |( \2 H9 n8 T. |6 N主备切换控制器 ZKFailoverController:ZKFailoverController 作为独立的进程运行,对 NameNode 的主备切换进行总体控制。ZKFailoverController 能及时检测到 NameNode 的健康状况,在主 NameNode 故障时借助 Zookeeper 实现自动的主备选举和切换,当然 NameNode 目前也支持不依赖于 Zookeeper 的手动主备切换。: _0 ]6 ^/ }& k  p. f0 Z3 a$ l
) C% r' ^$ E0 U& S
Zookeeper 集群:为主备切换控制器提供主备选举支持。2 s6 o" R8 i2 G; S9 d* J! G5 X5 M3 ~/ r

# E7 Y1 s+ u- M: q共享存储系统:共享存储系统是实现 NameNode 的高可用最为关键的部分,共享存储系统保存了 NameNode 在运行过程中所产生的 HDFS 的元数据。主 NameNode 和 NameNode 通过共享存储系统实现元数据同步。在进行主备切换的时候,新的主 NameNode 在确认元数据完全同步之后才能继续对外提供服务。8 j" J2 l0 k9 }

; D- I3 R/ _' {: C8 eDataNode 节点:除了通过共享存储系统共享 HDFS 的元数据信息之外,主 NameNode 和备 NameNode 还需要共享 HDFS 的数据块和 DataNode 之间的映射关系。DataNode 会同时向主 NameNode 和备 NameNode 上报数据块的位置信息。
, n% a) R+ H% l, H
3 V8 b: c7 Y# q1.2 基于 QJM 的共享存储系统的数据同步机制分析9 U9 W" X. Q* G, S2 b# u
目前 Hadoop 支持使用 Quorum Journal Manager (QJM) 或 Network File System (NFS) 作为共享的存储系统,这里以 QJM 集群为例进行说明:Active NameNode 首先把 EditLog 提交到 JournalNode 集群,然后 Standby NameNode 再从 JournalNode 集群定时同步 EditLog,当 Active NameNode 宕机后, Standby NameNode 在确认元数据完全同步之后就可以对外提供服务。- u" E7 |* {' y

; C# V* {4 d6 V" e. c需要说明的是向 JournalNode 集群写入 EditLog 是遵循 “过半写入则成功” 的策略,所以你至少要有 3 个 JournalNode 节点,当然你也可以继续增加节点数量,但是应该保证节点总数是奇数。同时如果有 2N+1 台 JournalNode,那么根据过半写的原则,最多可以容忍有 N 台 JournalNode 节点挂掉。
6 O+ J1 C8 s" O# C" ~4 I9 l+ T# W7 {" f5 s5 n) k& U
: H6 a; h# k) o( D8 k
1.3 NameNode 主备切换
% r6 o3 m; w" ~& Y3 ^NameNode 实现主备切换的流程下图所示:( g0 H5 @! d! F8 v* A* Y# a5 m$ U

: {) Z9 X( \7 ?% E3 z1 u& d: E8 |# h4 a1 H' |
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 状态。* Q2 a& q$ \" H. B
1.4 YARN高可用& H* a) O. o* f* `0 ?
YARN ResourceManager 的高可用与 HDFS NameNode 的高可用类似,但是 ResourceManager 不像 NameNode ,没有那么多的元数据信息需要维护,所以它的状态信息可以直接写到 Zookeeper 上,并依赖 Zookeeper 来进行主备选举。1 z" N0 R! }0 R5 Q$ w7 B" l# x

* c6 h4 J2 t( b8 ?; n! ^6 Z" @$ C. n3 L9 ?" R: v2 `
二、集群规划: \! T5 L& ~8 Y/ h" ?0 q
按照高可用的设计目标:需要保证至少有两个 NameNode (一主一备) 和 两个 ResourceManager (一主一备) ,同时为满足“过半写入则成功”的原则,需要至少要有 3 个 JournalNode 节点。这里使用三台主机进行搭建,集群规划如下:5 y. W" G% d1 b( z3 E' C' `; v, p
" m# `' i$ H7 g2 g

  b+ R) ?3 ?. ~/ m& z! n三、前置条件
& N5 w) k3 C) X& _! d- ]所有服务器都安装有 JDK,安装步骤可以参见:Linux 下 JDK 的安装;6 `" H2 u9 [! E8 R
搭建好 ZooKeeper 集群,搭建步骤可以参见:Zookeeper 单机环境和集群环境搭建
& L) t1 ]" ?/ n" W所有服务器之间都配置好 SSH 免密登录。$ G7 p9 h$ n) c: B, o
四、集群配置
  }; j5 }# Z6 S6 g; ?) E1 O4.1 下载并解压) y" L) |( ~+ J% N7 `2 l
下载 Hadoop。这里我下载的是 CDH 版本 Hadoop,下载地址为:http://archive.cloudera.com/cdh5/cdh/5/
7 j3 b8 t! S5 t" Q
0 }4 G" v5 _+ E6 A9 q6 X7 [2 n# tar -zvxf hadoop-2.6.0-cdh5.15.2.tar.gz
) Y4 U/ i6 V# x7 h3 W: ^5 ?! [: y3 `4.2 配置环境变量% Q/ m: M/ u" V$ y0 C3 E9 m
编辑 profile 文件:8 s' f2 y2 L! [: v

  y4 K& \3 J6 h! O. k# vim /etc/profile
  \* s- I: T+ J/ s; N4 ~) {* C增加如下配置:" t/ n( h' d3 ]1 h

  ^% r5 {3 T! z- C" N9 Q9 Fexport HADOOP_HOME=/usr/app/hadoop-2.6.0-cdh5.15.2
! p( C9 Y: h1 h' |; L% J; k0 h0 q0 j! ?export  PATH=${HADOOP_HOME}/bin:$PATH
- {9 u: E. T! U/ Y4 ^; ?! y2 K. H执行 source 命令,使得配置立即生效:
  j, i: W/ G& n. ?, x* [
! f) j  }' s: R1 z# source /etc/profile, }& P) Z8 ^8 u* c  E" c& w; S" E! M
4.3 修改配置
7 \: T% i$ G# q# z7 ?( O进入 ${HADOOP_HOME}/etc/hadoop 目录下,修改配置文件。各个配置文件内容如下:
* `2 m& Z) E. s: ^+ y( D
1 f- |, z1 D. A/ w1. hadoop-env.sh
+ c7 q% v& x/ H, P' I1 D! |# 指定JDK的安装位置
( E  {5 V3 |6 o5 Fexport JAVA_HOME=/usr/java/jdk1.8.0_201/
. \" x( E3 q# U" ?* z& T2. core-site.xml" o/ x5 T" d+ A! {1 N( A
<configuration>4 ?$ ^9 z& V! `1 v, _& ^; x/ O) y
    <property>$ U1 M4 b/ S& h! N% s3 c
        <!-- 指定 namenode 的 hdfs 协议文件系统的通信地址 -->( N# k) X4 u% e- q6 z; n
        <name>fs.defaultFS</name>
* Y( L5 u1 t8 {- X1 }7 r0 G( O        <value>hdfs://hadoop001:8020</value>
9 Z; F% J: L  Z& U1 Z; X    </property>
% c+ ]& P) P! s* i8 R, t) `" g    <property>; ^3 B' r: {( s& q1 R" A. d
        <!-- 指定 hadoop 集群存储临时文件的目录 -->  d5 M2 P) R( E3 a2 y
        <name>hadoop.tmp.dir</name>' A2 K  S2 O4 P8 a% d$ {
        <value>/home/hadoop/tmp</value>- d4 J0 e" m6 |7 Q. j1 B: `
    </property>
: n$ g# d6 E; J9 P% i* E' a    <property>
0 f1 g: p6 S2 V# p- h# U' I        <!-- ZooKeeper 集群的地址 -->% L0 Z6 P& B- c6 e4 {. I
        <name>ha.zookeeper.quorum</name>4 `3 Q  O. L% n9 h3 o- l% m
        <value>hadoop001:2181,hadoop002:2181,hadoop003:2181</value>
$ f( n/ `3 {1 r% O: T    </property>& j; _! O! \7 h2 d# v$ i
    <property>2 `! f/ Y( ?( A2 m8 O) S3 Z* x: z: l
        <!-- ZKFC 连接到 ZooKeeper 超时时长 -->8 n4 D: f; t- d
        <name>ha.zookeeper.session-timeout.ms</name>4 @# {9 ]6 b- q' |/ ^. L
        <value>10000</value>- B6 P# |6 }: x3 L7 [# a* m; `
    </property>
# R1 L: u. f8 C3 d& q</configuration>
& h$ h9 ]8 ~" x4 [6 Y4 `6 q3. hdfs-site.xml
$ T5 S+ C# D& s' {! [8 W7 Z: t1 O' T<configuration>0 s2 {# X  J7 m% X
    <property>! j, K9 o; ]; H( b  l! C
        <!-- 指定 HDFS 副本的数量 -->
6 y6 ^! r# n* c) d% h5 X7 x        <name>dfs.replication</name>$ n. r4 g, m' S
        <value>3</value>6 j2 Y# O( v2 Y1 [% b
    </property>  x4 g/ Y& w# r& l6 ~" G3 V! c7 j
    <property>
1 l# V* q9 L7 _% \) V9 x  f; A        <!-- namenode 节点数据(即元数据)的存放位置,可以指定多个目录实现容错,多个目录用逗号分隔 -->
, x* H9 b2 W5 G' g# S- v7 l        <name>dfs.namenode.name.dir</name>
0 T. R$ J' l3 H/ L' B  c        <value>/home/hadoop/namenode/data</value>
& f& s/ I; q8 n    </property>
/ u3 J% P$ ^1 q6 B" R& R    <property>3 Z* F* K: j8 z" \; H
        <!-- datanode 节点数据(即数据块)的存放位置 -->
( `/ }3 ]4 V, Z  W6 B$ b) V        <name>dfs.datanode.data.dir</name>
/ r- R! x" B9 ~  g. |        <value>/home/hadoop/datanode/data</value>
! c4 e( E6 h- v7 p, e% @$ n    </property>
3 A  @$ Q1 _+ D" Z    <property>
+ b. s1 k' e2 x% \" Y        <!-- 集群服务的逻辑名称 -->
: g5 l# v  S! i# [8 F( W. Z/ _        <name>dfs.nameservices</name>7 T/ q! Q" K- L. \# a5 x
        <value>mycluster</value>
! S# T: _* S5 j' f9 X% l    </property>
5 q& N6 e% }0 Y$ b; E5 N    <property>
5 }" c1 P5 a1 l, u3 k1 \        <!-- NameNode ID 列表-->( j- l! j5 T& J1 s9 a% ~+ L% J
        <name>dfs.ha.namenodes.mycluster</name>1 Z/ D/ h" J; E1 e3 j! f+ \% E! g) e
        <value>nn1,nn2</value>
, F# U$ q( G, @    </property>
' k5 o1 p1 m6 L& T    <property>
, q) m6 j( n+ q' L        <!-- nn1 的 RPC 通信地址 -->
: x: N0 D( c, ?& C        <name>dfs.namenode.rpc-address.mycluster.nn1</name>
) ^" P: T7 Q  p8 z        <value>hadoop001:8020</value>6 T! c. c+ _: L6 Z) F
    </property>/ i: A* A. b, _& @
    <property>1 Z/ h0 X1 O# \0 D7 X  Z
        <!-- nn2 的 RPC 通信地址 -->
# S1 k4 q) _; M0 }0 d5 I& _0 v- I        <name>dfs.namenode.rpc-address.mycluster.nn2</name>9 B* n( k" L/ k) P# _
        <value>hadoop002:8020</value>9 {) p6 s3 ?; V9 v/ y
    </property>7 D1 Y& r7 ^/ E0 t2 Y
    <property>7 {( a, ^  q% U: C# I" u- j0 O! c
        <!-- nn1 的 http 通信地址 -->
& k9 D  a6 m; s( e        <name>dfs.namenode.http-address.mycluster.nn1</name>% }$ E8 |4 J, ^+ a3 f$ W$ Y  [
        <value>hadoop001:50070</value>
: a' s" c2 Z  `1 \% n    </property>
; C- P9 ?+ f6 w8 H+ X% k    <property>
; O( A" i* B. }9 S0 b        <!-- nn2 的 http 通信地址 -->0 R$ i2 `  P( O2 P: e
        <name>dfs.namenode.http-address.mycluster.nn2</name>
- K5 a0 ?, \4 i9 @, ?7 ^        <value>hadoop002:50070</value>
: T7 @5 {) N7 r( M1 f8 H    </property>
1 L+ s1 c' q3 A6 _/ T* i    <property>- @5 [# `1 a4 k5 n
        <!-- NameNode 元数据在 JournalNode 上的共享存储目录 -->
( E7 G7 r2 R2 _) E  z/ H2 t        <name>dfs.namenode.shared.edits.dir</name>
9 S! Y0 K: E3 [, ]  N4 q. Z        <value>qjournal://hadoop001:8485;hadoop002:8485;hadoop003:8485/mycluster</value>
+ J( o) c9 z3 \  t    </property>- U. h8 g7 P! n+ E/ q
    <property>
- F3 z  l3 E# D& u- `        <!-- Journal Edit Files 的存储目录 -->
: n$ ^- E, c2 S- e; E) B        <name>dfs.journalnode.edits.dir</name>
$ C: J0 X( q- ?( U  t$ w. G        <value>/home/hadoop/journalnode/data</value>3 U% p; H- v$ Y. P" [
    </property>
- h) m3 h; o0 E    <property>
- C$ E- N( h7 J. Z4 j9 e        <!-- 配置隔离机制,确保在任何给定时间只有一个 NameNode 处于活动状态 -->
5 w2 Z. }4 d% g$ |: p9 m- s% P        <name>dfs.ha.fencing.methods</name>: n7 c. n4 V  G5 j$ N  K# t8 H; e7 s4 }
        <value>sshfence</value>; z4 j2 T# {  V6 R. v
    </property>/ c; c% S$ B" j$ [6 j+ u; ^6 T4 k
    <property>
" t  i( P6 d1 i+ S$ A8 v- M        <!-- 使用 sshfence 机制时需要 ssh 免密登录 -->
# ^; U, z6 ?; h% Z8 `1 x        <name>dfs.ha.fencing.ssh.private-key-files</name>
* }' h0 x6 ]2 W, O. T        <value>/root/.ssh/id_rsa</value>
, }; ~7 Q2 H. s( Q- e" k    </property>
4 G+ G8 O4 [3 [  D6 l; v6 N* r' ^    <property>+ w# c- B4 g5 R7 ?5 ~, w
        <!-- SSH 超时时间 -->8 V; W, W) r, t) B1 f+ c
        <name>dfs.ha.fencing.ssh.connect-timeout</name>$ d4 d# i2 A1 E% Z  h/ O' h9 k  Q
        <value>30000</value>7 p' o' U; J1 h2 [" W
    </property>
! l" \- j" V, ?1 p* ^) H5 @$ A    <property>
! w2 |- R. v- n+ V8 h  L* ]        <!-- 访问代理类,用于确定当前处于 Active 状态的 NameNode -->' l# W" k' F6 Z9 l7 m9 ~
        <name>dfs.client.failover.proxy.provider.mycluster</name>& @; C$ `4 y7 Q6 S
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
4 b( H0 F5 p! e, v    </property>
5 G* v( ~, s% ~& x1 D0 G$ _  T6 |4 u    <property>" g3 p* ]+ S# o! ^, {+ O
        <!-- 开启故障自动转移 -->* A7 Q3 ^) y/ b8 K0 N
        <name>dfs.ha.automatic-failover.enabled</name>
# a: G% R/ t, z  b  `! [        <value>true</value>, }, B' G2 s$ d: b: I- N! x% ^8 b
    </property>
" X+ I+ `. Z  N; F3 q( y) g- ^</configuration>
$ p. g; B4 U7 G+ ]! G& k4. yarn-site.xml
" C  h6 w" p; q. m" ~1 U* r' ~8 ^<configuration>
# W! O: h' m- h2 J+ J7 P8 @- n* j    <property>2 w5 Q( {  ]% W  X8 l
        <!--配置 NodeManager 上运行的附属服务。需要配置成 mapreduce_shuffle 后才可以在 Yarn 上运行 MapReduce 程序。-->
3 e" Y8 U5 {3 ^; t# z        <name>yarn.nodemanager.aux-services</name>
" c5 i, W3 t# C( b, v, M6 W        <value>mapreduce_shuffle</value>
+ {, ~: P" C0 s& ]! _  n/ Z' o    </property>& ?$ z9 w0 \! [
    <property>! l6 `& O, |/ o3 T
        <!-- 是否启用日志聚合 (可选) -->6 u# @. Q$ m8 ^& A
        <name>yarn.log-aggregation-enable</name>5 D$ Q! _4 a  F% ]  D& C
        <value>true</value>, e; ]& d! w7 O
    </property>4 y7 s  @1 H1 I# K) P& F( ?2 a4 b
    <property>
) j; ^9 g* ^4 g- ]        <!-- 聚合日志的保存时间 (可选) -->
: U% W: U3 c7 W% U        <name>yarn.log-aggregation.retain-seconds</name>
6 V6 L; ^; }1 Z/ ]% L* s0 v1 b        <value>86400</value>
% X  Y. Q4 S) o  k" e0 j    </property>- x; q7 l" f' ]7 g
    <property>, R' B. }) I. V& T% @6 l
        <!-- 启用 RM HA -->
* O% M( i5 a& i9 |" x! c# J  L0 |        <name>yarn.resourcemanager.ha.enabled</name>4 |1 i; l8 ?7 h7 j
        <value>true</value># {) m9 _* N5 T  A
    </property>; Y# d/ ^+ v* F) [( m; {) ]
    <property>" n, c9 ]6 g* K4 W
        <!-- RM 集群标识 -->
$ Y5 i" q' b) ]% _5 t* R        <name>yarn.resourcemanager.cluster-id</name>( _+ V/ l+ g. n+ k: ~
        <value>my-yarn-cluster</value>% P0 D' Z, P5 t4 o
    </property>8 |2 S1 @; T) y! q( p7 v7 M
    <property>4 a0 P% J+ W9 K% e
        <!-- RM 的逻辑 ID 列表 -->7 V" @- w" w; T, N: U6 _$ S
        <name>yarn.resourcemanager.ha.rm-ids</name>  S3 g& e7 z' u" _/ U
        <value>rm1,rm2</value># c+ z( i* J4 N9 a+ g$ t+ n/ Y0 }
    </property># s4 o! [! m/ [5 }9 k
    <property>
% z  w& ~8 m* W        <!-- RM1 的服务地址 -->
7 ]0 M8 ^6 k' ]( v        <name>yarn.resourcemanager.hostname.rm1</name>6 B* o0 `0 Y% e$ D
        <value>hadoop002</value>" t9 q$ j8 P, i5 e+ {) N
    </property>  I$ ]# M5 e/ d/ V: A. g. t
    <property>
2 F( T, l& o9 G        <!-- RM2 的服务地址 -->
/ E5 D5 t1 |8 a+ {: q$ k  W" c        <name>yarn.resourcemanager.hostname.rm2</name>& i1 W  ?$ S- g( h- p( K% M+ Q
        <value>hadoop003</value># a) a9 R. V; n/ e: L  j+ R( V
    </property>! c8 O( A$ G' p) N: X1 q4 m
    <property>% i' ^0 E  D: b/ c; R. S8 F
        <!-- RM1 Web 应用程序的地址 -->
1 \! X& ~  `. x' _' O5 v5 H$ g        <name>yarn.resourcemanager.webapp.address.rm1</name>
6 x: m" b) U& ]3 o        <value>hadoop002:8088</value>
/ {$ S( ~! j4 G& W/ l! N) [: M: ^1 J1 T    </property>" n7 }( j0 D( Q9 z6 l
    <property>; @4 W# u# N0 y# s
        <!-- RM2 Web 应用程序的地址 -->
6 L2 `7 |6 j3 e$ U        <name>yarn.resourcemanager.webapp.address.rm2</name>- k6 S( P2 z+ s8 T; `0 `
        <value>hadoop003:8088</value>5 k* l( `' e7 g% V' V/ H
    </property>9 X7 C3 X# p' Q' M$ w% Z" R$ i
    <property>* z& b! c, Z0 X* y) p: P
        <!-- ZooKeeper 集群的地址 -->+ s2 i3 _  r6 _  U5 J
        <name>yarn.resourcemanager.zk-address</name>
( i4 U  D- |0 j/ M4 v* F# E        <value>hadoop001:2181,hadoop002:2181,hadoop003:2181</value>
1 J9 R: I6 C+ t5 t4 x, i    </property>1 l! r4 T1 A) X2 i- s
    <property>, ?5 {5 _8 M+ k- P+ x0 E4 R
        <!-- 启用自动恢复 -->. H" _$ {4 _- z  x3 V4 n
        <name>yarn.resourcemanager.recovery.enabled</name>' Z& ]$ Z) p1 e$ G2 L/ Q6 G$ G) P
        <value>true</value>
% f8 b5 r+ }& u) V: I/ D! k# d; T$ v: y: O    </property>' i9 F9 S1 R. P/ f2 t+ p4 B% D
    <property>
4 L' g$ i/ W- X/ g) s, |) J5 s        <!-- 用于进行持久化存储的类 -->
# E% O7 M* t$ {* F        <name>yarn.resourcemanager.store.class</name>
7 K! R! @! t+ g: \        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
7 t- T9 q; R" U    </property>* \  I" k4 a- \" d- G5 H* C% K
</configuration>
. S* Q' d' N+ A5. mapred-site.xml
4 B: R0 U2 _' U<configuration>) \! g. s/ q9 R/ t0 _* F3 [
    <property>
" F/ @4 F/ \7 h9 l" ~        <!--指定 mapreduce 作业运行在 yarn 上-->) N5 g0 e4 d3 U9 H9 E! M5 m
        <name>mapreduce.framework.name</name>+ s) J) |0 R' n# i; R. g
        <value>yarn</value>
- O7 {0 l: C; H: u    </property>
6 C5 c# O' _% B# k7 A( q5 f0 w</configuration>
! e& _4 D2 ^4 U: ]/ v+ L5 J& c5. slaves
1 j, V2 T; R' d; ~7 Y配置所有从属节点的主机名或 IP 地址,每行一个。所有从属节点上的 DataNode 服务和 NodeManager 服务都会被启动。
5 j& l2 |8 @8 \7 c2 v
9 r9 ^& F& f6 J7 `* ?0 jhadoop001
; u/ K3 V5 h1 i+ qhadoop002
9 t4 D' B/ }$ f$ p1 h6 x) Uhadoop003
' a6 h7 M8 v  k4.4 分发程序, F$ d  d! y) k5 z/ Y" K" ^) s
将 Hadoop 安装包分发到其他两台服务器,分发后建议在这两台服务器上也配置一下 Hadoop 的环境变量。
% e; u1 t4 q. W. F( i# C
% E* j" V. b+ e$ N& ]: x6 ?# 将安装包分发到hadoop0024 a2 z3 v+ F6 r6 f3 I  j8 E  w
scp -r /usr/app/hadoop-2.6.0-cdh5.15.2/  hadoop002:/usr/app/
7 A% p9 @8 ]6 c# n, P  A) p# 将安装包分发到hadoop003
. u4 v. ]5 s: N  R1 ]scp -r /usr/app/hadoop-2.6.0-cdh5.15.2/  hadoop003:/usr/app/2 a1 l: |! Q6 {  E9 \" H9 h: u+ S0 m
五、启动集群
+ m: y" v/ c9 S9 e; o- z* {5.1 启动ZooKeeper0 r" q# B, |5 \5 f% q' o! E% h5 i
分别到三台服务器上启动 ZooKeeper 服务:& T  U' e5 r# Z6 p" B" U, d' ~

; ]. ^" R. ]8 _! T( O" t) J7 i zkServer.sh start1 R6 v! U' s* ^) H
5.2 启动Journalnode
  |( M( r( g5 b' ^: C# E分别到三台服务器的的 ${HADOOP_HOME}/sbin 目录下,启动 journalnode 进程:
/ s$ y2 Z$ }- l) [$ X* J# z1 g
" ]: P: q8 ^$ b1 P$ z& [9 Q  Shadoop-daemon.sh start journalnode
8 S: g& v. y/ ^1 @: P. O% \: I) U5.3 初始化NameNode
) V% }6 p3 t3 I' I' l! a在 hadop001 上执行 NameNode 初始化命令:
1 X, t; l1 P( N# Q  S3 I1 W5 V( @4 j9 }9 g
hdfs namenode -format2 X$ K9 e; u' s" [! f
执行初始化命令后,需要将 NameNode 元数据目录的内容,复制到其他未格式化的 NameNode 上。元数据存储目录就是我们在 hdfs-site.xml 中使用 dfs.namenode.name.dir 属性指定的目录。这里我们需要将其复制到 hadoop002 上:, T( ~( q' z7 C

7 W" N- K! \3 G5 ~, a- | scp -r /home/hadoop/namenode/data hadoop002:/home/hadoop/namenode/' i! N" o  R* Q, h  `
5.4 初始化HA状态1 L5 L6 l* @  L# Z' X* @8 ?
在任意一台 NameNode 上使用以下命令来初始化 ZooKeeper 中的 HA 状态:
. |. `, T3 |6 ?* V+ Z/ Y& X/ d
: E3 S1 a# k) j! C/ Bhdfs zkfc -formatZK
" k) s/ ], ], D# B# g3 {; p5.5 启动HDFS8 @5 ?0 [" S  B0 f
进入到 hadoop001 的 ${HADOOP_HOME}/sbin 目录下,启动 HDFS。此时 hadoop001 和 hadoop002 上的 NameNode 服务,和三台服务器上的 DataNode 服务都会被启动:5 w" i/ `, O$ D# k* N3 ?. _1 S  {

, c, M' ?) @) n4 G/ G$ n8 [start-dfs.sh. |, R1 ?7 ~. ]. S/ m! D! Z; q
5.6 启动YARN3 L4 {1 ?, L8 u2 p6 S1 o' J  W
进入到 hadoop002 的 ${HADOOP_HOME}/sbin 目录下,启动 YARN。此时 hadoop002 上的 ResourceManager 服务,和三台服务器上的 NodeManager 服务都会被启动:
. [. J4 f, P% N; _' j8 o# h  V* w* V# q. s1 `( d
start-yarn.sh
0 `" L; G2 L% K* U需要注意的是,这个时候 hadoop003 上的 ResourceManager 服务通常是没有启动的,需要手动启动:
) x2 q# j. s1 W# n2 g0 O% K: `( `7 U9 P! v& g  {& `- Q
yarn-daemon.sh start resourcemanager( s& v0 z) P" O" u( m
六、查看集群: S* d, d6 Q8 x9 r6 m
6.1 查看进程7 F+ b* o7 s8 o; i
成功启动后,每台服务器上的进程应该如下:
; n: V2 K; K4 d. R' m3 f1 }5 Z( @4 ?" S
[root@hadoop001 sbin]# jps
6 o( Y9 W9 A/ N) u* n0 K4512 DFSZKFailoverController# }% |% H# ]# `+ U! P1 B) f7 }
3714 JournalNode  r) v  R2 ~: p2 Y
4114 NameNode: C# ^8 K+ m( Y- E. c6 f" K+ [
3668 QuorumPeerMain# O/ ?4 f3 E$ [: z9 j; W, G" U
5012 DataNode* t. {# i1 [; G2 ^$ g  `$ {
4639 NodeManager! P% {/ L& z) z, ~* K5 j

( U+ V2 h5 m. I  F/ h8 u0 G8 w$ E) _% A2 N
[root@hadoop002 sbin]# jps
# V* g6 ^9 d5 [* x6 b& p# G: _* D4499 ResourceManager' V, U, F/ a! Y' i0 N: B
4595 NodeManager* _  a3 `9 X+ C
3465 QuorumPeerMain: X2 w' G& m8 N9 n- x
3705 NameNode0 G2 G# y0 ]4 b8 V
3915 DFSZKFailoverController
/ I, b( }& S+ W- l4 p4 {5211 DataNode' w/ S. p/ w% v7 W* u" F! t7 X# \' m; i
3533 JournalNode
5 B, {% @1 F4 }0 c8 Y
5 u( \& n# `$ y6 {1 K: {* N) [, A: g, E# {& l7 Z2 l
[root@hadoop003 sbin]# jps
+ \2 D! z- v; H3 Q5 b2 V- G3491 JournalNode) O. V1 l2 Y' W
3942 NodeManager2 u' u3 c4 p# a  A; b5 Q
4102 ResourceManager
2 ~" o) S9 {6 m" N; E4201 DataNode
& o- v5 Y" n- a1 S% H3 f7 P: Z0 G: R3435 QuorumPeerMain
  s# z: c6 f/ u1 r- U6.2 查看Web UI6 Y; [' x9 g4 _/ N2 M7 S4 q
HDFS 和 YARN 的端口号分别为 50070 和 8080,界面应该如下:
2 i& [& Q$ r6 u  \9 \# p
: {; t9 N* X- W! S此时 hadoop001 上的 NameNode 处于可用状态:3 K4 b, t& E. [6 F

9 t4 L% z2 }& L# h9 b4 z
1 T  {8 ^2 C3 p+ ?4 N3 b8 p/ l) D而 hadoop002 上的 `NameNode` 则处于备用状态:: p/ U& w- E" H9 c

3 l9 U0 I7 C" \; |0 t
% d, I7 Y/ C$ S  T: Jhadoop002 上的 ResourceManager 处于可用状态:8 ^- P1 W6 C( _4 k% F7 M! j0 e2 e8 h

% T& Q) A# R  D6 X; @6 {2 Q+ t) v* J0 B1 M! {
" L; u- U( B  U

- F% [6 r8 W! q2 Fhadoop003 上的 ResourceManager 则处于备用状态:
2 j* Q( F2 @% Z5 i4 f# ~- z4 i( H# l; J; o1 O  `( v

: ~& m- \8 Z$ L2 W, ?& ?1 T) y, ~" L( ^! N3 a% ]& L" J

2 T% l3 w+ i" ^- B+ B6 a同时界面上也有 Journal Manager 的相关信息:
: v, f4 c7 _' I2 j
9 X" y" S3 {& X, ?# i" h
% ?/ ^3 s; Q1 G" o6 O, P1 v
* [* w0 B" R( a- Y5 B) s* V% I## 七、集群的二次启动
* L' W9 i. ]( k) t$ T/ V9 p: g上面的集群初次启动涉及到一些必要初始化操作,所以过程略显繁琐。但是集群一旦搭建好后,想要再次启用它是比较方便的,步骤如下(首选需要确保 ZooKeeper 集群已经启动):, X3 R- E7 u% O; Q: v7 ~4 r

' Z5 ]7 R( G& z) k! ^$ f' m" g0 ~在 hadoop001 启动 HDFS,此时会启动所有与 HDFS 高可用相关的服务,包括 NameNode,DataNode 和 JournalNode:. t9 u/ E7 T8 S9 c' |6 L; i
. k* a* |9 t6 b8 `0 e
start-dfs.sh
$ g* Z8 M. f  N- ~1 B& Q1 Y在 hadoop002 启动 YARN:
, I9 p. O" H+ G2 f( b) J
1 o; T7 x- k# t! H$ T: ostart-yarn.sh; I5 @  I* x+ }; T' @  ^2 j
这个时候 hadoop003 上的 ResourceManager 服务通常还是没有启动的,需要手动启动:0 y' J5 K! q0 E( ?

) f% z% t- w! _* p6 M+ ?yarn-daemon.sh start resourcemanager% K  m6 N# e8 Q5 O" a; u0 a  O9 q/ n' h" H

6 H* t# H8 d, x' M" b8 c
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-12 03:06 , Processed in 0.034377 second(s), 25 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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