もなかアイスの試食品

「とりあえずやってみたい」そんな気持ちが先走りすぎて挫折が多い私のメモ書きみたいなものです.

Vagrantを使ったPostgreSQL9.6非同期レプリケーションの環境構築

はじめに

とあるリリース前のサービスの負荷試験をやったときに、将来的にDBを複数台使用するとして、Webアプリケーションをどのように変更したら良いか分からなかった。

WebアプリケーションはSpringBootを使用しており、アプリケーションの機能追加で、DBの負荷分散に対応するようにした。

その時の記事はこれ↓

monakaice88.hatenablog.com

そんな経緯があったので、アプリケーションを改造する前に、AWSでリードレプリカを使用するのを想定して、PostgreSQLで非同期レプリケーション環境が開発環境に欲しかった。

なので、今回はPostgreSQLで非同期レプリケーション環境をVagrantで構築したお話。

目次


参考サイト

以下のサイトを参考にした。

qiita.com


環境

  • CentOS 7
  • PostgreSQL 9.6
    • マスタ側IP:192.168.35.10
    • スレーブ側IP:192.168.35.11


マスタ側の構築スクリプトの作成

マスタ側のプロビジョニングスクリプトを作成する。

マスタ側のプロビジョニングスクリプトは以下の感じ

ファイル名は「create_db_master_server.sh」で保存

# いつものやーつ
sudo yum update -y
sudo yum install vim wget -y

# 時刻を日本にする
sudo cp -p /usr/share/zoneinfo/Japan /etc/localtime

# 時刻を自動で調整するようにする
cp /etc/chrony.conf /etc/chrony.conf_preprovision
sudo sed -i -e "s/server 0.centos.pool.ntp.org iburst/server ntp.nict.jp/g" /etc/chrony.conf
sudo sed -i -e "s/server 1.centos.pool.ntp.org iburst/server ntp1.jst.mfeed.ad.jp/g" /etc/chrony.conf
sudo sed -i -e "s/server 2.centos.pool.ntp.org iburst/server ntp2.jst.mfeed.ad.jp/g" /etc/chrony.conf
sudo sed -i -e "s/server 3.centos.pool.ntp.org iburst/server ntp3.jst.mfeed.ad.jp/g" /etc/chrony.conf
sudo chronyc -a makestep

# PostgreSQLのインストール
sudo rpm -U https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-3.noarch.rpm
sudo yum install -y postgresql96 postgresql96-server

# postgresユーザで「initdb」を実行するため、rootユーザになる
sudo su -
sudo su postgres -c "/usr/pgsql-9.6/bin/initdb /var/lib/pgsql/9.6/data/"

PG_DIR="/var/lib/pgsql/9.6/data/"

sudo su postgres -c "cp ${PG_DIR}postgresql.conf ${PG_DIR}postgresql.conf_preprovision"
# 接続受付IPを変更
sudo sed -i -e "s/#listen_addresses = 'localhost'/listen_addresses = '*'/g" ${PG_DIR}postgresql.conf
# 各ログの設定を変更
# Webアプリの接続先が読み取り用と更新用で分かれるか確認のため、
# 「log_connections」、「log_disconnections 」を有効にする
sudo sed -i -e "s/log_filename = 'postgresql-%a.log'/log_filename = 'postgresql-%m%d.log'/g" ${PG_DIR}postgresql.conf
sudo sed -i -e "s/#log_checkpoints = off/log_checkpoints = on/g" ${PG_DIR}postgresql.conf
sudo sed -i -e "s/#log_connections = off/log_connections = on/g" ${PG_DIR}postgresql.conf
sudo sed -i -e "s/#log_disconnections = off/log_disconnections = on/g" ${PG_DIR}postgresql.conf
sudo sed -i -e "s/#log_lock_waits = off/log_lock_waits = on/g" ${PG_DIR}postgresql.conf
sudo sed -i -e "s/log_timezone = 'UTC'/log_timezone = 'Japan'/g" ${PG_DIR}postgresql.conf

# レプリケーション設定の変更
# https://qiita.com/U_ikki/items/e117acad0413546d6923
sudo sed -i -e "s/#checkpoint_timeout = 5min/checkpoint_timeout = 15min/g" ${PG_DIR}postgresql.conf
sudo sed -i -e "s/#hot_standby = off/hot_standby = on/g" ${PG_DIR}postgresql.conf
sudo sed -i -e "s/#wal_level = minimal/wal_level = replica/g" ${PG_DIR}postgresql.conf
sudo sed -i -e "s/#max_wal_senders = 0/max_wal_senders = 3/g" ${PG_DIR}postgresql.conf

# 接続許可の設定を変更
sudo su postgres -c "cp ${PG_DIR}pg_hba.conf ${PG_DIR}pg_hba.conf_preprovision"
sudo sed -i -e "87i host    replication     postgres        192.168.35.0/24         trust" ${PG_DIR}pg_hba.conf
sudo sed -i -e "88i host    all             all             192.168.35.0/24         md5" ${PG_DIR}pg_hba.conf

# 参照先DNSサーバの変更(今回あまり関係なし)
sudo cp /etc/NetworkManager/NetworkManager.conf /etc/NetworkManager/NetworkManager.conf_preprovision
sudo sed -i -e "26i dns=none" /etc/NetworkManager/NetworkManager.conf
sudo systemctl restart NetworkManager
sudo sed -i -r "s/nameserver [\.0-9]+/nameserver 192.168.35.20/g" /etc/resolv.conf

# 自動起動ON&PostgreSQL起動
sudo systemctl enable postgresql-9.6
sudo systemctl start postgresql-9.6

# アカウントのパスワードを変更するSQLを実行
sudo psql -U postgres sample_db < /vagrant/db/set_password_to_db.sql


スレーブ側の構築スクリプトの作成

スレーブ側のプロビジョニングスクリプトを作成する。

スレーブ側のプロビジョニングスクリプトは以下の感じ

ファイル名は「create_db_slave_server.sh」で保存する。

# いつものやーつ
sudo yum update -y
sudo yum install vim wget -y

# 時刻を日本にする
sudo cp -p /usr/share/zoneinfo/Japan /etc/localtime

# 時刻を自動で調整するようにする
cp /etc/chrony.conf /etc/chrony.conf_preprovision
sudo sed -i -e "s/server 0.centos.pool.ntp.org iburst/server ntp.nict.jp/g" /etc/chrony.conf
sudo sed -i -e "s/server 1.centos.pool.ntp.org iburst/server ntp1.jst.mfeed.ad.jp/g" /etc/chrony.conf
sudo sed -i -e "s/server 2.centos.pool.ntp.org iburst/server ntp2.jst.mfeed.ad.jp/g" /etc/chrony.conf
sudo sed -i -e "s/server 3.centos.pool.ntp.org iburst/server ntp3.jst.mfeed.ad.jp/g" /etc/chrony.conf
sudo chronyc -a makestep


# PostgreSQLのインストール
sudo rpm -U https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-3.noarch.rpm
sudo yum install -y postgresql96 postgresql96-server

# postgresユーザで「pg_basebackup」を実行するため、rootユーザになる
sudo su -
sudo su postgres -c "pg_basebackup -h 192.168.35.10 -D /var/lib/pgsql/9.6/data/ -X stream --progress -U postgres -R"

# 参照先DNSサーバの変更(今回あまり関係なし)
sudo cp /etc/NetworkManager/NetworkManager.conf /etc/NetworkManager/NetworkManager.conf_preprovision
sudo sed -i -e "26i dns=none" /etc/NetworkManager/NetworkManager.conf
sudo systemctl restart NetworkManager
sudo sed -i -r "s/nameserver [\.0-9]+/nameserver 192.168.35.20/g" /etc/resolv.conf

# 自動起動ON&PostgreSQL起動
sudo systemctl enable postgresql-9.6
sudo systemctl start postgresql-9.6


仮想マシンの設定ファイルの作成

仮想マシンのCPU数・メモリサイズを定義する設定ファイルを用意する。

設定ファイル名は「vmconf.yml」で保存

# 仮想マシンのスペック設定
vm:
  # DBサーバ(マスター・スレーブ共通)
  db:
    cpus: 2
    memory: 1024

マスター・スレーブ両方同じ設定を使用

今回はCPUコア数2個、メモリサイズ1GBに設定


Vagrantファイルの作成

# -*- mode: ruby -*-
# vi: set ft=ruby :

require 'yaml'
settings = YAML.load_file 'vmconf.yml'

Vagrant.configure("2") do |config|

  config.vm.box = "centos/7"

  # postgresql マスターサーバ
  config.vm.define :db_master do |define|
    define.vm.hostname = "db-master"
    define.vm.provision "db-master", type: "shell", :path => "create_db_master_server.sh", :privileged => false
    define.vm.network "forwarded_port", guest: 5432, host: 5432
    define.vm.network "private_network", ip: "192.168.35.10"
    define.vm.provider "virtualbox" do |provider|
      provider.name = "db-master"
      provider.cpus = settings['vm']['db']['cpus']
      provider.memory = settings['vm']['db']['memory']
    end
  end

  # postgresql スレーブサーバ
  config.vm.define :db_slave do |define|
    define.vm.hostname = "db-slave"
    define.vm.provision "db-slave", type: "shell", :path => "create_db_slave_server.sh", :privileged => false
    define.vm.network "forwarded_port", guest: 5432, host: 55432
    define.vm.network "private_network", ip: "192.168.35.11"
    define.vm.provider "virtualbox" do |provider|
      provider.name = "db-slave"
      provider.cpus = settings['vm']['db']['cpus']
      provider.memory = settings['vm']['db']['memory']
    end
  end

end


おわりに

レプリケーション構成のPostgreSQLを開発環境に構築することができ、この環境をもとにアプリケーションの改造が出来た。

AWSの運用環境を想定して、DNSサーバも構築したので、このことについてもいつか書きたい・・・