CDH Hadoop + HBase HA 部署详解

CDH 的部署和 Apache Hadoop 的部署是没有任何区别的。这里着重的是 HA的部署,需要特殊说明的是NameNode HA 需要依赖 Zookeeper。

准备

Hosts文件配置:

cat > /etc/hosts << _HOSTS_
127.0.0.1          localhost
10.0.2.59          cdh-m1
10.0.2.60          cdh-m2
10.0.2.61          cdh-s1
_HOSTS_

各个节点服务情况

cdh-m1 Zookeeper JournalNode NameNode DFSZKFailoverController HMaster
cdh-m2 Zookeeper JournalNode NameNode DFSZKFailoverController HMaster
cdh-s1 Zookeeper JournalNode DataNode HRegionServer

对几个新服务说明下:

  • JournalNode 用于同步 NameNode 元数据,和 Zookeeper 一样需要 2N+1个节点存活集群才可用;
  • DFSZKFailoverController(ZKFC) 用于主备切换,类似 Keepalived 所扮演的角色。

NTP 服务

设置时区

rm -f /etc/localtime
ln -s  /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

配置NTP Server

yum install -y ntp
cat > /etc/ntp.conf << _NTP_
driftfile /var/lib/ntp/drift

restrict default nomodify
restrict -6 default nomodify

server cn.ntp.org.cn prefer
server news.neu.edu.cn iburst
server dns.sjtu.edu.cn iburst
server 127.127.1.1 iburst

tinker dispersion 100
tinker step 1800
tinker stepout 3600
includefile /etc/ntp/crypto/pw

keys /etc/ntp/keys
_NTP_

# NTP启动时立即同步
cat >> /etc/ntp/step-tickers << _NTP_
server cn.ntp.org.cn prefer
server news.neu.edu.cn iburst
server dns.sjtu.edu.cn iburst
_NTP_

# 同步硬件时钟
cat >> /etc/sysconfig/ntpd << _NTPHW_
SYNC_HWCLOCK=yes
_NTPHW_

启动并设置开机自启动

/etc/init.d/ntpd start
chkconfig ntpd on

配置 NTP Client

yum install -y ntp
# 注意修改内网NTP Server地址
cat > /etc/ntp.conf << _NTP_
driftfile /var/lib/ntp/drift

restrict default nomodify
restrict -6 default nomodify

restrict 127.0.0.1
restrict -6 ::1

server 10.0.2.59 prefer

tinker dispersion 100
tinker step 1800
tinker stepout 3600
includefile /etc/ntp/crypto/pw

keys /etc/ntp/keys
_NTP_

# NTP启动时立即同步
cat >> /etc/ntp/step-tickers << _NTP_
server 10.0.2.59 prefer
_NTP_

# 同步硬件时钟
cat >> /etc/sysconfig/ntpd << _NTPHW_
SYNC_HWCLOCK=yes
_NTPHW_

启动并设置开机自启动

/etc/init.d/ntpd start
chkconfig ntpd on

检查 NTP 同步

ntpq -p

# 结果
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*time7.aliyun.co 10.137.38.86     2 u   17   64    3   44.995    5.178   0.177
 news.neu.edu.cn .INIT.          16 u    -   64    0    0.000    0.000   0.000
 202.120.2.90    .INIT.          16 u    -   64    0    0.000    0.000   0.000

JDK配置

创建目录

mkdir -p /data/{install,app,logs,pid,appData}
mkdir /data/appData/tmp

cd /data/install
wget -c http://oracle.com/jdk-7u51-linux-x64.gz
tar xf jdk-7u51-linux-x64.gz -C /data/app
cd /data/app
ln -s jdk1.7.0_51 jdk1.7
cat >> /etc/profile << _PATH_
export JAVA_HOME=/data/app/jdk1.7
export CLASSPATH=.:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar
export PATH=\$JAVA_HOME/bin:\$PATH
_PATH_
source /etc/profile

创建运行账户

useradd -u 600 run

下载 安装包

# http://archive.cloudera.com/cdh5/cdh/5/
cd /data/install
wget -c http://archive.cloudera.com/cdh5/cdh/5/hadoop-2.6.0-cdh5.4.5.tar.gz
wget -c http://archive.apache.org/dist/zookeeper/zookeeper-3.4.5/zookeeper-3.4.5.tar.gz
wget -c http://archive.cloudera.com/cdh5/cdh/5/hbase-1.0.0-cdh5.4.5.tar.gz

安装 Zookeeper

cd /data/install
tar xf zookeeper-3.4.5.tar.gz -C /data/app
cd /data/app
ln -s zookeeper-3.4.5 zookeeper

设置环境变量

sed -i '/^export PATH=/i\export ZOOKEEPER_HOME=/data/app/zookeeper' /etc/profile
sed -i 's#export PATH=#&\$ZOOKEEPER_HOME/bin:#' /etc/profile
source /etc/profile

删除无用文件

cd $ZOOKEEPER_HOME
rm -rf *xml *txt zookeeper-3.4.5.jar.* src recipes docs dist-maven contrib
rm -f $ZOOKEEPER_HOME/bin/*.cmd $ZOOKEEPER_HOME/bin/*.txt
rm -f $ZOOKEEPER_HOME/conf/zoo_sample.cfg

创建数据目录

mkdir -p /data/appData/zookeeper/{data,logs}

配置

cat > $ZOOKEEPER_HOME/conf/zoo.cfg << _ZOO_
tickTime=2000
initLimit=10
syncLimit=5
clientPort=2181
dataDir=/data/appData/zookeeper/data
dataLogDir=/data/appData/zookeeper/logs
server.1=cdh-m1:2888:3888
server.2=cdh-m2:2888:3888
server.3=cdh-s1:2888:3888
_ZOO_

修改Zookeeper的日志打印方式,与日志路径设置, 编辑

$ZOOKEEPER_HOME/bin/zkEnv.sh

在27行后加入两个变量

ZOO_LOG_DIR=/data/logs/zookeeper
ZOO_LOG4J_PROP="INFO,ROLLINGFILE"

创建 myid文件

# 注意myid与配置文件保持一致
echo 1 >/data/appData/zookeeper/data/myid

设置目录权限

chown -R run.run /data/{app,appData,logs}

启动、停止

# 启动
runuser - run -c 'zkServer.sh start'
# 停止
runuser - run -c 'zkServer.sh stop'

安装 Hadoop

tar xf hadoop-2.6.0-cdh5.4.5.tar.gz -C /data/app
cd /data/app
ln -s hadoop-2.6.0-cdh5.4.5 hadoop

设置环境变量

sed -i '/^export PATH=/i\export HADOOP_HOME=/data/app/hadoop' /etc/profile
sed -i 's#export PATH=#&\$HADOOP_HOME/bin:\$HADOOP_HOME/sbin:#' /etc/profile
source /etc/profile

删除无用文件

cd $HADOOP_HOME
rm -rf *txt share/doc src examples* include bin-mapreduce1 cloudera
find . -name "*.cmd"|xargs rm -f

新建数据目录

mkdir -p /data/appData/hdfs/{name,edits,data,jn,tmp}

配置

切换到配置文件目录

cd $HADOOP_HOME/etc/hadoop

编辑 core-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
     <!-- HDFS 集群名称,可指定端口 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hdfs-cdh</value>
    </property>

    <!-- 临时文件目录 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/data/appData/hdfs/tmp</value>
    </property>

    <!-- 回收站设置,0不启用回收站,1440 表示1440分钟后删除 -->
    <property>
        <name>fs.trash.interval</name>
        <value>1440</value>
    </property>

    <!-- SequenceFiles在读写中可以使用的缓存大小,单位 bytes 默认 4096 -->
    <property>
        <name>io.file.buffer.size</name>
        <value>131072</value>
    </property>

    <!-- 可用压缩算法,启用在hdfs-site.xml中,需要编译动态链接库才能用 -->
    <property>
        <name>io.compression.codecs</name>
        <value>org.apache.hadoop.io.compress.SnappyCodec</value>
    </property>
</configuration>

编辑 hdfs-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <!-- 指定hdfs 集群名称,需要和core-site.xml中的保持一致 -->
    <property>
        <name>dfs.nameservices</name>
        <value>hdfs-cdh</value>
    </property>

    <!-- 指定 Zookeeper 用于NameNode HA,默认官方配置在core-site.xml中,为了查看清晰配置到hdfs-site.xml也是可用的 -->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>cdh-m1:2181,cdh-m2:2181,cdh-s1:2181</value>
    </property>

    <!-- hdfs-cdh 下有两个NameNode,分别为 nn1,nn2 -->
    <property>
        <name>dfs.ha.namenodes.hdfs-cdh</name>
        <value>nn1,nn2</value>
    </property>

    <!-- nn1 RPC通信地址 -->
    <property>
        <name>dfs.namenode.rpc-address.hdfs-cdh.nn1</name>
        <value>cdh-m1:9000</value>
    </property>

    <!-- nn1 HTTP通信地址 -->
    <property>
        <name>dfs.namenode.http-address.hdfs-cdh.nn1</name>
        <value>cdh-m1:50070</value>
    </property>

    <!-- nn2 RPC通信地址 -->
    <property>
        <name>dfs.namenode.rpc-address.hdfs-cdh.nn2</name>
        <value>cdh-m2:9000</value>
    </property>

    <!-- nn2 HTTP通信地址 -->
    <property>
        <name>dfs.namenode.http-address.hdfs-cdh.nn2</name>
        <value>cdh-m2:50070</value>
    </property>

    <!-- 指定NameNode元数据在JournalNode上的存储路径 -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://cdh-m1:8485;cdh-m2:8485;cdh-s1:8485;/hdfs-cdh</value>
    </property>

    <!-- 开启NameNode失败自动切换 -->
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>

    <!-- 配置主备切换实现方式 -->
    <property>
        <name>dfs.client.failover.proxy.provider.hdfs-cdh</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>

    <!-- 配置主备切换方法,每个方法一行-->
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>
            sshfence
            shell(/bin/true)
        </value>
    </property>

    <!-- 指定运行用户的秘钥,需要NameNode双向免密码登录,用于主备自动切换 -->
    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/home/run/.ssh/id_rsa</value>
    </property>

    <!-- 配置sshfence 超时时间 -->
    <property>
        <name>dfs.ha.fencing.ssh.connect-timeout</name>
        <value>50000</value>
    </property>

    <!-- NameNode 数据本地存储路径 -->
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/data/appData/hdfs/name</value>
    </property>

    <!-- DataNode 数据本地存储路径 -->
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/data/appData/hdfs/data</value>
    </property>

    <!-- JournalNode 数据本地存储路径 -->
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/data/appData/hdfs/jn</value>
    </property>

    <!-- 修改文件存储到edits,定期同步到DataNode -->
    <property>
        <name>dfs.namenode.edits.noeditlogchannelflush</name>
        <value>true</value>
    </property>

    <!-- edits 数据本地存储路径 -->
    <property>
        <name>dfs.namenode.edits.dir</name>
        <value>/data/appData/hdfs/edits</value>
    </property>

    <!-- 开启Block Location metadata允许impala知道数据块在哪块磁盘上 默认关闭 -->
    <property>
        <name>dfs.datanode.hdfs-blocks-metadata.enabled</name>
        <value>true</value>
    </property>

    <!-- 权限检查 默认开启 -->
    <property>
        <name>dfs.permissions.enabled</name>
        <value>false</value>
    </property>

    <!-- block 大小设置 -->
    <property>
        <name>dfs.blocksize</name>
        <value>64m</value>
    </property>
</configuration>

小于5个DataNode建议添加如下配置

<!-- 数据副本数量,不能超过DataNode数量,大集群建议使用默认值 默认 3 -->
    <property>
        <name>dfs.replication</name>
        <value>2</value>
    </property>

    <!-- 当副本写入失败时不分配新节点,小集群适用 -->
    <property>
        <name>dfs.client.block.write.replace-datanode-on-failure.policy</name>
        <value>NEVER</value>
    </property>

在 hadoop-env.sh 中添加如下变量

export JAVA_HOME=/data/app/jdk1.7
export HADOOP_LOG_DIR=/data/logs/hadoop
export HADOOP_PID_DIR=/data/pid
# SSH端口 可选
export HADOOP_SSH_OPTS="-p 22"

Heap 设置,单位 MB

export HADOOP_HEAPSIZE=1024

权限设置

chown -R run.run /data/{app,appData,logs}
chmod 777 /data/pid

格式化

格式化只需要执行一次,格式化之前启动Zookeeper

切换用户

su - run

启动所有 JournalNode

hadoop-daemon.sh start journalnode

格式化 Zookeeper(为 ZKFC 创建znode)

hdfs zkfc -formatZK

NameNode 主节点格式化并启动

hdfs namenode -format
hadoop-daemon.sh start namenode

NameNode 备节点同步数据并启动

hdfs namenode -bootstrapStandby
hadoop-daemon.sh start namenode

启动 ZKFC

hadoop-daemon.sh start zkfc

启动 DataNode

hadoop-daemon.sh start datanode

启动与停止

切换用户

su - run

集群批量启动
需要配置运行用户ssh-key免密码登录,与$HADOOP_HOME/etc/hadoop/slaves

# 启动
start-dfs.sh
# 停止
stop-dfs.sh

单服务启动停止
启动HDFS

hadoop-daemon.sh start journalnode
hadoop-daemon.sh start namenode
hadoop-daemon.sh start zkfc
hadoop-daemon.sh start datanode

停止HDFS

hadoop-daemon.sh stop datanode
hadoop-daemon.sh stop namenode
hadoop-daemon.sh stop journalnode
hadoop-daemon.sh stop zkfc

测试

HDFS HA 测试
打开 NameNode 状态页:
http://cdh-m1:50010
http://cdh-m2:50010

在 Overview 后面能看见 active 或 standby,active 为当前 Master,停止 active 上的 NameNode,检查 standby是否为 active。

HDFS 测试

hadoop fs -mkdir /test
hadoop fs -put /etc/hosts /test
hadoop fs -ls /test

结果:

-rw-r--r--   2 java supergroup         89 2016-06-15 10:30 /test/hosts
# 其中权限后面的列(这里的2)代表文件总数,即副本数量。

HDFS 管理命令

# 动态加载 hdfs-site.xml
hadoop dfsadmin -refreshNodes

HBase安装配置

cd /data/install
tar xf hbase-1.0.0-cdh5.4.5.tar.gz -C /data/app
cd /data/app
ln -s hbase-1.0.0-cdh5.4.5 hbase

设置环境变量

sed -i '/^export PATH=/i\export HBASE_HOME=/data/app/hbase' /etc/profile
sed -i 's#export PATH=#&\$HBASE_HOME/bin:#' /etc/profile
source /etc/profile

删除无用文件

cd $HBASE_HOME
rm -rf *.txt pom.xml src docs cloudera dev-support hbase-annotations hbase-assembly hbase-checkstyle hbase-client hbase-common hbase-examples hbase-hadoop2-compat hbase-hadoop-compat hbase-it hbase-prefix-tree hbase-protocol hbase-rest hbase-server hbase-shell hbase-testing-util hbase-thrift
find . -name "*.cmd"|xargs rm -f

配置
进入配置文件目录

cd $HBASE_HOME/conf

编辑 hbase-site.xml

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <!-- HBase 数据存储路径 -->
    <property>
        <name>hbase.rootdir</name>
        <value>hdfs://hdfs-cdh/hbase</value>
    </property>

    <!-- 完全分布式模式 -->
    <property>
        <name>hbase.cluster.distributed</name>
        <value>true</value>
    </property>

    <!-- HMaster 节点 -->
    <property>
        <name>hbase.master</name>
        <value>cdh-m1:60000,cdh-m2:60000</value>
    </property>

    <!-- Zookeeper 节点 -->
    <property>
        <name>hbase.zookeeper.quorum</name>
        <value>cdh-m1:2181,cdh-m2:2181,cdh-s1:2181</value>
    </property>

    <!-- znode 路径,Zookeeper集群中有多个HBase集群需要设置不同znode -->
    <property>
        <name>zookeeper.znode.parent</name>
        <value>/hbase</value>
    </property>

    <!-- HBase 协处理器 -->
    <property>
        <name>hbase.coprocessor.user.region.classes</name>
        <value>org.apache.hadoop.hbase.coprocessor.AggregateImplementation</value>
    </property>
</configuration>

在 hbase-env.sh 中添加如下变量

export JAVA_HOME=/data/app/jdk1.7
export HBASE_LOG_DIR=/data/logs/hbase
export HBASE_PID_DIR=/data/pid
export HBASE_MANAGES_ZK=false
# SSH 默认端口 可选
export HBASE_SSH_OPTS="-o ConnectTimeout=1 -p 36000"

Heap 设置,单位 MB

export HBASE_HEAPSIZE=1024

可选设置 regionservers 中添加所有RegionServer主机名,用于集群批量启动、停止。

启动与停止
切换用户

su - run

集群批量启动
需要配置运行用户ssh-key免密码登录,与$HBASE_HOME/conf/regionservers

# 启动
start-hbase.sh
# 停止
stop-hbase.sh

单服务启动停止
HMaster

# 启动
hbase-daemon.sh start master
# 停止
hbase-daemon.sh stop master

HRegionServer

# 启动
hbase-daemon.sh start regionserver
# 停止
hbase-daemon.sh stop regionserver

测试
HBase HA 测试
浏览器打开两个HMaster状态页:
http://cdh-m1:60010
http://cdh-m2:60010

可以在Master后面看见其中一个主机名,Backup Masters中看见另一个。
停止当前Master,刷新另一个HMaster状态页会发现Master后面已经切换,HA成功。

HBase 测试
进入hbase shell 执行:

create 'users','user_id','address','info'
list
put 'users','anton','info:age','24'
get 'users','anton'

# 最终结果
COLUMN                     CELL
 info:age                  timestamp=1465972035945, value=24
1 row(s) in 0.0170 seconds

清除测试数据:

disable 'users'
drop 'users'

到这里安装就全部完成。

0 个评论

要回复文章请先登录注册