1. 程式人生 > >基於Docker的Zookeeper+Hadoop(HA)+hbase(HA)搭建

基於Docker的Zookeeper+Hadoop(HA)+hbase(HA)搭建

公司要將監控資料存入opentsdb,而opentsdb使用了hbase作為儲存。所以想搭建一套高可用的分散式儲存來供opentsdb使用。

因為機器有限,所以測試過程中將三臺叢集的環境安裝在docker上。

 

一:宿主機版本和docker版本

  宿主機:Centos7.2  3.10.0-862.14.4.el7.x86_64

  docker:Docker version 1.13.1, build 94f4240/1.13.1

二:映象版本

  docker.io/centos 

三:建立docker映象

   mkdir -p /home/dockerfile/hbaseha

  上傳軟體包至此目錄

  zookeeper-3.4.12.tar.gz

  hbase-1.3.2.1-bin.tar.gz

  hadoop-2.6.5.tar.gz

  jdk8.tar.gz

  建立Dockerfile。

  vi Dockerfile

# 選擇一個已有的os映象作為基礎  
FROM centos 
# 安裝openssh-server和sudo軟體包,並且將sshd的UsePAM引數設定成no  
RUN yum install -y openssh-server sudo  
RUN sed -i 's/UsePAM yes/UsePAM no/g
' /etc/ssh/sshd_config #安裝openssh-clients RUN yum install -y openssh-clients # 新增測試使用者root,密碼root,並且將此使用者新增到sudoers裡 RUN echo "root:root" | chpasswd RUN echo "root ALL=(ALL) ALL" >> /etc/sudoers # 下面這兩句比較特殊,在centos6上必須要有,否則創建出來的容器sshd不能登入 RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key RUN ssh
-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key # 啟動sshd服務並且暴露22埠 RUN mkdir /var/run/sshd EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]
ADD jdk8.tar.gz /usr/local/
RUN mv /usr/local/jdk1.8.0_171 /usr/local/jdk1.8
ENV JAVA_HOME /usr/local/jdk1.8
ENV PATH $JAVA_HOME/bin:$PATH
ADD hadoop-2.6.5.tar.gz /usr/local
#安裝which軟體包
RUN yum install -y which
#安裝net-tools軟體包
RUN yum install -y net-tools
ENV HADOOP_HOME /usr/local/hadoop-2.6.5
ENV PATH $HADOOP_HOME/bin:$PATH
ADD zookeeper-3.4.12.tar.gz /usr/local
ENV ZOOKEEPER_HOME /usr/local/zookeeper-3.4.12
ENV PATH $ZOOKEEPER_HOME/bin:$PATH
ADD hbase-1.3.2.1-bin.tar.gz /usr/local

        建立映象命令:

        docker build -t pro/hbase .

        建立完成後檢視映象生成情況:

        docker images

  

四:啟動容器,並規劃IP

  1-虛擬機器規劃

name role IP
hab0 Hadoop namenode/Hbase Master/ResourceManager 172.17.0.21
hab1 Hadoop namenode/Hbase Master/ResourceManager 172.17.0.22
hab2   172.17.0.23

  

  

 

  

 

  2-啟動容器

docker run --name hab0 --hostname hab0 -d -P -p 50070:50070 -p 8088:8088 pro/hbase
docker run --name hab1 --hostname hab1 -d -P pro/hbase
docker run --name hab2 --hostname hab2 -d -P pro/hbase

 

  3-安裝bridge-utils 和pipework

  bridge-utils用來管理網橋,pipework可以用來給docker容器設定固定IP

yum -y install bridge-utils
unzip pipework-master.zip
mv pipework-master pipework
cp -rp pipework/pipework /usr/local/bin/

  4-設定容器IP

pipework docker0 hab0 172.17.0.20/24
pipework docker0 hab1 172.17.0.21/24
pipework dcoker0 hab2 172.17.0.22/24 

 五:安裝Zookeeper

  1-進入hab0/hab1/hab2 並配置免密登陸

docker exec -it hab0 /bin/bash

  hab0/1/2都需要新增如下hosts

 vi /etc/hosts
172.17.0.20 hab0
172.17.0.21 hab1
172.17.0.22 hab2
在hab0上執行如下操作
    cd  ~
    mkdir .ssh
    cd .ssh
    ssh-keygen -t rsa(一直按回車即可)
    ssh-copy-id -i localhost
    ssh-copy-id -i hab0
    ssh-copy-id -i hab1
    ssh-copy-id -i hab2
 在hab1上執行下面操作
    cd  ~
    cd .ssh
    ssh-keygen -t rsa(一直按回車即可)
    ssh-copy-id -i localhost
    ssh-copy-id -i hab1
 在hab2上執行下面操作
    cd  ~
    cd .ssh
    ssh-keygen -t rsa(一直按回車即可)
    ssh-copy-id -i localhost
    ssh-copy-id -i hab2

  2-修改zookeeper檔案

/usr/local/zookeeper-3.4.12/conf
cp zoo_sample.cfg zoo.cfg

  vi zoo.cfg 在檔案末尾追加

dataDir=/home/hadoop/zookeeper-3.4.12/data/zkData
//在最後新增,指定zookeeper叢集主機及埠,機器數必須為奇數
server.1=hab0:2888:3888
server.2=hab1:2888:3888
server.3=hab2:2888:3888

  3-建立data/zkData目錄,並創經myid. 待會兒同步配置後需要修改三個節點的myid的值。

//在zookeeper根目錄下建立zoo.cfg中配置的目錄
mkdir data/zkData/ -p

//建立並編輯檔案
vi myid

//輸入1,即表示當前機器為在zoo.cfg中指定的server.1
1

//儲存退出
:wq

  4-拷貝zookeeper到其他節點

  上述操作是在hab0機器上進行的,要將zookeeper拷貝到其他zookeeper叢集機器上:

  叢集中各元件的安裝目錄最好保持一致。

cd /usr/local
scp -r zookeeper-3.4.12/ hab1:/usr/local
scp -r zookeeper-3.4.12/ hab2:/usr/local

  5-修改hab1 和hab2的myid

  myid檔案是作為當前機器在zookeeper叢集的標識,這些標識在zoo.cfg檔案中已經配置好了,但是之前在hab0這臺機器上配置的myid為1,所以還需要修改其他機器的myid檔案:

//在hab1機器上
echo 2 > /usr/local/zookeeper-3.4.12/data/zkData/myid
//在hab2機器上
echo 3 > /usr/local/zookeeper-3.4.12/data/zkData/myid

  6-啟動zookeeper叢集

cd zookeeper-3.4.12/bin/

//分別在hab0、hab1、hab2上啟動
./zkServer.sh start

//檢視狀態
./zkServer.sh status

三臺機器的zookeeper狀態必須只有一個leader,其他都是follower。
//檢視程序,若有QuorumpeerMain,則啟動成功
jps

 六:安裝並啟動hadoop的ha叢集

  1-修改hadoop 5大配置檔案

  進入hadoop配置目錄

cd /usr/local/hadoop-2.6.5/etc/hadoop

  vi hadoop-env.sh

JAVA_HOME=/usr/local/jdk1.8

  vi core-site.xml

<configuration>
  <!-- hdfs地址,ha模式中是連線到nameservice  -->
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://junode</value>
  </property>
  <!-- 這裡的路徑預設是NameNode、DataNode、JournalNode等存放資料的公共目錄,也可以單獨指定 -->
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/usr/local/hadoop-2.6.5/tmp</value>
  </property>

  <!-- 指定ZooKeeper叢集的地址和埠。注意,數量一定是奇數,且不少於三個節點-->
  <property>
    <name>ha.zookeeper.quorum</name>
    <value>hab0:2181,hab1:2181,hab2:2181</value>
  </property>
</configuration>

  vi hdfs-site.xml

<configuration>
  <!-- 指定副本數,不能超過機器節點數  -->
  <property>
    <name>dfs.replication</name>
    <value>3</value>
  </property>

  <!-- 為namenode叢集定義一個services name -->
  <property>
    <name>dfs.nameservices</name>
    <value>junode</value>
  </property>

  <!-- nameservice 包含哪些namenode,為各個namenode起名 -->
  <property>
    <name>dfs.ha.namenodes.junode</name>
    <value>hab0,hab1</value>
  </property>

  <!-- hab0的namenode的rpc地址和埠號,rpc用來和datanode通訊 -->
  <property>
    <name>dfs.namenode.rpc-address.junode.hab0</name>
    <value>hab0:9000</value>
  </property>

  <!---hab1的namenode的rpc地址和埠號,rpc用來和datanode通訊 -->
  <property>
    <name>dfs.namenode.rpc-address.junode.hab1</name>
    <value>hab1:9000</value>
  </property>

  <!--hab0的namenode的http地址和埠號,用來和web客戶端通訊 -->
  <property>
    <name>dfs.namenode.http-address.junode.hab0</name>
    <value>hab0:50070</value>
  </property>

  <!-- hab1的namenode的http地址和埠號,用來和web客戶端通訊 -->
  <property>
    <name>dfs.namenode.http-address.junode.hab1</name>
    <value>hab1:50070</value>
  </property>
  
  <!-- namenode間用於共享編輯日誌的journal節點列表 -->
  <property>
    <name>dfs.namenode.shared.edits.dir</name>
    <value>qjournal://hab0:8485;hab1:8485;hab2:8485/junode</value>
  </property>

  <!-- 指定該叢集出現故障時,是否自動切換到另一臺namenode -->
  <property>
    <name>dfs.ha.automatic-failover.enabled.junode</name>
    <value>true</value>
  </property>

  <!-- journalnode 上用於存放edits日誌的目錄 -->
  <property>
    <name>dfs.journalnode.edits.dir</name>
    <value>/usr/local/hadoop-2.6.5/tmp/data/dfs/journalnode</value>
  </property>

  <!-- 客戶端連線可用狀態的NameNode所用的代理類 -->
  <property>
    <name>dfs.client.failover.proxy.provider.junode</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
  </property>
  <!-- 一旦需要NameNode切換,使用ssh方式進行操作 -->
  <property>
    <name>dfs.ha.fencing.methods</name>
    <value>sshfence</value>
  </property>

  <!-- 如果使用ssh進行故障切換,使用ssh通訊時用的金鑰儲存的位置 -->
  <property>
    <name>dfs.ha.fencing.ssh.private-key-files</name>
    <value>/root/.ssh/id_rsa</value>
  </property>
  <!-- connect-timeout超時時間 -->
  <property>
    <name>dfs.ha.fencing.ssh.connect-timeout</name>
    <value>30000</value>
  </property>
</configuration>

   vi mapred-site.xml

<!-- 採用yarn作為mapreduce的資源排程框架 -->
<configuration>
  <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
  </property>
</configuration>

  vi yarn-site.xml

<configuration>

  <!-- 啟用HA高可用性 -->
  <property>
    <name>yarn.resourcemanager.ha.enabled</name>
    <value>true</value>
  </property>

  <!-- 指定resourcemanager的名字 -->
  <property>
    <name>yarn.resourcemanager.cluster-id</name>
    <value>yrc</value>
  </property>

  <!-- 使用了2個resourcemanager,分別指定Resourcemanager的地址 -->
  <property>
    <name>yarn.resourcemanager.ha.rm-ids</name>
    <value>rm1,rm2</value>
  </property>
  
  <!-- 指定rm1的地址 -->
  <property>
    <name>yarn.resourcemanager.hostname.rm1</name>
    <value>hab0</value>
  </property>
  
  <!-- 指定rm2的地址  -->
  <property>
    <name>yarn.resourcemanager.hostname.rm2</name>
    <value>hab1</value>
  </property>
  
  <!-- 指定當前機器hab0作為rm1 -->
  <property>
    <name>yarn.resourcemanager.ha.id</name>
    <value>rm1</value>
  </property>
  
  <!-- 指定zookeeper叢集機器 -->
  <property>
    <name>yarn.resourcemanager.zk-address</name>
    <value>hab0:2181,hab1:2181,hab2:2181</value>
  </property>
  
  <!-- NodeManager上執行的附屬服務,預設是mapreduce_shuffle -->
  <property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
  </property>

</configuration>

  vi slaves

hab0
hab1
hab2

  2-拷貝hadoop目錄到其他節點

scp -r hadoop-2.6.5 hab1:/usr/local
scp -r hadoop-2.6.5 hab2:/usr/local

  3-修改hab1的yarn-site.xml

  在hab1機器,即ResourceManager備用主節點上修改如下屬性,表示當前機器作為rm2::

<property>
    <name>yarn.resourcemanager.ha.id</name>
    <value>rm2</value>
  </property>

  同時刪除hab2節點上的該屬性對,因為hab2機器並不作為ResourceManager。

  3-啟動hadoop

  啟動Journalnode

cd hadoop-2.6.5/sbin/

./hadoop-daemon.sh start 

//檢視程序JouralNode是否啟動
jps

  4-格式化 NameNode和ZKFC

  在hab0機器上,執行格式化操作:

cd hadoop-2.6.5/bin

./hdfs namenode -format

./hdfs zkfc -formatZK

../sbin/hadoop-daemon.sh start namenode

  5-備用主節點同步主節點元資料

  在hab1(備用主節點)機器上,執行同步操作:

cd hadoop-2.6.5/bin

./hdfs namenode -bootstrapStandby

  6-安裝fuster

  若伺服器是最小化安裝centeros時,有可能系統沒有fuster程式,那麼跳過這個安裝步驟直接進行後面的操作時,將有可能出現以下問題:

hab0作為主節點時,kill掉hab0上的NameNode和ResourceManager程序時,可以實現故障轉移,hab1將從stanby狀態自動變成active狀態;但是當hab1作為主節點時,
若kill掉hab1上的程序,hab0上的程序狀態卻還是stanby,並不能實現故障自動轉移。原因是我們在 hdfs-site.xml中配置了當叢集需要故障自動轉移時採用SSH方式進行,
而因為缺少fuster程式,將在zkfc的日誌檔案中發現如下錯誤:
PATH=$PATH:/sbin:/usr/sbin fuser -v -k -n tcp 9000 via ssh: bash: fuser: 未找到命令
Unable to fence service by any configured method
java.lang.RuntimeException: Unable to fence NameNode at master
hab1/172.17.0.21:9000

  在hab0/hab1/hab2上執行

sudo yum install psmisc

  7-啟動HDFS、YARN、ZookeeperFailoverController

  在hab0上

cd hadoop-2.6.5/sbin

./start-dfs.sh

//驗證,顯示NameNode和DataNode
jps

./start-yarn.sh

//驗證,顯示ResourceManager和NodeManager
jps

./hadoop-daemon.sh start zkfc

//驗證,顯示ZookeeperFailoverController
jps

  在hab1機器上,啟動ResourceManager,備用主節點的ResourceManager需要手動啟動:

cd hadoop-2.6.5/sbin

yarn-daemon.sh start resourcemanager

  檢視hab0 Namenode、ResourceManager狀態

hdfs haadmin -getServiceState hab0
yarn rmadmin -getServiceState rm1 

hdfs haadmin -getServiceState hab1
yarn rmadmin -getServiceState rm2

  也可以通過Web介面來檢視,瀏覽器中輸入 ip:50070 檢視HDFS,輸入 ip:8088/cluster/cluster 檢視YARN。

  8-測試高可用

  a.主節點--->備用主節點

  kill掉主節點的namenode,檢視備用主節點的namenode狀態是否切換為active;

  kill掉主節點的ResourceManager,檢視備用主節點的ResourceManager是否切換為active;

  b.備用主節點--->主節點

  若上述操作執行成功,那麼再測試反向故障自動轉移

  先啟動被殺死的原主節點的namenode和ResourceManager

  hadoop-daemon.sh start namenode 

  yarn-daemon.sh start resourcemanager

  再kill備用主節點的namenode和ResourceManager,檢視主節點的狀態,若能切換為active,那麼Hadoop HA高可用叢集搭建完成。

  

  補充當前三臺機器網元啟動狀態

  

hab0

[[email protected] sbin]# jps

5794 DataNode
5186 JournalNode
2835 ResourceManager
3219 DFSZKFailoverController
38 QuorumPeerMain
7274 Jps
5483 NameNode
3694 HRegionServer
2943 NodeManager
[[email protected] logs]# jps
2258 NameNode
2403 JournalNode
1333 NodeManager
1765 HRegionServer
2684 DataNode
3262 Jps
30 QuorumPeerMain
1487 ResourceManager
[[email protected] ~]#jps

1891 Jps
1496 JournalNode
249 QuorumPeerMain
1129 HRegionServer
1596 DataNode
959 NodeManager

七:在ha的hadoop叢集上搭建Hbase

  1-修改hbase配置

進入hbase-1.3.2.1//conf/目錄,修改配置檔案:
cd /usr/local/hbase-1.3.2.1/conf/

  建立pid目錄

mkdir -p /usr/local/hbase-1.3.2.1/data/hbase/pids

  vi hbase-env.sh

//配置JDK
export JAVA_HOME=/usr/local/jdk1.8

//儲存pid檔案
export HBASE_PID_DIR=/usr/local/hbase-1.3.2.1/data/hbase/pids

//修改HBASE_MANAGES_ZK,禁用HBase自帶的Zookeeper,因為我們是使用獨立的Zookeeper
export HBASE_MANAGES_ZK=false

  vi hbase-site.xml

<configuration>
  <!-- 設定HRegionServers共享目錄,請加上埠號 -->
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://junode/hbase</value>
  </property>

  <!-- 指定HMaster主機 -->
  <property>
    <name>hbase.master</name>
    <value>hdfs://hab0:60000</value>
  </property>

  <!-- 啟用分散式模式 -->
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
  </property>

  <!-- 指定Zookeeper叢集位置 -->
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>hab0:2181,hab1:2181,hab2:2181</value>
  </property>

  <!-- 指定獨立Zookeeper安裝路徑 -->
  <property>
    <name>hbase.zookeeper.property.dataDir</name>
    <value>/usr/local/zookeeper-3.4.12</value>
  </property>

  <!-- 指定ZooKeeper叢集埠 -->
  <property>
    <name>hbase.zookeeper.property.clientPort</name>
    <value>2181</value>
  </property>
</configuration>

  vi regionservers

  修改regionservers檔案,因為當前是使用獨立的Zookeeper叢集,所以要指定RegionServers所在機器:

hab0
hab1
hab2

  2-拷貝hbase到其他節點

scp -r hbase-1.3.2.1 hab1:/usr/local
scp -r hbase-1.3.2.1 hab2:/usr/local

  3-在主節點上啟動HBase(這裡的主節點是指NameNode狀態為active的節點)

cd hbase-1.3.2.1/bin

./start-hbase.sh

//檢視HMaster、Regionserver程序是否啟動
jps
注意:此時Hadoop叢集應處於啟動狀態,並且是在主節點執行start-hbase.sh啟動HBase叢集,否則HMaster程序將在啟動幾秒後消失,而備用的HMaster程序需要在備用主節點單獨啟動,命令是:./hbase-daemon.sh start master。
備用節點啟動hmaster
cd hbase-1.3.2.1/bin
./hbase-daemon.sh start master

  4-Hbase高可用測試

  在瀏覽器中輸入 ip:16010 ,檢視主節點和備用主節點上的HMaster的狀態,在備用主節點的web介面中,可以看到“Current Active Master: master188”,表示當前HBase主節點是master188機器;
  主節點--->備用主節點

    這裡的主節點指使用start-hbase.sh命令啟動HBase叢集的機器

  kill掉主節點的HMaster程序,在瀏覽器中檢視備用主節點的HBase是否切換為active;

  若上述操作成功,則在主節點啟動被殺死的HMaster程序:

  cd hbase-1.3.2.1/bin/

  ./hbase-daemon.sh start master

  然後,kill掉備用主節點的HMaster程序,在瀏覽器中檢視主節點的HBase是否切換為active,若操作成功,則HBase高可用叢集搭建完成;

  5-Hbase基本操作

//啟動HBase
[[email protected] ~] start-hbase.sh

//進入HBase Shell
[[email protected] ~] hbase shell

//檢視當前HBase有哪些表
hbase(main):> list

//建立表t_user,cf1和cf2是列族,列族一般不超過3個
hbase(main):> create 't_user','cf1','cf2'

//獲得表t_user的描述資訊
hbase(main):> describe 't_user'

//禁用表
hbase(main):> disable 't_user'

//刪除表,刪除表之前要先把表禁用掉
hbase(main):> drop 't_user'

//查詢表是否存在
hbase(main):> exists 't_user'

//檢視全表資料
hbase(main):> scan 't_user'

//插入資料,分別是表名、key、列(列族:具體列)、值。HBase是面向列的資料庫,列可無限擴充
hbase(main):> put 't_user' ,'001','cf1:name','chenxj'
hbase(main):> put 't_user' ,'001','cf1:age','18'
hbase(main):> put 't_user' ,'001','cf2:sex','man'
hbase(main):> put 't_user' ,'002','cf1:name','chenxj'
hbase(main):> put 't_user' ,'002','cf1:address','fuzhou'
hbase(main):> put 't_user' ,'002','cf2:sex','man'

//獲取資料,可根據key、key和列族等進行查詢
hbase(main):> get 't_user','001'
hbase(main):> get 't_user','002','cf1'
hbase(main):> get 't_user','001','cf1:age'