BLOG

mogilefs+nginx+nginx mogilefs moduleで分散型オブジェクトストレージを構築(PostgreSQL版・後半)

mogilefs_architecture

前半ではMogileFSを使って分散型オブジェクトストレージを構築する方法について学びました。
MogileFSを使う事によって安価なストレージサービスを提供する事ができますが、
Trackerと通信ができる専用のクライアントを用いる必要があります。

後半ではより汎用的にプログラムからアップロードができるよう、
Amazon S3と同等機能が提供できるHTTP通信を導入する方法について学びます。

 

■ nginx+nginx mogilefs moduleを用いた連携
ここからはnginxとmogilefsの連携モジュールを導入していきます。

・前提パッケージのインストール

yum -y install openssl-devel zlib-devel gd-devel pcre-devel

・nginx本体のダウンロード
nginx本体をダウンロードし解凍します。 [本家よりダウンロードしてください。]

・nginx_moduleのダウンロード
nginx用の追加モジュールをダウンロードし解凍します。

wget http://www.grid.net.ru/nginx/download/nginx_mogilefs_module-1.0.4.tar.gz
tar -xvzf nginx_mogilefs_module-1.0.4.tar.gz

・nginx_moduleのパッチ適用
ダウンロードしたモジュールは一部機能で不具合が発生しますので、
ngx_http_mogilefs_module.cへ以下のパッチを当てます。
※3行追加するだけですので、文字列を探して+部分を追加しても構いません。

diff ngx_http_mogilefs_module.c ngx_http_mogilefs_module.c
index e229f47..a4d249d 100644
--- ngx_http_mogilefs_module.c
+++ ngx_http_mogilefs_module.c
@@ -483,6 +483,9 @@ ngx_http_mogilefs_put_handler(ngx_http_request_t *r)
case FETCH:
spare_location = mgcf->create_close_spare_location;
ctx->state = CREATE_CLOSE;
+#if defined nginx_version && nginx_version >= 8011
+            r->main->count++;
+#endif
break;
case CREATE_CLOSE:
r->headers_out.content_length_n = 0;

・nginxのコンパイル&インストール
nginx本体をコンパイルし、インストールを行います。
このコンフィグオプションにより、設定ファイルやログファイルは以下に配置されます。
加えて一部モジュールを追加していますが、これらの詳しい利用方法はオマケ編を参照ください。
【設定ファイル】 /etc/nginx/nginx.conf
【ログファイル】 /var/log/nginx/access_log

mkdir -p /var/tmp/nginx/{proxy,client,fcgi}
./configure --add-module=../nginx_mogilefs_module-1.0.4 --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error_log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --user=nginx --group=nginx --with-http_image_filter_module --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --http-log-path=/var/log/nginx/access_log --http-client-body-temp-path=/var/tmp/nginx/client --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fcgi
make
make install

・nginxの設定

vi /etc/nginx/nginx.conf
--------------------------------------------------
user  nobody;
worker_processes  10;

events {
use epoll;
worker_connections 8192;
}

http {
    server_tokens off;
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  0;
    gzip  on;

    server {
        listen       80;
        server_name  localhost;
        client_max_body_size 100M; #最大アップロードサイズ、5000MBで5GBのファイルアップロードを確認済
        client_body_buffer_size 128k;
        location /_ドメイン1で使用するURI_/ {
            mogilefs_tracker _trackerのIPアドレス_:7001;
            mogilefs_domain  _ドメイン1_;
            mogilefs_class _ドメイン1で使用するクラス_;
            mogilefs_methods GET PUT DELETE;
            mogilefs_pass {
                proxy_pass $mogilefs_path;
                proxy_hide_header Content-Type;
                proxy_buffering off;
        }
    }
location /_ドメイン2で使用するURI_/ {
            mogilefs_tracker _trackerのIPアドレス_:7001;
            mogilefs_domain  _ドメイン2_;
            mogilefs_class _ドメイン2で使用するクラス_;
            mogilefs_methods GET PUT DELETE;
            mogilefs_pass {
                proxy_pass $mogilefs_path;
                proxy_hide_header Content-Type;
                proxy_buffering off;
        }
    }

location /nginx_status {
  stub_status on;
  access_log   off;
  allow _ステータス情報を許可するIPアドレス_;
  deny all;
}
}
}

・ファイルオープン数周りの対策

vi /etc/sysctl.conf
--------------------------------------------------
fs.file-max = 70000

net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.netfilter.nf_conntrack_tcp_timeout_established = 60

・ソケットオープン数周りの対策

vi /etc/security/limits.conf
--------------------------------------------------
nobody soft nofile 65536
nobody hard nofile 65536
root soft nofile 65536
root hard nofile 65536

・nginxの起動スクリプトの追加

vi /etc/init.d/nginx (755)
--------------------------------------------------
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemin
#
# chkconfig:   - 85 15 
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# pidfile:     /usr/local/nginx/logs/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/etc/nginx/nginx.conf"

lockfile=/var/lock/subsys/nginx

start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest || return $?
    stop
    start
}

reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}

force_reload() {
    restart
}

configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac

・nginxの起動

/etc/init.d/nginx start

■ 動作確認

・ファイルのアップロード
curlコマンドを用いてHTTP/PUTメソッドで保存します。
キーの名前で保存しますが、例えばjpgファイルを保存する場合に、キー名に○○.jpgという名称で保存する事で、
ウェブサーバー側で表示する事も可能です。

$ curl --upload-file アップロードするファイル http://_サーバーのIPアドレス_/_指定したドメイン_/キーの名前

・ファイルの表示
ブラウザやHTTP/GETメソッドで以下のアドレスを表示してみてください。
http://_サーバーのIPアドレス_/_指定したドメイン_/キーの名前

・保存済みファイルの削除
※HTTP/DELETEメソッドを用いて削除します。

$ curl -X DELETE http://_サーバーのIPアドレス_/_指定したドメイン_/キーの名前

 

うまくできましたでしょうか?
以上によりAmazon S3同等の分散ファイルシステムを構築する事ができました。

柔軟に拡張ができるストレージは、スモールスタートで開始し必要に応じて追加する事が可能ですが、
ストレージだけあってメーカー製品では最低500万円~と高額です。

それをオープンソース技術で実現できるのがMogileFSの大きな特徴です。
更にnginxと組み合わせてHTTP通信をサポートする事で、アプリケーションの親和性も改善できました。

続くmogilefs+nginx+nginx mogilefs moduleで分散型オブジェクトストレージを構築(PostgreSQL版・オマケ編)では、
一番負荷がかかるtrackerとMetadataの負荷を減らす方法としてmemcachedとの連携、
ディザスタリカバリ対策、画像を柔軟にリサイズ利用できるモジュールの利用方法についても紹介します。

Tweet about this on TwitterShare on FacebookShare on Google+