search
LoginSignup
1

More than 3 years have passed since last update.

posted at

updated at

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

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 デーモンにより実現しましたが、死活監視パターンにつきましては、実用にあわせて適宜実装してください。
他の分散ファイルシステムとのパフォーマンスのベンチマークテストにつきましては、別の機会に投稿しようと思います。

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
What you can do with signing up
1