Redis Cluster でマスタ・スレーブのクラスタ構成を構築してみた

Redis 3.0 から正式に追加された機能である Redis Cluster を使って、同一サーバ内で、マスタが 3 インスタンス、スレーブが 3 インスタンスクラスタ構成を構築してみました。

図にするとこちらのような構成です。

f:id:enomotodev:20170602213336p:plain

作業環境

Redis をインストールする

今回は全て root で作業を行ったので、root に変更します。

$ sudo su -

あとで redis-trib.rb を使って、クラスタ構成とレプリケーションを設定するので、Ruby などのパッケージをインストールしておきます

# yum install ruby
# ruby --version
ruby 2.0.0p648 (2015-12-16) [x86_64-linux]
# gem install redis

次に、Redis をソースからインストールします。

# wget http://download.redis.io/releases/redis-3.2.9.tar.gz
# tar xzf redis-3.2.9.tar.gz
# cd redis-3.2.9
# make
# make install

これで Redis のインストールは完了したのでバージョンを確認します。

# redis-server --version
Redis server v=3.2.9 sha=00000000:0 malloc=jemalloc-4.0.3 bits=64 build=ccbe915be5386293

マスタ・スレーブのクラスタ構成を構築する

今回は下の図のように1つのサーバでポートを分けて Redis を起動させてクラスタ構成を構築していきたいと思います。

f:id:enomotodev:20170602214131p:plain

まずは、それぞれのポート用の conf ファイルを作成し、それを元に Redis を起動させます。

# mkdir -p /opt/redis-cluster/700{0..5}
# cat <<EOS > redis.conf
port 7000
cluster-enabled yes
cluster-config-file /opt/redis-cluster/7000/nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
EOS
# for i in {0..5}; do cp -av redis.conf "/opt/redis-cluster/700$i/"; sed -i -e "s/7000/700$i/g" "/opt/redis-cluster/700$i/redis.conf"; done
# for i in {0..5}; do redis-server /opt/redis-cluster/700$i/redis.conf; done

起動できているか確認してみます。

# ps aux | grep redis | grep -v grep
root      1617  0.0  0.7 141016  7580 ?        Ssl  07:53   0:00 redis-server *:7000 [cluster]
root      1621  0.0  0.7 136920  7544 ?        Ssl  07:53   0:00 redis-server *:7001 [cluster]
root      1623  0.0  0.7 136920  7548 ?        Ssl  07:53   0:00 redis-server *:7002 [cluster]
root      1625  0.0  0.7 136920  7544 ?        Ssl  07:53   0:00 redis-server *:7003 [cluster]
root      1629  0.0  0.7 136920  7544 ?        Ssl  07:53   0:00 redis-server *:7004 [cluster]
root      1633  0.0  0.7 136920  7548 ?        Ssl  07:53   0:00 redis-server *:7005 [cluster]

この状態ではそれぞれが単独のマスタとなっているので、これをマスタ・スレーブのクラスタ構成にします。

クラスタ構成にするにはそれぞれの Redis を起動した状態で redis-trib.rb create コマンドで簡単に設定できます。

--replicas 1 オプションでそれぞれ1つのマスタに1つのスレーブを設定するという意味になります。

# ./src/redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.01:7004 127.0.0.1:7005

これでクラスタ構成を構築できたので確認してみます。

# redis-cli -p 7000 cluster nodes
7619bc693126ebfc684f6373af297b124670a018 127.0.0.1:7001 master - 0 1496390202022 2 connected 10923-16383
9bec110278fb159540c6d8aa0f215a81bb0d6e3b 127.0.0.1:7004 master - 0 1496390204038 5 connected 5461-10922
046b85341f98820141a89704b966fc0ed3a79304 127.0.0.1:7003 slave 9bec110278fb159540c6d8aa0f215a81bb0d6e3b 0 1496390202022 5 connected
6fb9cccaab638b2bcaa69598dd3acdd36b792588 127.0.0.1:7002 slave cc994cf3f71b95e36046f8eb65db060133bea306 0 1496390202527 3 connected
1b20ef4dadb0aa7f1fc693078709d0cbc3047d64 127.0.0.1:7005 slave 7619bc693126ebfc684f6373af297b124670a018 0 1496390203030 6 connected
cc994cf3f71b95e36046f8eb65db060133bea306 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460

次に、下図のように、7004 番ポートの Redis (マスタ)をわざと停止させるとどうなるか確認してみたいと思います。

f:id:enomotodev:20170602214135p:plain

# ps aux | grep redis | grep -v grep
root      1617  0.0  0.9 141016  9800 ?        Ssl  07:53   0:00 redis-server *:7000 [cluster]
root      1621  0.0  0.9 138968  9772 ?        Ssl  07:53   0:00 redis-server *:7001 [cluster]
root      1623  0.0  0.7 136920  7740 ?        Ssl  07:53   0:00 redis-server *:7002 [cluster]
root      1625  0.0  0.7 136920  7736 ?        Ssl  07:53   0:00 redis-server *:7003 [cluster]
root      1629  0.0  0.9 138968  9772 ?        Ssl  07:53   0:00 redis-server *:7004 [cluster]
root      1633  0.0  0.7 136920  7740 ?        Ssl  07:53   0:00 redis-server *:7005 [cluster]

7004 番ポートの Redis の PID を確認し kill します。

# kill -9 1629

もう一度、構成を確認してみます。

# redis-cli -p 7000 cluster nodes
7619bc693126ebfc684f6373af297b124670a018 127.0.0.1:7001 master - 0 1496390360732 2 connected 10923-16383
9bec110278fb159540c6d8aa0f215a81bb0d6e3b 127.0.0.1:7004 master,fail - 1496390301201 1496390300798 5 disconnected
046b85341f98820141a89704b966fc0ed3a79304 127.0.0.1:7003 master - 0 1496390362242 7 connected 5461-10922
6fb9cccaab638b2bcaa69598dd3acdd36b792588 127.0.0.1:7002 slave cc994cf3f71b95e36046f8eb65db060133bea306 0 1496390362744 3 connected
1b20ef4dadb0aa7f1fc693078709d0cbc3047d64 127.0.0.1:7005 slave 7619bc693126ebfc684f6373af297b124670a018 0 1496390361738 6 connected
cc994cf3f71b95e36046f8eb65db060133bea306 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460

確認すると、7004 番ポートの Redis から 7003 番ポートの Redis がマスタに昇格したのが確認できると思います。

f:id:enomotodev:20170602214138p:plain

まとめ

今回は Redis Cluster を使って、Redis のマスタ・スレーブのクラスタ構成を構築してみました。

構築するだけであれば redis-trib.rb を使うと、簡単に構築できるので、気軽にシステムの可用性向上につなげることができそうです。

ただ、Redis Cluster だと集合演算など、一部制約を受ける部分もあるようなので、その辺もこれから調べていきたいと思います。

venv で Python の仮想環境をつくってみた

作業環境

Python3 のインストー

まずは、デフォルトの Python のバージョンを確認してみます。

$ python -V
Python 2.7.13

Homebrew を使って Python3 をインストールし、インストールした Python3 のバージョンを確認します。

$ brew install python3
$ python3 -V
Python 3.6.1

venv で仮想環境をつくる

Python ではこれまで virtualenv というツールで仮想環境をつくるのが一般的でしたが、Python 3.3 から venv という標準モジュールで仮想環境をつくることができるようになったようなので、今回は venv を用いて仮想環境をつくってみたいと思います。

次のコマンドで早速仮想環境を作ってみましょう。

$ python3 -m venv python-test

ここでは python-test という名前の仮想環境を作っています。

カレントディレクトリに python-test というディレクトリが作成されます。

仮想環境に入るには activate スクリプトを実行します。

$ . python-test/bin/activate

これで仮想環境に入ることができました。

ちゃんと仮想環境に入ることができているか、バージョンを確認してみます。

(python-test) $ python -V
Python 3.6.1

仮想環境から抜けるには deactivate コマンドを実行します、

(python-test) $ deactivate

仮想環境から抜けることができたか、もう一度バージョンを確認してみます。

$ python -V
Python 2.7.13

まとめ

Python 3.3 からは virtualenv を使用しなくても標準モジュールの venv で簡単に仮想環境をつくることができるようになったようです。

2つ以上のプロジェクトを開発していると、それぞれのプロジェクトのライブラリでバージョンが衝突することがよくあるので、venv を使ってそれぞれのプロジェクトで仮想環境をつくってきちんと環境を分離していきたいと思います。

Ionic で簡易カウンターアプリ作ってみた

開発環境

  • macOS 10.12.4
  • Node.js 7.9.0

Ionic のインストール・プロジェクト作成

Ionic で簡単なカウンターアプリを作成したので、まとめてみました。

まずは npm installcordovaionic をグローバルインストールします。

$ npm install -g cordova ionic

Ionic がインストールできたので、ionic start コマンドでプロジェクトを作成してみます。

$ ionic start SampleApp blank --v2

blank の部分はテンプレートの種類で、他にも tabssidemenu などが指定できるようです。

f:id:enomotodev:20170519205103p:plain

それでは ionic serve コマンドでプロジェクトを起動してみます。

$ cd SampleApp
$ ionic serve

http://localhost:8100/ionic-lab を開くと、各モバイル端末でどのように表示されるかが見れるので、こちらを確認しながら開発していきたいと思います。

f:id:enomotodev:20170519205109p:plain

コードが変更されると自動で更新されるので、タイトルを変更してみます。

  • src/pages/home/home.html
<ion-title>
  Ionic Blank
</ion-title>
↓
<ion-title>
  サンプルアプリ
</ion-title>

f:id:enomotodev:20170519205114p:plain

ブラウザが自動で更新され、タイトル部分が更新されたのがわかるかと思います。

カウンターアプリなので、『数値表示部分』『プラスボタン』『マイナスボタン』『リセットボタン』を配置していきます。

  • src/pages/home/home.html
<ion-content padding>
  The world is your oyster.
  <p>
    If you get lost, the <a href="http://ionicframework.com/docs/v2">docs</a> will be your guide.
  </p>
</ion-content>
↓
<ion-content padding>
  <div>
    <p align="center">0</p>
  </div>
  <ion-buttons>
    <button ion-button block round>プラス</button>
    <button ion-button block round>マイナス</button>
    <button ion-button block round color="danger">リセット</button>
  </ion-buttons>
</ion-content>

f:id:enomotodev:20170519205119p:plain

これでとりあえずデザインは OK なので、ロジックの部分を実装していきます。

  • src/pages/home/home.ts
// ...

export class HomePage {

  public num: number = 0;

  constructor(public navCtrl: NavController) {

  }

}
  • src/pages/home/home.html
  <div>
    <p align="center">{{num}}</p>
  </div>

これで見た目は変わりませんが、数字の表示部分が変数の値を表示するようになりました。

最後にそれぞれのボタンを押した時の動作を実装しましょう。

  • src/pages/home/home.ts
export class HomePage {

  // ...

  plus() {
    this.num++;
  }

  minus() {
    this.num--;
  }

  reset() {
    this.num = 0;
  }

}
  • src/pages/home/home.html
    <button ion-button block round (click)="plus()">プラス</button>
    <button ion-button block round (click)="minus()">マイナス</button>
    <button ion-button block round color="danger" (click)="reset()">リセット</button>

ほとんどコードは書いていないですが、これで完成です!

まとめ

Ionic を使って簡単なカウンターアプリを作ってみました。

簡単なアプリであれば、Webエンジニアでも比較的容易にアプリを作成することができるようなので、色々と試してみたいと思います。

CentOS に Aerospike インストールしてみた

Aerospike とは

Aerospike(エアロスパイク)とは、米 Aerospike 社によって開発されている NoSQL データベースです

とにかく高速であると言われており、最近では日本の企業でも採用事例が増えてきています

今回は OSS 版を CentOS 上に構築してみたいと思います

作業環境

Aerospike のインストー

公式ドキュメントを参考に Aerospike をインストールします

$ wget -O aerospike.tgz 'http://aerospike.com/download/server/latest/artifact/el7'
$ tar -xvf aerospike.tgz
$ cd aerospike-server-community-3.12.0-el7/
$ sudo ./asinstall

自動起動設定をして、Aerospike を起動します

$ sudo systemctl enable aerospike
$ sudo systemctl start aerospike

Aerospike が起動したのでステータスを確認してみましょう

$ sudo systemctl status aerospike
● aerospike.service - Aerospike Server
   Loaded: loaded (/usr/lib/systemd/system/aerospike.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/aerospike.service.d
           └─aerospike.conf
   Active: active (running) since 月 2017-03-27 13:33:10 UTC; 4s ago
  Process: 3559 ExecStartPre=/bin/systemctl start aerospike_telemetry (code=exited, status=0/SUCCESS)
  Process: 3554 ExecStartPre=/usr/bin/asd-systemd-helper (code=exited, status=0/SUCCESS)
 Main PID: 3563 (asd)
   CGroup: /system.slice/aerospike.service
           └─3563 /usr/bin/asd --config-file /etc/aerospike/aerospike.conf --fgdaemon

 3月 27 13:33:14 localhost.localdomain asd[3563]: Mar 27 2017 13:33:14 GMT: INFO (paxos): (paxos.c:3730) ... no other nodes detected - node will operate a...e cluster
 3月 27 13:33:14 localhost.localdomain asd[3563]: Mar 27 2017 13:33:14 GMT: INFO (partition): (partition_balance.c:285) {test} 4096 absent partitions prom...to master
 3月 27 13:33:14 localhost.localdomain asd[3563]: Mar 27 2017 13:33:14 GMT: INFO (partition): (partition_balance.c:285) {bar} 4096 absent partitions promo...to master
 3月 27 13:33:14 localhost.localdomain asd[3563]: Mar 27 2017 13:33:14 GMT: INFO (paxos): (paxos.c:3740) starting paxos threads
 3月 27 13:33:14 localhost.localdomain asd[3563]: Mar 27 2017 13:33:14 GMT: INFO (nsup): (thr_nsup.c:1421) starting namespace supervisor threads
 3月 27 13:33:14 localhost.localdomain asd[3563]: Mar 27 2017 13:33:14 GMT: INFO (demarshal): (thr_demarshal.c:863) starting 1 demarshal threads
 3月 27 13:33:14 localhost.localdomain asd[3563]: Mar 27 2017 13:33:14 GMT: INFO (demarshal): (socket.c:709) Started client endpoint 0.0.0.0:3000
 3月 27 13:33:14 localhost.localdomain asd[3563]: Mar 27 2017 13:33:14 GMT: INFO (info-port): (thr_info_port.c:307) starting info port thread
 3月 27 13:33:14 localhost.localdomain asd[3563]: Mar 27 2017 13:33:14 GMT: INFO (info-port): (socket.c:709) Started info endpoint 0.0.0.0:3003
 3月 27 13:33:14 localhost.localdomain asd[3563]: Mar 27 2017 13:33:14 GMT: INFO (as): (as.c:449) service ready: soon there will be cake!
Hint: Some lines were ellipsized, use -l to show in full.

Aerospike の起動が確認できました!

AMC(Aerospike Management Console)のインストー

AMC は Aerospike の管理ツールです

複数の node をブラウザ上から一度に管理できるそうなので、こちらもインストールしていきたいと思います

まずは、依存パッケージをインストールします

$ sudo yum install gcc python python-devel

こちらも公式ドキュメントを参考にインストールします

$ wget http://aerospike.com/download/amc/latest/artifact/el7
$ sudo rpm -ivh el7

自動起動設定をしてから起動します

$ sudo systemctl enable amc
$ sudo systemctl start amc

ステータスを確認してみます

$ sudo systemctl status amc
● amc.service - LSB: Aerospike's Management Console
   Loaded: loaded (/etc/rc.d/init.d/amc; bad; vendor preset: disabled)
   Active: active (running) since 月 2017-03-27 13:48:04 UTC; 45s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 3819 ExecStart=/etc/rc.d/init.d/amc start (code=exited, status=0/SUCCESS)
 Main PID: 3824 (amc)
   CGroup: /system.slice/amc.service
           └─3824 /opt/amc/amc -config-file=/etc/amc/amc.conf -config-dir=/etc/amc

 3月 27 13:48:04 localhost.localdomain systemd[1]: Starting LSB: Aerospike's Management Console...
 3月 27 13:48:04 localhost.localdomain runuser[3822]: pam_unix(runuser:session): session opened for user root by (uid=0)
 3月 27 13:48:04 localhost.localdomain amc[3819]: Starting amc: [  OK  ]
 3月 27 13:48:04 localhost.localdomain systemd[1]: Started LSB: Aerospike's Management Console.

AMC の起動も確認することができました!

AMC はデフォルトでは 8081 ポートで起動するので、ブラウザからアクセスしてみます

f:id:enomotodev:20170519204627p:plain

Aerospike の IP アドレスとポートを入力する画面が表示されるので、それぞれ localhost, 3000 と設定し、『Connect』ボタンを押下します

特に問題なければ次のような画面が表示されます

f:id:enomotodev:20170519204631p:plain

まとめ

Aerospike をインストールするところまで学習しました

実際にレコードを insert, select, update, delete するなど、今後色々と触って試していきたいと思います

CentOS に pyenv で Python インストールしてみた

pyenv とは

pyenv とは Python のバージョン管理を行なうコマンドラインツールで、複数のバージョンの Python のインストールや、インストールしたバージョンの変更を簡単に行うことができます。

Ruby では rbenv + ruby-build が有名ですが、それの Python 版だと考えていただけたらと思います。

作業環境

pyenv のインストー

まずは依存パッケージを yum でインストールします。

$ sudo yum install gcc zlib-devel bzip2 bzip2-devel readline readline-devel sqlite sqlite-devel openssl openssl-devel git

pyenv を ~/.pyenvgit clone します。

$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv

~/.bash_profile環境変数などを設定します。

$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile

先ほど設定した環境変数を反映します。

$ source ~/.bash_profile

これで pyenv のインストールは完了となりますので、問題なくインストールできているか、pyenv のバージョンを確認してみましょう。

$ pyenv --version
pyenv 1.0.6-1-g0256ff0

pyenv で Python をインストールする

pyenv で別バージョンの Python をインストールする前に、まずは現在の Python のバージョンを確認してみます。

$ python --version
Python 2.7.5

次に、インストールできる Python のバージョンを一覧表示してみます。

$ pyenv install --list
Available versions:
  2.1.3
  2.2.3
  2.3.7
  2.4
  2.4.1
  2.4.2
  2.4.3
  2.4.4
  2.4.5
  2.4.6
  2.5
  2.5.1
  2.5.2
  2.5.3
  2.5.4
  2.5.5
  2.5.6
...(略)

今回は Python 3.6.0 をインストールします。

$ pyenv install 3.6.0
Downloading Python-3.6.0.tar.xz...
-> https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tar.xz
Installing Python-3.6.0...
Installed Python-3.6.0 to /home/vagrant/.pyenv/versions/3.6.0

使用する Python のバージョンを 3.6.0 に変更します。

$ pyenv global 3.6.0
$ pyenv rehash

Python のバージョンがきちんと 3.6.0 に変更されているか、Python のバージョンを再度確認してみます。

$ python --version
Python 3.6.0

Python 3.6.0 がインストールできました!

Python のバージョンを元に戻す

Python のバージョンを元に戻したいこともあると思うので、バージョンを元に戻す方法も確認しておきましょう。

まずは、pyenv でインストールしたバージョンの一覧を表示します。

$ pyenv versions
  system
* 3.6.0 (set by /home/enomotodev/.pyenv/version)

先ほどインストールした 3.6.0 以外に system というバージョンがあるのがわかるかと思います。

Python のバージョンを元に戻したいときは、system にバージョンを設定してあげれば OK です。

$ pyenv global system
$ python --version
Python 2.7.5

これで Python のバージョンが元に戻りました!