はじめに
Hiveについて、独立したホストでクラスタ化(repmgr + keepalived利用)してみました。
前提として、以下手順に従いHadoopクラスタを構築してること。
動作確認用にzeppelinも構築していること。
構成概要
Hadoop クラスタ
master1 : ZooKeeper / JournalNode / NameNode(nn1) / ZKFC
JobHistoryServer / ATSv2 / Hive / PostgreSQL
master2 : ZooKeeper / JournalNode / NameNode(nn2) / ZKFC
ResourceManager(rm1)
master3 : ZooKeeper / JournalNode
ResourceManager(rm2)
worker1 : DataNode / NodeManager
worker2 : DataNode / NodeManager
zeppelin1 : zeppelin
上記ZookeeeperをHiveServer2クラスタで利用。
master1のHive&PostgreSQLは下記ホスト、Hive稼働できたらサービス停止してよい。
追加ホスト
hive1 : HiveServer2 + Hive Metastore
hive2 : HiveServer2 + Hive Metastore
hivepg1 : PostgreSQL Primary + repmgr + keepalived
hivepg2 : PostgreSQL Standby + repmgr + keepalived
hivepg-vip : PostgreSQL 仮想IP(Keepalived制御)
HA 方針
| コンポーネント | HA方式 |
|---|---|
| HiveServer2 | ZooKeeper Service Discovery |
| Hive Metastore | Active-Active |
| PostgreSQL | Streaming Replication |
| Primary 切替 | repmgrd |
| postgresql接続先 | VIP (Keepalived) |
| ZooKeeper | Hadoop 既存を流用 |
前提 IP(例)
192.168.11.54 hive1
192.168.11.55 hive2
192.168.11.56 hivepg1
192.168.11.57 hivepg2
192.168.11.58 hivepg-vip
※適宜読み替えてください
1. 全ノード共通設定(新規ホスト)
全ホストの名前解決を行えるようにする。
以下のコマンドでBigTop APT リポジトリ追加すること。
こちらについてはhivepg1/hivepg2では実施しなくてよい。
sudo tee /etc/apt/sources.list.d/bigtop.list << 'EOF'
deb [trusted=yes] http://repos.bigtop.apache.org/releases/3.3.0/ubuntu/22.04/amd64 bigtop contrib
EOF
sudo apt update
2. PostgreSQL HA 構築
2-1. パッケージインストール(hivepg1 / hivepg2)
sudo apt update
sudo apt install -y postgresql postgresql-contrib repmgr keepalived
2-2. PostgreSQL Primary 初期設定(hivepg1)
ユーザー / DB 作成
sudo -u postgres psql << 'EOF'
-- ===== ロール作成 =====
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'repl') THEN
CREATE ROLE repl WITH REPLICATION LOGIN PASSWORD 'replpass';
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'repmgr') THEN
CREATE ROLE repmgr WITH LOGIN SUPERUSER PASSWORD 'repmgrpass';
END IF;
END
$$;
-- postgres パスワード設定
ALTER USER postgres PASSWORD 'postgrespass';
-- ===== DB 作成 =====
CREATE DATABASE repmgr OWNER repmgr;
-- ===== repmgr DB に接続 =====
\connect repmgr
-- repmgr 拡張
CREATE EXTENSION IF NOT EXISTS repmgr;
-- 確認
SELECT extname FROM pg_extension WHERE extname = 'repmgr';
\dt repmgr.*
EOFsudo -u postgres psql -d repmgr -c "\dt repmgr.*"
→repmgrがあること。
postgresql.conf
sudo tee -a /etc/postgresql/16/main/postgresql.conf << 'EOF'
listen_addresses = '*'
wal_level = replica
max_wal_senders = 10
max_replication_slots = 10
hot_standby = on
wal_keep_size = 1024MB
EOF
pg_hba.conf
sudo tee -a /etc/postgresql/16/main/pg_hba.conf << 'EOF'
# replication
host replication repl 192.168.11.57/32 md5
host replication repmgr 192.168.11.57/32 md5
# repmgr
host repmgr repmgr 192.168.11.56/32 md5
host repmgr repmgr 192.168.11.57/32 md5
# allow repmgr standby clone (postgres -> repmgr) from hivepg2
host repmgr postgres 192.168.11.57/32 scram-sha-256
EOF
設定の有効化
sudo systemctl restart postgresql
2-3. PostgreSQL Primary 初期設定(hivepg2)
postgresql.conf
sudo tee -a /etc/postgresql/16/main/postgresql.conf << 'EOF'
listen_addresses = '*'
wal_level = replica
max_wal_senders = 10
max_replication_slots = 10
hot_standby = on
wal_keep_size = 1024MB
EOF
pg_hba.conf
sudo tee -a /etc/postgresql/16/main/pg_hba.conf << 'EOF'
# replication
host replication repl 192.168.11.56/32 md5
host replication repmgr 192.168.11.56/32 md5
# repmgr
host repmgr repmgr 192.168.11.56/32 md5
host repmgr repmgr 192.168.11.57/32 md5
# allow repmgr standby clone (postgres -> repmgr) from hivepg2
host repmgr postgres 192.168.11.56/32 scram-sha-256
EOF
設定の有効化
sudo systemctl restart postgresql
2-4. repmgr 設定
2-4-1. hivepg1(Primary)
regmgr設定
sudo tee /etc/repmgr.conf << 'EOF'
node_id=1
node_name=hivepg1
conninfo='host=192.168.11.56 user=repmgr password=repmgrpass dbname=repmgr'
data_directory='/var/lib/postgresql/16/main'
use_replication_slots=yes
failover=automatic
promote_command='repmgr standby promote -f /etc/repmgr.conf'
follow_command='repmgr standby follow -f /etc/repmgr.conf'
ssh_options='-o StrictHostKeyChecking=accept-new'
service_start_command = 'sudo systemctl start postgresql'
service_stop_command = 'sudo systemctl stop postgresql'
service_restart_command = 'sudo systemctl restart postgresql'
service_reload_command = 'sudo systemctl reload postgresql'
EOF
regmgr登録(primary)
sudo -u postgres repmgr primary register -f /etc/repmgr.conf
ノード間認証設定
sudo -u postgres tee ~postgres/.pgpass > /dev/null <<'EOF'
hivepg2:5432:*:postgres:postgrespass
hivepg2:5432:*:repmgr:repmgrpass
hivepg2:5432:*:repl:replpass
192.168.11.57:5432:*:repmgr:repmgrpass
EOF
sudo -u postgres chmod 600 ~postgres/.pgpass
2-4-2. hivepg2(Standby)
regmgr設定
sudo tee /etc/repmgr.conf <<'EOF'
node_id=2
node_name=hivepg2
conninfo='host=192.168.11.57 user=repmgr password=repmgrpass dbname=repmgr connect_timeout=2'
data_directory='/var/lib/postgresql/16/main'
use_replication_slots=yes
monitoring_history=yes
failover=automatic
promote_command='repmgr standby promote -f /etc/repmgr.conf --log-to-file'
follow_command='repmgr standby follow -f /etc/repmgr.conf --log-to-file'
ssh_options='-o StrictHostKeyChecking=accept-new'
service_start_command = 'sudo systemctl start postgresql'
service_stop_command = 'sudo systemctl stop postgresql'
service_restart_command = 'sudo systemctl restart postgresql'
service_reload_command = 'sudo systemctl reload postgresql'
EOF
ノード間認証設定
sudo -u postgres tee ~postgres/.pgpass > /dev/null <<'EOF'
hivepg1:5432:*:postgres:postgrespass
hivepg1:5432:*:repmgr:repmgrpass
hivepg1:5432:*:repl:replpass
192.168.11.56:5432:*:repmgr:repmgrpass
EOF
sudo -u postgres chmod 600 ~postgres/.pgpass
ActiveからStandbyへのデータクローン
sudo systemctl stop postgresql
sudo -u postgres repmgr standby clone -h hivepg1 -d repmgr -f /etc/repmgr.conf --force
sudo systemctl start postgresql
regmgr登録(standby)
sudo -u postgres repmgr standby register -f /etc/repmgr.conf
2-5. repmgrdサービス作成(hivepg1/hivepg2)
sudo sed -i 's/^[# ]*shared_preload_libraries.*/shared_preload_libraries = '\''repmgr'\''/' /etc/postgresql/16/main/postgresql.conf
sudo systemctl restart postgresql
sudo tee /etc/systemd/system/repmgrd.service > /dev/null <<'EOF'
[Unit]
Description=repmgr daemon
After=network-online.target postgresql.service
Wants=network-online.target
[Service]
Type=simple
User=postgres
Group=postgres
Environment=PGPASSFILE=/var/lib/postgresql/.pgpass
ExecStart=/usr/bin/repmgrd -f /etc/repmgr.conf --daemonize=false
Restart=always
RestartSec=3
TimeoutStartSec=60
TimeoutStopSec=30
KillMode=process
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl disable repmgrd 2>/dev/null || true
sudo systemctl stop repmgrd 2>/dev/null || true
sudo systemctl enable --now repmgrd
確認
ps -ef | grep -E '[r]epmgrd'
→プロセスが見えること。
確認:
repmgr cluster show
以下の結果となること。
hivepg1 = Role:primary status: running
hivepg2 = Role:standby status: running
2-6. VIP 制御(Keepalived)
Primary 判定スクリプト(両ノード)
sudo tee /usr/local/bin/is_primary.sh << 'EOF'
#!/bin/bash
pg_isready -q || exit 1
sudo -u postgres psql -qtAX -c "select not pg_is_in_recovery();" | grep -q t
EOF
sudo chmod +x /usr/local/bin/is_primary.sh
sudo 許可:
sudo update-alternatives --config editor
→/usr/bin/vim.basicを選択する。
sudo visudo
以下を追記
keepalived ALL=(postgres) NOPASSWD: /usr/bin/psql
keepalived.conf(hivepg1)
sudo tee /etc/keepalived/keepalived.conf << 'EOF'
vrrp_script chk_primary {
script "/usr/local/bin/is_primary.sh"
interval 2
}
vrrp_instance VI_PG {
state MASTER
interface eth0
virtual_router_id 70
priority 200
authentication {
auth_type PASS
auth_pass HivePgVIP
}
virtual_ipaddress {
192.168.11.58/24
}
track_script {
chk_primary
}
}
EOF
keepalived.conf(hivepg2)
sudo tee /etc/keepalived/keepalived.conf << 'EOF'
vrrp_script chk_primary {
script "/usr/local/bin/is_primary.sh"
interval 2
}
vrrp_instance VI_PG {
state BACKUP
interface eth0
virtual_router_id 70
priority 150
authentication {
auth_type PASS
auth_pass HivePgVIP
}
virtual_ipaddress {
192.168.11.58/24
}
track_script {
chk_primary
}
}
EOF
keepalived起動(hivepg1/hivepg2)
sudo systemctl enable --now keepalived
確認(hivepg1で実施):
ip a
VIPがリストに出ること。
2-7 SSH鍵交換(hivepg1/hivepg2)
sudo -u postgres bash -lc 'test -f ~/.ssh/id_ed25519 || ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519'
sudo -u postgres cat /var/lib/postgresql/.ssh/id_ed25519.pub
それぞれの公開鍵を控える。
sudo -u postgres touch /var/lib/postgresql/.ssh/authorized_keys
sudo -u postgres chmod 600 /var/lib/postgresql/.ssh/authorized_keys
sudo -u postgres vi /var/lib/postgresql/.ssh/authorized_keys
1,2でそれぞれ交換で書き込む。
hivepg1:
sudo -u postgres ssh postgres@hivepg2 'hostname'
hivepg2:
sudo -u postgres ssh postgres@hivepg1 'hostname'
→yesを入力し、以下の回答が出てくること。
hivepg1実施:
hivepg2
hivepg2実施:
hivepg1
2-8. postgresユーザーのsystemctl実行許可設定(hivepg1/hivepg2)
sudo tee /etc/sudoers.d/repmgr-postgresql <<'EOF'
postgres ALL=NOPASSWD: /bin/systemctl start postgresql, /bin/systemctl stop postgresql, /bin/systemctl restart postgresql, /bin/systemctl reload postgresql
EOF
sudo chmod 440 /etc/sudoers.d/repmgr-postgresql
3. Hive(hive1 / hive2)
3-1. インストール
sudo apt install -y hive hive-metastore hive-server2
sudo apt install -y openjdk-8-jdk
3-2. hadoop ユーザー作成
sudo useradd -m -g hadoop -s /bin/bash hadoop
3-3. Hadoop 設定作成
sudo tee /etc/hadoop/conf/core-site.xml << 'EOF'
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://cluster1</value>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>master1:2181,master2:2181,master3:2181</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/var/lib/hadoop/tmp</value>
</property>
</configuration>
EOF
sudo tee /etc/hadoop/conf/hdfs-site.xml << 'EOF'
<configuration>
<property>
<name>dfs.nameservices</name>
<value>cluster1</value>
</property>
<property>
<name>dfs.ha.namenodes.cluster1</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.cluster1.nn1</name>
<value>master1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.cluster1.nn2</name>
<value>master2:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.cluster1.nn1</name>
<value>master1:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.cluster1.nn2</name>
<value>master2:9870</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///var/lib/hadoop-hdfs/namenode</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///var/lib/hadoop-hdfs/datanode</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://master1:8485;master2:8485;master3:8485/cluster1</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/var/lib/hadoop-hdfs/journalnode</value>
</property>
<property>
<name>dfs.client.failover.proxy.provider.cluster1</name>
<value>
org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_rsa</value>
</property>
</configuration>
EOF
sudo tee /etc/hadoop/conf/yarn-site.xml << 'EOF'
<configuration>
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>ycluster</value>
</property>
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>master2</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>master3</value>
</property>
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>master1:2181,master2:2181,master3:2181</value>
</property>
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>512</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>128</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>256</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.timeline-service.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.timeline-service.version</name>
<value>2.0</value>
</property>
<property>
<name>yarn.timeline-service.fs-writer.root-dir</name>
<value>/atsv2</value>
</property>
<property>
<name>yarn.timeline-service.reader.webapp.address</name>
<value>master1:8188</value>
</property>
<property>
<name>yarn.webapp.ui2.enable</name>
<value>true</value>
</property>
<property>
<name>yarn.log.server.url</name>
<value>http://master1:19888/jobhistory/logs</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>master2:8088</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>master3:8088</value>
</property>
</configuration>
EOF
sudo tee /etc/hadoop/conf/mapred-site.xml << 'EOF'
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_COMMON_HOME=/usr/lib/hadoop,HADOOP_HDFS_HOME=/usr/lib/hadoop-hdfs,HADOOP_MAPRED_HOME=/usr/lib/hadoop-mapreduce</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_COMMON_HOME=/usr/lib/hadoop,HADOOP_HDFS_HOME=/usr/lib/hadoop-hdfs,HADOOP_MAPRED_HOME=/usr/lib/hadoop-mapreduce</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_COMMON_HOME=/usr/lib/hadoop,HADOOP_HDFS_HOME=/usr/lib/hadoop-hdfs,HADOOP_MAPRED_HOME=/usr/lib/hadoop-mapreduce</value>
</property>
<property>
<name>mapreduce.application.classpath</name>
<value>/etc/hadoop/conf,/etc/hadoop/conf/*,/usr/lib/hadoop/*,/usr/lib/hadoop/lib/*,/usr/lib/hadoop-hdfs/*,/usr/lib/hadoop-hdfs/lib/*,/usr/lib/hadoop-mapreduce/*,/usr/lib/hadoop-mapreduce/lib/*,/usr/lib/hadoop-yarn/*,/usr/lib/hadoop-yarn/lib/*</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>master1:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>master1:19888</value>
</property>
<property>
<name>mapreduce.jobhistory.done-dir</name>
<value>/mr-history/done</value>
</property>
<property>
<name>mapreduce.jobhistory.intermediate-done-dir</name>
<value>/mr-history/tmp</value>
</property>
<property>
<name>yarn.app.mapreduce.am.command-opts</name>
<value>-Dlog4j.configuration=file:/etc/hadoop/conf/log4j.properties</value>
</property>
<property>
<name>mapreduce.map.java.opts</name>
<value>-Dlog4j.configuration=file:/etc/hadoop/conf/log4j.properties</value>
</property>
<property>
<name>mapreduce.reduce.java.opts</name>
<value>-Dlog4j.configuration=file:/etc/hadoop/conf/log4j.properties</value>
</property>
<property>
<name>mapreduce.job.am.webapp.address</name>
<value>0.0.0.0:0</value>
</property>
<property>
<name>mapreduce.job.am.webapp.https.address</name>
<value>0.0.0.0:0</value>
</property>
<property>
<name>mapreduce.shuffle.port</name>
<value>13562</value>
</property>
</configuration>
EOF
3-4. hive-site.xml(両ノード共通)
sudo tee /etc/hive/conf/hive-site.xml << 'EOF'
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:postgresql://hivepg-vip:5432/hive_metastore</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>org.postgresql.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hive</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>HivePasswordHere</value>
</property>
<property>
<name>hive.metastore.uris</name>
<value>thrift://hive1:9083,thrift://hive2:9083</value>
</property>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<property>
<name>hive.server2.support.dynamic.service.discovery</name>
<value>true</value>
</property>
<property>
<name>hive.zookeeper.quorum</name>
<value>master1:2181,master2:2181,master3:2181</value>
</property>
<property>
<name>hive.server2.zookeeper.namespace</name>
<value>hiveserver2</value>
</property>
<property>
<name>hive.metastore.client.notification.event.poll.interval</name>
<value>0s</value>
</property>
<property>
<name>hive.metastore.event.db.notification.api.auth</name>
<value>false</value>
</property>
<property>
<name>hive.server2.enable.doAs</name>
<value>false</value>
</property>
</configuration>
EOF
3-5. PostgreSQL JDBC ドライバを Hive に追加
sudo apt install -y libpostgresql-jdbc-java
dpkg -L libpostgresql-jdbc-java | grep -E 'postgresql.*\.jar$'
sudo ln -sf /usr/share/java/postgresql.jar /usr/lib/hive/lib/postgresql.jar
sudo rm -rf /usr/lib/hive/lib/postgresql-9.4.1208.jre7.jar
3-6. hive DB設定
hivepg1で実施。
sudo -u postgres psql <<'SQL'
-- ===== Hive 用 role =====
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'hive') THEN
CREATE ROLE hive LOGIN PASSWORD 'HivePasswordHere';
END IF;
END $$;
CREATE DATABASE hive_metastore OWNER repmgr;
-- DB 接続
\connect hive_metastore
-- ===== 権限(必要十分)=====
-- DB 接続/一時テーブル
GRANT CONNECT, TEMP ON DATABASE hive_metastore TO hive;
-- public スキーマの所有者を hive に(Hive がテーブル作るため)
ALTER SCHEMA public OWNER TO hive;
GRANT USAGE, CREATE ON SCHEMA public TO hive;
-- 既存オブジェクトにも権限を揃える(再実行・移行時に効く)
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO hive;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO hive;
GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO hive;
-- 今後作られるオブジェクトのデフォルト権限も hive に
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO hive;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO hive;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON FUNCTIONS TO hive;
SQL
hivepg1/hivepg2で実施
sudo tee -a /etc/postgresql/16/main/pg_hba.conf << 'EOF'
# Hive Metastore via VIP
host hive_metastore repmgr 192.168.11.58/32 md5
# Hive Metastore (hive1/hive2) -> PostgreSQL via VIP
host hive_metastore hive 192.168.11.54/32 scram-sha-256
host hive_metastore hive 192.168.11.55/32 scram-sha-256
EOF
3-7. Metastore スキーマ初期化(hive1で1 回のみ)
sudo -u hadoop /usr/lib/hive/bin/schematool -dbType postgres -initSchema
3-8. サービス作成
sudo tee /etc/default/hive <<'EOF'
HIVE_HOME=/usr/lib/hive
HIVE_CONF_DIR=/etc/hive/conf
HADOOP_CONF_DIR=/etc/hadoop/conf
YARN_CONF_DIR=/etc/hadoop/conf
MAPRED_CONF_DIR=/etc/hadoop/conf
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
TERM=dumb
EOF
sudo tee /etc/systemd/system/hive-metastore.service <<'EOF'
[Unit]
Description=Apache Hive Metastore Service
After=network.target
Wants=network.target
After=hadoop-hdfs-namenode.service hadoop-hdfs-datanode.service hadoop-yarn-resourcemanager.service hadoop-yarn-nodemanager.service
Wants=hadoop-hdfs-namenode.service hadoop-hdfs-datanode.service hadoop-yarn-resourcemanager.service hadoop-yarn-nodemanager.service
[Service]
Type=simple
User=hive
Group=hive
EnvironmentFile=-/etc/default/hive
Environment="HIVE_CONF_DIR=/etc/hive/conf"
ExecStart=/usr/lib/hive/bin/hive --service metastore
Restart=on-failure
RestartSec=5
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
EOF
sudo tee /etc/systemd/system/hiveserver2.service <<'EOF'
[Unit]
Description=Apache HiveServer2 Service
After=network.target hive-metastore.service
Wants=network.target hive-metastore.service
[Service]
Type=simple
User=hive
Group=hive
EnvironmentFile=-/etc/default/hive
Environment="HADOOP_CLIENT_OPTS=-Dlog4j2.debug=false"
Environment="HIVE_OPTS=--hiveconf hive.root.logger=INFO,console --hiveconf hive.server2.logging.operation.enabled=true"
Environment="HADOOP_HEAPSIZE=1024"
ExecStartPre=/bin/bash -lc 'for i in {1..30}; do nc -z localhost 9083 && exit 0; sleep 1; done; exit 1'
ExecStart=/usr/lib/hive/bin/hive --service hiveserver2
Restart=on-failure
RestartSec=5
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
EOF
3-9. HDFS 上に Hive warehouse 作成(master1で実施)
既存のHadoopクラスタに対し、以下の設定を実施すること。
sudo su - hadoop
hdfs dfs -mkdir -p /user/hive/warehouse
hdfs dfs -chown -R hive:hive /user/hive
hdfs dfs -chmod 771 /user/hive
hdfs dfs -chmod 771 /user/hive/warehouse
hdfs dfs -chmod -R 1777 /tmp
exit
3-10. 起動(hive1/hive2)
sudo systemctl enable --now hive-metastore hiveserver2
4. 動作確認
4-1. beeline/zeppelin利用確認
それぞれのHive接続で使用するJDBC設定を以下のように変更して、
それぞれ利用できることを確認する。
変更前
'jdbc:hive2://master1:10000/default'
変更後
'jdbc:hive2://master1:2181,master2:2181,master3:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2'
4-2. PostgreSQL フェールオーバ試験
目的:primary を hivepg1 → hivepg2 に自動的にフェールオーバーさせる。
障害注入方法:hivepg1のpostgresqlサービスを停止する。
期待する結果:自動的にhivepg2へ自動的にDBプライマリが切り替わり、外からの接続も実施できること。
hivepg1で実施:
sudo systemctl stop postgresql
hivepg2で実施:
repmgr cluster show
期待状態(数分後)
hivepg1 = Role:primary status: failed
hivepg2 = Role:primary status: running
VIP確認(hivepg2で実施):
ip a
VIPがリストに出ること。
確認:
再度beelineでの接続、zeppelinでのnotebook実行が行えること。
5. PostgreSQL フェイルオーバ試験後の戻し方
目的:primary を hivepg2 → hivepg1 に戻す
リスク:両系でプライマリになるとDBクラスタが壊れる。
→ 対策:hivepg1停止中にhivepg2からの再クローンを実施し、hivepg2のスタンバイ機として立ち上げる。
その後プライマリとスタンバイの切り替えを実施することによりリスク軽減を図る。
5-1. 新 Primary(hivepg2)から再クローン(hivepg1)
sudo -u postgres repmgr standby clone -h hivepg2 -d repmgr -f /etc/repmgr.conf --force
5-2. postgresql起動(hivepg1)
sudo systemctl start postgresql
5-3. hivepg1をStandby として登録(hivepg1)
sudo -u postgres repmgr standby register -f /etc/repmgr.conf --force
repmgr cluster show
以下の状態になること。
hivepg1 = Role:standby status: running
hivepg2 = Role:primary status: running
5-4. hivepg1へのactive切り戻し(hivepg1)
運用中の場合は夜間など使用する人のいないタイミングで対応すること。
- 切り戻し(手動フェールバック)
standbyとなっているホストで以下のコマンド実施
sudo -u postgres repmgr standby switchover \
-f /etc/repmgr.conf \
--siblings-follow
- postgresql HA確認
repmgr cluster show
以下の状態になること。
hivepg1 = Role:primary status: running
hivepg2 = Role:standby status: running
- VIP確認(hivepg1で実施):
ip a
VIPがリストに出ること。
- 再度beelineでの接続、zeppelinでのnotebook実行が行えること。