天天看點

CDH Hadoop + HBase HA 部署詳解

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/UTC /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 36000"      

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"      
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'