GlusterFS と tmpfs による分散メモリキャッシュシステム

&gt; to English Pages
https://kyowg.blogspot.com/2018/11/distributed-fault-tolerant-cache-system.html
## 1. 要約
この記事では、GlusterFS と tmpfs による、フォールトトレラントな分散メモリーキャッシュシステムの設計と構築の一例を投稿します。

## 2. はじめに
以前、“<a href='https://qiita.com/KyojiOsada/items/aa38868c0bbc057ab4e4'>分散ファイルシステム GlusterFS による Web サーバー間の同期</a>” の記事で、 GlusterFS について投稿しました。
今回の記事では、GlusterFS と tmpfs を使ったフォールトトレラントな分散メモリキャッシュシステムを投稿します。
このアイディアの設計は、現時点ではアウトプットが世の中にほぼ存在しないようです。
改良次第では、更にシンプルでパフォーマンスの高い分散メモリキャッシュシステムが実現できるかもしれません。

* <a href='https://ja.wikipedia.org/wiki/%E5%88%86%E6%95%A3%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0'>分散ファイルシステムとは？</a>
* <a href='https://ja.wikipedia.org/wiki/GlusterFS'>GlusterFS とは？</a>
* <a href='https://ja.wikipedia.org/wiki/Tmpfs'>tmpfs とは？</a>
* <a href='https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A9%E3%83%BC%E3%83%AB%E3%83%88%E3%83%88%E3%83%AC%E3%83%A9%E3%83%B3%E3%83%88%E8%A8%AD%E8%A8%88'>フォルートトレラントとは？</a>
* <a href=https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)''>メモリーキャッシュシステムとは？</a>

## 3. GlusterFS & tmpfs 環境
* CentOS 7
* GlusterFS 4.1.5
* tmpfs
* Go 1.9

## 4. GlusterFS & tmpfs 設計
![GlusterFS_tmpfs_architecture.png](https://qiita-image-store.s3.amazonaws.com/0/260161/eaa66d6a-de09-b4c1-48f0-716cb043a242.png)

## 5. GlusterFS & tmpfs キャッシュサーバー構築
### 5-1. GlusterFS インストール
@ キャッシュサーバー 1, 2
`$ sudo yum -y install centos-release-gluster`
`$ sudo yum -y install glusterfs-server`

### 5-2. GlusterFS 起動
@ キャッシュサーバー 1, 2
`$ sudo systemctl start glusterd`
`$ sudo systemctl enable glusterd`
`$ sudo systemctl status glusterd`

### 5-3. GlusterFS ホスト設定
@ キャッシュサーバー 1, 2
`$ sudo vim /etc/hosts`

```conf:/etc/hosts
10.0.0.1 cache1.example.com
10.0.0.2 cache2.example.com
```

### 5-4. GlusterFS ストレージプール作成
@ キャッシュサーバー 1
`$ sudo gluster peer probe cache2.example.com`

### 5-5. GlusterFS ストレージプール情報確認
@ キャッシュサーバー 1, 2
`$ sudo gluster peer status`

### 5-6. tmpfs サーバー設定
@ キャッシュサーバー 1, 2
`$ sudo mkdir /cache_server`
`$ sudo mount -t tmpfs -o size=512m tmpfs /cache_server`
`$ sudo vim /etc/fstab`

### 5-7. tmpfs サーバー自動起動
@ キャッシュサーバー 1
`$ sudo vim /etc/fstab`

```conf:/etc/fstab
tmpfs    /cache_server    tmpfs    defaults,size=512m    0 0
```

@ キャッシュサーバー 2
`$ sudo vim /etc/fstab`<br>

```conf:/etc/fstab
tmpfs    /cache_server    tmpfs    defaults,size=512m    0 0
```

### 5-8. GlusterFS ボリューム作成
@ キャッシュサーバー 1
`$ sudo gluster volume create cache_server replica 2 cache1.example.com:/cache_server/ cache2.example.com:/cache_server/ force`

### 5-9. GlusterFS ボリューム情報確認
@ キャッシュサーバー 1, 2
`$ sudo gluster volume info`

### 5-10. Gluster ボリューム起動
@ キャッシュサーバー 1
`$ sudo gluster volume start cache_server`

### 5-11. GlusterFS ボリューム状態確認
@ キャッシュサーバー 1, 2
`$ sudo gluster volume status`

## 6. GlusterFS & tmpfs キャッシュクライアント構築
### 6-1. GlusterFS クライアントインストール
@ キャッシュサーバー 1, 2
`$ sudo yum -y install glusterfs glusterfs-fuse glusterfs-rdma`

### 6-2. GlusterFS サーバーホスト名設定
@ キャッシュサーバー 1, 2
`$ sudo vim /etc/hosts`

```conf:/etc/hosts
10.0.0.1 cache1.example.com
10.0.0.2 cache2.example.com
```

### 6-3. GlusterFS サーバーマウント
@ Web サーバー 1
`$ sudo mkdir /cache_client`
`$ sudo mount -t glusterfs cache1.example.com:/cache_server /cache_client`
`$ sudo df -Th`

@ Web サーバー 2
`$ sudo mkdir /cache_client`
`$ sudo mount -t glusterfs cache2.example.com:/cache_server /cache_client`
`$ sudo df -Th`

### 6-4. GlusterFS 自動起動
@ Web サーバー 1
`$ sudo vim /etc/fstab`

```conf:/etc/fstab
cache1.example.com:/cache_server       /cache_client   glusterfs       defaults,_netdev        0 0
```

@ Web サーバー 2
`$ sudo vim /etc/fstab`

```conf:/etc/fstab
cache2.example.com:/cache_server       /cache_client   glusterfs       defaults,_netdev        0 0
```

### 6-5. GlusterFS 同期テスト
@ Web サーバー 1
`$ sudo touch /cache_client/test.txt`
`$ sudo ls /cache_client`

@ Web サーバー 2
`$ sudo ls /cache_client`
`$ sudo rm /cache_client/text.txt`

@ Web サーバー 1
`$ sudo ls /cache_client`

## 7. GlusterFS & tmpfs ベンチマークテスト
ベンチマークテストの結果は、参考値です。
下記のベンチマークテストプログラムは Golang で書かれています。

```
1 MB のテキスト
↓
キャッシュシステム
ファイル作成、ファイル書き込み、ファイル読み込み、ファイル削除 x 1,000 回
↓
ファイルシステム
ファイル作成、ファイル書き込み、ファイル読み込み、ファイル削除 x 1,000 回
↓
10 回処理の平均値
```

### 7-1. ベンチマークテスト Golang プログラム
@ Web サーバー 1
`$ sudo nvim ~/go/main.go`

```go:~/go/main.go
package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"time"
)

func main() {
	// Configure
	file_paths := []string{"/cache_client/test.txt", "/file_client/test.txt"}
	systems := []string{"Cache System", "File System"}
	results := []float64{0, 0}
	benchmark_times := 10
	processing_times := 1000

	var content_string string
	for i := 0; i < 1000000; i++ {
		content_string += "a"
	}
	content_byte := []byte(content_string)

	for i := 0; i < benchmark_times; i++ {
		for j, _ := range file_paths {
			// Get processing start datetime
			start_datetime := time.Now()
			for k := 0; k < processing_times; k++ {
				// Write file
				err := ioutil.WriteFile(file_paths[j], content_byte, 0644)
				if err != nil {
					fmt.Println("File Writing Error: ", err)
					os.Exit(1)
				}

				// Read file
				content_read, err := ioutil.ReadFile(file_paths[j])
				if err != nil {
					fmt.Println("File Reading Error: ", err, content_read)
					os.Exit(1)
				}

				// Remove file
				err = os.Remove(file_paths[j])
				if err != nil {
					fmt.Println("File Removing Error: ", err)
					os.Exit(1)
				}
			}
			// Get processing end datetime
			end_datetime := time.Now()

			// Get processing total time
			total_time := end_datetime.Sub(start_datetime)
			results[j] += total_time.Seconds()
			fmt.Printf("[%v] %v: %v\n", i, systems[j], total_time)
		}
	}

	for i, v := range results {
		average := v / float64(benchmark_times)
		fmt.Printf("%v Average: %vs\n", systems[i], average)
	}

	os.Exit(0)
}
```

### 7-2. ベンチマークテスト Golang プラグラム実行
@ Web サーバー 1
`$ go build main.go`
`$ ./main`

### 7-3. ベンチマークテスト結果
```
[0] Cache System: 16.180571409s
[0] File System: 16.302403193s
[1] Cache System: 15.93305082s
[1] File System: 16.61177919s
[2] Cache System: 16.311321483s
[2] File System: 16.393385347s
[3] Cache System: 16.036057793s
[3] File System: 16.740742882s
[4] Cache System: 16.139074157s
[4] File System: 16.754381782s
[5] Cache System: 16.151769414s
[5] File System: 16.90680323s
[6] Cache System: 16.340969528s
[6] File System: 16.693090068s
[7] Cache System: 16.177776325s
[7] File System: 16.961861504s
[8] Cache System: 16.226036092s
[8] File System: 16.638383153s
[9] Cache System: 16.622041061s
[9] File System: 16.887159942s
Cache System Average: 16.2618668082s
File System Average: 16.638999029100003s
```

## 8. まとめ
この記事では、GlusterFS と tmpfs による、フォールトトレラントな分散メモリキャッシュシステムの設計と構築の一例を投稿しました。
ベンチマークテスト結果はあくまで参考値ですが、パフォーマンスが向上する事もわかります。
このアイディアの設計は、現時点で世の中にアウトプットがほぼ存在しないようです。
改良次第では、更にシンプルでパフォーマンスの高い分散メモリキャッシュシステムが実現できるかもしれません。

次回以降、GlusterFS と同じフォールトトレラントな分散ファイルシステムである “<b>LizardFS</b>” の記事をどこかで投稿しようと思います。
アドバイスをくれた LizardFS Inc. の Mark Mulrainey に感謝します。

（投稿しました。“<a href='https://qiita.com/KyojiOsada/items/b0b32b2fcda4e967164b'>LizardFS 分散ファイルシステムの構築（RC 版 3.13 RPM パッケージ編）</a>”）