LoginSignup
0
1

More than 5 years have passed since last update.

LizardFS による分散ファイルシステムの構築(GA 版 3.12 yum インストール編)

Last updated at Posted at 2018-12-09

1. 要約

この記事では、LizardFS による分散ファイルシステムの構築(GA 版 3.12 yum インストール編)の例と、keepalived や、スクラッチの Golang デーモンによる、自前のマスターフェイルオーバー機構の構築例について投稿します。

2. はじめに

前回の記事 “LizardFS による分散ファイルシステムの構築(RC 版 3.13 RPM パッケージ編)” では、lizardfs-uraft パッケージが入ったバージョンの構築例と、keepalived やスクラッチの Golang デーモンを使った、自前のマスターフェイルオーバー機構の構築例について投稿しました。
今回の記事では、lizardfs-uraft パッケージのない yum インストール編の構築例と、前回作った keepalived 構成やスクラッチの Golang デーモンを使った、自前の自動フェイルオーバー環境をカスタマイズした構築例を投稿します。
LizardFS の GA 版 3.12 yum インストール編と RC 版 3.13 RPM パッケージ編の違いは、“LizardFS による分散ファイルシステムの構築(RC 版 3.13 RPM パッケージ編)” をご参照ください。

3. LizardFS 環境

  • RHEL 7 系
  • LizardFS 3.12
  • keepalived 1.3.5
  • Go 1.9

4. LizardFS 設計

  • LizardFS マスターサーバー x 2
    • mfs-master1
    • mfs-master2
  • LizardFS チャンクサーバー x 2
    • mfs-chunk1
    • mfs-chunk2
  • LizardFS クライアント x 2
    • mfs-client1
    • mfs-client2

LizardFS パッケージ一覧

lizardfs-master – LizardFS master server
lizardfs-chunkserver – LizardFS data server
lizardfs-client – LizardFS client
lizardfs-adm – LizardFS administration tools (e.g, lizardfs-probe)
lizardfs-cgi – LizardFS CGI Monitor
lizardfs-cgiserv – Simple CGI-capable HTTP server to run LizardFS CGI Monitor
lizardfs-metalogger – LizardFS metalogger server
lizardfs-debuginfo – (CentOS 7 / RHEL 7 only) Debugging symbols and sources for all the LizardFS binaries

5. LizardFS マスターサーバー

5-1. epel リポジトリインストール

@ mfs-master1, 2
$ sudo yum install -y epel-release
$ sudo vim /etc/yum.repos.d/epel.repo

/etc/yum.repos.d/epel.repo
- enabled=1
+ enabled=0

※ diff 表示

5-2. LizardFS リポジトリインストール

@ mfs-master1, 2
$ sudo curl http://packages.lizardfs.com/yum/el7/lizardfs.repo > /etc/yum.repos.d/lizardfs.repo
$ sudo vim /etc/yum.repos.d/lizardfs.repo

/etc/yum.repos.d/lizardfs.repo
- enabled=1
+ enabled=0

※ diff 表示

5-6. LizardFS マスターインストール

@ mfs-master1, 2
$ sudo yum install -y --enablerepo=lizardfs,epel lizardfs-master lizardfs-adm

5-7. hosts ファイル設定

@ mfs-master1, 2
$ vim /etc/hosts

/etc/hosts
10.0.0.1    mfs-master1
10.0.0.2    mfs-master2
10.0.0.3    mfs-chunk1
10.0.0.4    mfs-chunk2
10.0.0.5    mfs-client1
10.0.0.6    mfs-client2

5-8. metadata.mfs 設定

@ mfs-master1, 2
$ sudo cd /var/lib/mfs/
$ sudo cp -a metadata.mfs.empty metadata.mfs

5-9. mfsmaster.cfg 設定

@ mfs-master1, 2
$ sudo cd /etc/mfs/
$ sudo cp -a mfsmaster.cfg.dist mfsmaster.cfg
$ sudo vim mfsmaster.cfg

@ mfs-master1

/etc/mfs/mfsmaster.cfg
PERSONALITY = master
# ホスト名または IP アドレス
MASTER_HOST = mfs-cluster

@ mfs-master2

/etc/mfs/mfsmaster.cfg
PERSONALITY = shadow
# ホスト名または IP アドレス
MASTER_HOST = mfs-cluster

5-10. mfsgloas.cfg 設定

@ mfs-master1, 2
$ sudo cd /etc/mfs/
$ sudo cp -a mfsgoals.cfg.dist mfsgoals.cfg
$ sudo vim mfsgoals.cfg

/etc/mfs/mfsgoals.cfg
2 2 : _ _

5-11. その他設定ファイル

@ mfs-master1, 2
$ sudo cp -a globaliolimits.cfg.dist globaliolimits.cfg=
$ sudo cp -a mfsexports.cfg.dist mfsexports.cfg
$ sudo cp -a mfstopology.cfg.dist mfstopology.cfg`

globaliolimits.cfg       mfsexports.cfg       mfsgoals.cfg       mfsmaster.cfg       mfstopology.cfg
globaliolimits.cfg.dist  mfsexports.cfg.dist  mfsgoals.cfg.dist  mfsmaster.cfg.dist  mfstopology.cfg.dist

6 LizardFS チャンクサーバー

6-1. epel リポジトリインストール

@ mfs-chunk1, 2
$ yum install -y epel-release

/etc/yum.repos.d/lizardfs.repo
- enabled=1
+ enabled=0

※ diff 表示

6-2. LizardFS リポジトリインストール

@ mfs-chunk1, 2
$ curl http://packages.lizardfs.com/yum/el7/lizardfs.repo > /etc/yum.repos.d/lizardfs.repo
$ vim /etc/yum.repos.d/lizardfs.repo

/etc/yum.repos.d/lizardfs.repo
- enabled=1
+ enabled=0

※ diff 表示

6-3. LizardFS チャンクサーバーインストール

@ mfs-chunk1, 2
$ sudo yum install -y --enablerepo=lizardfs,epel lizardfs-chunkserver lizardfs-adm

6-4. hosts ファイル設定

@ mfs-chunk1, 2
$ vim /etc/hosts

/etc/hosts
10.0.0.1    mfs-master1
10.0.0.2    mfs-master2
10.0.0.3    mfs-chunk1
10.0.0.4    mfs-chunk2
10.0.0.5    mfs-client1
10.0.0.6    mfs-client2

6-5. mfschunkserver.cfg 設定

@ mfs-chunk1, 2
$ sudo cd /etc/mfs/
$ sudo cp -a mfschunkserver.cfg.dist mfschunkserver.cfg
$ sudo vim mfschunkserver.cfg

/etc/mfs/mfschunkserver.cfg
# ホスト名または IP アドレス
MASTER_HOST = mfs-cluster

6-6. mfshdd.cfg 設定

@ mfs-chunk1, 2
$ sudo cd /etc/mfs/
$ sudo cp -a mfshdd.cfg.dist mfshdd.cfg
$ sudo vim mfshdd.cfg

/etc/mfs/mfshdd.cfg
/mnt/mfs

7. LizardFS クライアント

7-1. epel リポジトリインストール

@ mfs-client1, 2
$ sudo yum install -y epel-release

/etc/yum.repos.d/lizardfs.repo
- enabled=1
+ enabled=0

※ diff 表示

7-2. LizardFS リポジトリインストール

@ mfs-client1, 2
$ sudo curl http://packages.lizardfs.com/yum/el7/lizardfs.repo > /etc/yum.repos.d/lizardfs.repo
$ sudo vim /etc/yum.repos.d/lizardfs.repo

/etc/yum.repos.d/lizardfs.repo
- enabled=1
+ enabled=0

※ diff 表示

7-3. LizardFS クライアントインストール

@ mfs-client1, 2
$ sudo yum install -y --enablerepo=lizardfs,epel lizardfs-client lizardfs-adm

7-4. hosts ファイル設定

@ mfs-client1, 2
$ sudo vim /etc/hosts

/etc/hosts
10.0.0.1    mfs-master1
10.0.0.2    mfs-master2
10.0.0.3    mfs-chunk1
10.0.0.4    mfs-chunk2
10.0.0.5    mfs-client1
10.0.0.6    mfs-client2

7-5. mfsmount.cfg 設定

@ mfs-client1, 2
$ sudo cd /etc/mfs/
$ sudo cp -a mfsmount.cfg.dist mfsmount.cfg
$ sudo vim mfsmount.cfg

/etc/mfs/mfsmount.cfg
mfsmaster=mfs-cluster,mfsport=9421
/mnt/mfs

8. マスターフェイルオーバー環境の準備

ここから、マスターフェイルオーバー機構を自前で用意します。
前回の記事 “LizardFS による分散ファイルシステムの構築(RC 版 3.13 RPM パッケージ編)” で、keepalived 構成と、Go 言語デーモンのスクラッチ開発の 2 通りで用意しましたので、それらを少しだけカスタマイズしていきます。

9. keepalived マスターフェイルオーバー機構

以降で、keepalived による、マスターフェイルオーバー機構を構築します。

9-1. keepalived インストール

前回の記事 “LizardFS による分散ファイルシステムの構築(RC 版 3.13 RPM パッケージ編)” をご参照ください。

9-3. keepalived 設定

前回の記事 “LizardFS による分散ファイルシステムの構築(RC 版 3.13 RPM パッケージ編)” をご参照ください。

9-4. notify Bash スクリプト作成

@ mfs-master1, 2
$ sudo cd /etc/keepalived
$ sudo touch notify.sh
$ sudo vim notify.sh

/etc/keepalived/notify.sh
#!/bin/bash
# notify.sh

# Check argument counts
if [ $# -ne 3 ]; then
    echo "Three arguments must be passed in $HOSTNAME." 1>&2
    exit 1
fi

# Init variables
NOTIFY=$1
IPV4=$2
PORT=$3

# Validate 1st argument values
if [ $NOTIFY != "master" ] && [ $NOTIFY != "backup" ]; then
    echo "The passed argument is invalid." 1>&2
    exit 1
fi

# Validate 2nd argument values
#...

# Validate 3rd argument values
#...

# Take cluster personality
PERSONALITY=`lizardfs-admin metadataserver-status $IPV4 $PORT`

# Notify master
if [ $NOTIFY = "master" ]; then
    ## Promote master
    if [[ $PERSONALITY =~ "personality: shadow" ]]; then
        ### Restart master
        lizardfs-master -o initial-personality=master -o auto-recovery restart
    fi
# Notify backup
elif [ $NOTIFY = "backup" ]; then
    ## Demote Master
    if [[ $PERSONALITY =~ "personality: master" ]]; then
        ### Restart shadow
        lizardfs-master -o initial-personality=shadow restart
    fi
fi

# Check promotion or demotion of master
if [ $? != 0 ]; then
    echo "Could not !$ in $HOSTNAME."
    exit 1
fi

## Restart LizardFS
systemctl restart lizardfs-master 2>&1 >/dev/null
if [ $? != 0 ]; then
    echo "Could not !$ in $HOSTNAME." 1>&2
    exit 1
fi

exit 0

10. 起動

10-1. keepalived 起動

前回の記事 “LizardFS による分散ファイルシステムの構築(RC 版 3.13 RPM パッケージ編)” をご参照ください。

10-2. LizardFS マスターサーバー起動

@ mfs-master1, 2
$ sudo systemctl start lizardfs-master
$ sudo systemctl status lizardfs-master

10-3. LizardFS チャンクサーバー起動

前回の記事 “LizardFS による分散ファイルシステムの構築(RC 版 3.13 RPM パッケージ編)” をご参照ください。

10-4. クライアントマウント

前回の記事 “LizardFS による分散ファイルシステムの構築(RC 版 3.13 RPM パッケージ編)” をご参照ください。

10-5. 同期テスト

@ mfs-client1
$ sudo touch /mnt/mfs/test

@ mfs-client2
$ sudo ls /mnt/mfs
$ sudo rm -rf /mnt/mfs/test

@ mfs-client1
$ sudo ls /mnt/mfs

10-6. keepalived マスターフェイルオーバーテスト

前回の記事 “LizardFS による分散ファイルシステムの構築(RC 版 3.13 RPM パッケージ編)” をご参照ください。

10-7. keepalived マスターフェイルバックテスト

前回の記事 “LizardFS による分散ファイルシステムの構築(RC 版 3.13 RPM パッケージ編)” をご参照ください。

11. Golang マスターフェイルオーバーデーモン

以降で、スクラッチで Golang マスターフェイルオーバーデーモンを作成します。

11-1. VIP のアサイン

この構築例の VIP(フローティング IP)は、手動アサインします。

@ mfs-master1
$ sudo ip -f inet addr add 10.0.0.9/24 dev eth0
$ sudo arping -q -U -c5 -w1 10.0.0.9 -I eth0

11-2. Golang マスターフェイルオーバープログラム作成

@ mfs-master1, 2
$ sudo cd ~/go/
$ sudo nvim main.go

~/go/main.go
package main

import (
    "fmt"
    "net"
    "os"
    "os/exec"
    "strings"
    "time"
    "unsafe"
)

func main() {

    cluster_vip := os.Args[1]
    cluster_port := os.Args[2]
    cluster_address := cluster_vip + ":" + cluster_port
    self_ip := os.Args[3]
    self_port := os.Args[4]
    greeting_interval := 1
    greeting_timeout := 5
    retry_interval := 3
    retry_count := 3
    retry_timeout := 5

    for {
        // Sleep healthcheck interval seconds
        time.Sleep(time.Duration(greeting_interval) * time.Second)

        // Greet to cluster
        conn, err := net.DialTimeout("tcp", cluster_address, time.Duration(greeting_timeout)*time.Second)

        // Succeeded greeting
        if err == nil {
            conn.Close()
            fmt.Println("Could greet to cluster.")
            continue
        }

        // Failed greeting
        // Log
        //...
        fmt.Println("Could not greet to cluster.")

        // Loop re-connection to cluster
        health_flag := false
        for j := 0; j < retry_count; j++ {

            // Sleep re-connection interval seconds
            time.Sleep(time.Duration(retry_interval) * time.Second)

            // Re-connect
            conn, err = net.DialTimeout("tcp", cluster_address, time.Duration(retry_timeout)*time.Second)

            // Failed re-connection
            if err != nil {
                // Log
                //...
                fmt.Println("Could not re-connect to cluster.")
                continue
            }

            // Succeeded re-connection
            fmt.Println("Succeeded re-connection to cluster.")
            health_flag = true
            break
        }

        // Alive
        if health_flag {
            continue
        }

        // Dead
        personality_byte, err := exec.Command("lizardfs-admin", "metadataserver-status", self_ip, self_port).Output()
        personality := *(*string)(unsafe.Pointer(&personality_byte))

        // Failed get personality
        if err != nil {
            // Log
            //...
            fmt.Println("Could not get personality.")
            os.Exit(1)
        }

        // Demote from master
        if -1 != strings.Index(personality, "personality: master") {
            // Restart shadow
            err = exec.Command("lizardfs-master", "-o initial-personality=shadow", "restart").Run()

            // Failed master demotion
            if err != nil {
                // Log
                //...
                fmt.Println("Could not demote to master.")
                os.Exit(1)
            }
            fmt.Println("Succeeded master demotion.")

            // Unasign VIP
            err = exec.Command("ip", "-f inet addr delete 10.0.0.9/24 dev eth0").Run()

            // Failed VIP Unasigning
            if err != nil {
                // Log
                //...
                fmt.Println("Could not unasigning vip.")
                os.Exit(1)
            }
            fmt.Println("Succeeded master demotion.")

        // Promote to master
        } else if -1 != strings.Index(personality, "personality: shadow") {
            // Asign VIP
            err = exec.Command("ip", "-f inet addr add 10.0.0.9/24 dev eth0").Run()
            // Failed asigning VIP
            if err != nil {
                // Log
                //...
                fmt.Println("Could not asign VIP.")
                os.Exit(1)
            }

            // Execute arping
            err = exec.Command("arping", "-q -U -c5 -w1 10.0.0.9 -I eth0").Run()
            // Failed arping
            if err != nil {
                // Log
                //...
                fmt.Println("Could not execute arping.")
                os.Exit(1)
            }

            // Restart master
            err = exec.Command("lizardfs-master", "-o initial-personality=master -o auto-recovery", "restart").Run()

            // Failed master promotion
            if err != nil {
                // Log
                //...
                fmt.Println("Could not promote to master.")
                os.Exit(1)
            }
            fmt.Println("Succeeded master promotion.")
        }

        // Restart LizardFS
        err = exec.Command("systemctl", "restart", "lizardfs-master").Run()

        // Failed restart
        if err != nil {
            // Log
            //...
            fmt.Println("Could not restart LizardFS.")
            os.Exit(1)
        }
        fmt.Println("Succeeded restart LizardFs.")
    } // End Loop
}

$ sudo go build main.go

11-3. Golang マスターフェイルオーバープログラムテスト

前回の記事 “LizardFS による分散ファイルシステムの構築(RC 版 3.13 RPM パッケージ編)” をご参照ください。

12. Golang マスターフェイルオーバーデーモン化

前回の記事 “LizardFS による分散ファイルシステムの構築(RC 版 3.13 RPM パッケージ編)” をご参照ください。

13. まとめ

この記事では、 LizardFS による分散ファイルシステムの構築(GA 版 3.12 yum インストール編)の例について投稿しました。
自前のマスターフェイルオーバー機構につきましては、keepalvied や、スクラッチの Golang デーモンにより実現しましたが、死活監視パターンにつきましては、実用にあわせて適宜実装してください。
他の分散ファイルシステムとのパフォーマンスのベンチマークテストにつきましては、別の機会に投稿しようと思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1