Memcached · 3 min read · Jan 20, 2026

方法: Debian Lenny に repcached "組み込みサーバーサイドレプリケーション" で Memcached をインストールする

方法: Debian Lenny に repcached “組み込みサーバーサイドレプリケーション” で Memcached をインストールする

人々はおそらく memcached ( http://memcached.org/) とその高性能な名前-値ベースのメモリオブジェクトキャッシュインターフェースについて知っているでしょう。その主な目的は、マルチノード環境で使いやすい分散キャッシングエンジンを提供することです。memcached にレプリケーションを処理させたいと思ったことはありますか?

高可用性機能を追加したい場合は、クライアント(-ライブラリ)にデータのレプリケーションをすべてのノードに処理させることをお勧めします。たとえば、php セッションのストレージバックエンドとして memcached を使用する場合は、次のように設定します:

# php memcache モジュールの設定
extension=memcache.so
session.save_handler = memcache
session.save_path = "tcp://192.168.168.61:11211?persistent=1,tcp://192.168.168.62:11211?persistent=1"

これで、セッションは両方のノードに分散(レプリケートされず)されます。一方のノードがダウンすると、そのデータはすべて失われます。memcached をパフォーマンスブースターおよび「キャッシュ可能」データの配布者としてのみ使用する場合は、それが問題になることはありません: 失われたデータはキャッシュエントリを作成する際に行われたように補充されます。

セッションデータをレプリケートするには、各ノードに独自に接続するカスタムセッションハンドラーを使用する必要があります… レプリケーションのために。同様に、愛する memcached に独自のキャッシュオブジェクトを書き込みたい場合も同様です。それでも、アプリケーションは書き込むすべてのノードを知っている必要があります。

repcached によってレプリケーションを簡素化する

これらの問題は、アプリケーションに集中したいだけで、高可用性、負荷分散、スケーラビリティについてあまり気にしたくない開発者を混乱させるかもしれません。repcached を使用すれば、少なくとも 2 ノードの HA ソリューションを簡単かつ透明に設定できます。

シンプルなパッチを適用することで、memcached にファンシーなマスターマスターレプリケーションを追加します。これで、ローカルの memcached に接続するだけで、レプリケーションを自動的に処理します。

したがって、アプリケーションは単純でシンプルなままで、ローカルの POSIX ファイルシステム(DRBD、GlusterFS などでレプリケートされる可能性があります)、ローカルデータベース(お察しの通り: “自動的にレプリケーションを処理する”)を使用し、”memcached-cluster” のローカルインスタンスに接続します。このセットアップは、簡単で軽量な HA スケーラビリティのためのよりシンプルで透明なオプションを開きます。

2 ノードクラスタのインストール、設定、およびテスト

まず、repcached パッチのコピーを取得するか、http://repcached.lab.klab.org/ から事前にパッチされた memcached ソースをダウンロードします。インストール前に解決する必要がある libevent への依存関係があります。

root@ha-01 ~ # apt-get install libevent-dev

次に、解凍してディレクトリに移動します:

root@ha-01 ~ # tar xvf memcached-1.2.8-repcached-2.2.tar
root@ha-01 ~ # cd memcached-1.2.8-repcached-2.2/

–enable-repcached オプションで設定します。

root@ha-01 ~/memcached-1.2.8-repcached-2.2 # ./configure –enable-replication
root@ha-01 ~/memcached-1.2.8-repcached-2.2 # make
root@ha-01 ~/memcached-1.2.8-repcached-2.2 # make install

以前にインストールされた memcached.dep パッケージについてあまり心配しないでください。この手動インストールは、/usr/local/bin/memcached にバイナリをインストールし、”元の” memcached を /usr/bin/memcached にそのまま残します。

Debian パッケージとは異なり、/etc/default/memcachedrep(rep => ‘レプリケーション’)にシンプルなデフォルト設定を使用してコマンドラインオプションを提供することをお勧めします:

デフォルト設定

## レプリケーションモードで memcached を起動するための追加コマンドラインオプション
# -x < ip_addr > マスターレプリケーションサーバーのホスト名または IP アドレス
# -X < num > マスターの TCP ポート番号(デフォルト: 11212)
DAEMON_ARGS="-m 64 -p 11211 -u root -P /var/run/memcachedrep.pid -d -x 192.168.168.2"

これで、Debian スケルトンを使用して init スクリプトを簡単に設定できます:

init スクリプト

#! /bin/sh
### BEGIN INIT INFO
# Provides:             memcached
# Required-Start:       $syslog
# Required-Stop:        $syslog
# Should-Start:         $local_fs
# Should-Stop:          $local_fs
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    memcached - メモリキャッシングデーモンレプリケート
# Description:          memcached - メモリキャッシングデーモンレプリケート
### END INIT INFO
# Author: Marcus Spiegel <[email protected]>
#
# 上記の "Author" 行を削除し、
# このスクリプトをコピーして変更する場合は自分の名前に置き換えてください。
# "set -e" を使用しないでください
# PATH は、mountnfs.sh スクリプトの後に実行される場合にのみ /usr/* を含めるべきです
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="memcachedrep"
NAME=memcached
DAEMON=/usr/local/bin/$NAME
DAEMON_ARGS="--options args"
PIDFILE=/var/run/memcachedrep.pid
SCRIPTNAME=/etc/init.d/$DESC
VERBOSE="yes"
# パッケージがインストールされていない場合は終了
[ -x "$DAEMON" ] || exit 0
# 設定変数ファイルが存在する場合は読み込む
[ -r /etc/default/$DESC ] && . /etc/default/$DESC
# VERBOSE 設定と他の rcS 変数を読み込む
. /lib/init/vars.sh
# LSB log_* 関数を定義します。
# このファイルが存在することを確認するために lsb-base (>= 3.0-6) に依存します。
. /lib/lsb/init-functions
#
# デーモン/サービスを開始する関数
#
do_start()
{
    # 戻り値
    #   0 デーモンが開始された場合
    #   1 デーモンがすでに実行中の場合
    #   2 デーモンを開始できなかった場合
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
        || return 1
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
        $DAEMON_ARGS \
        || return 2
    # 必要に応じて、リクエストを処理する準備が整うまでプロセスを待つコードを追加します
    # これは、後で開始されるサービスに依存するものです。最後の手段として、しばらく待ちます。
}
#
# デーモン/サービスを停止する関数
#
do_stop()
{
    # 戻り値
    #   0 デーモンが停止された場合
    #   1 デーモンがすでに停止されていた場合
    #   2 デーモンを停止できなかった場合
    #   他は失敗が発生した場合
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
    RETVAL="$?"
    [ "$RETVAL" = 2 ] && return 2
    # このスクリプトからのみ実行されるデーモンであれば、子プロセスが終了するのを待ちます。
    # 上記の条件が満たされない場合は、後で開始されるサービスに必要なリソースがすべて解放されるまで待つコードを追加します。最後の手段として、しばらく待ちます。
    start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
    [ "$?" = 2 ] && return 2
    # 多くのデーモンは終了時に pidfile を削除しません。
    rm -f $PIDFILE
    return "$RETVAL"
}
#
# デーモン/サービスに SIGHUP を送信する関数
#
do_reload() {
    #
    # デーモンが再起動せずに設定を再読み込みできる場合(たとえば、SIGHUP を送信された場合)、
    # ここでそれを実装します。
    #
    start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
    return 0
}
case "$1" in
  start)
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
    do_start
    case "$?" in
        0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 
        2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    esac
    ;;
  stop)
    [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
    do_stop
    case "$?" in
        0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 
        2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    esac
    ;;
  #reload|force-reload)
    #
    # do_reload() が実装されていない場合は、これをコメントアウトし、
    # 'force-reload' を 'restart' のエイリアスとして残します。
    #
    #log_daemon_msg "Reloading $DESC" "$NAME"
    #do_reload
    #log_end_msg $? 
    #;;
  restart|force-reload)
    #
    # "reload" オプションが実装されている場合は、
    # 'force-reload' エイリアスを削除します。
    #
    log_daemon_msg "Restarting $DESC" "$NAME"
    do_stop
    case "$?" in
      0|1)
        do_start
        case "$?" in
            0) log_end_msg 0 ;;
            1) log_end_msg 1 ;; # 古いプロセスがまだ実行中
            *) log_end_msg 1 ;; # 起動に失敗
        esac
        ;;
      *)
        # 停止に失敗
        log_end_msg 1
        ;;
    esac
    ;;
  *)
    #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
    echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
    exit 3
    ;;
esac
:

テスト

両方のノードに repcached を設定した後は、テストする必要があります。各ノードの memcached に telnet で接続できます:

root@ha-01 ~ # telnet 127.0.0.1 11211

Trying 127.0.0.1…
Connected to 127.0.0.1.
Escape character is ‘^]’.

次に、1 つのノードに対してテスト値を書き込むために set コマンドを発行します:

set foo 0 0 3
bar
STORED

別のノードに移動し、接続して読み取ってみてください:

root@ha-02 ~ # telnet 127.0.0.1 11211

Trying 127.0.0.1…
Connected to 127.0.0.1.
Escape character is ‘^]’.
get foo
VALUE foo 0 3
bar
END

逆に試してみて、楽しんでください!最後に、メモリにいくつかの値をプッシュした後、これらのノードの 1 つをシャットダウンします。実行中のノードは、すべて のデータに応答し続けます - 素晴らしい。

本当に楽しい部分は、利用できないノードを再起動すると、他のマスターからすべての「失われた」データを取得することです。自分で試してみてください。同様のことが、今別のノードをシャットダウンして再起動した場合にも起こります。片方のノードがダウンしている間に設定されたデータも、起動後に新しいノードに追加されます。

このセットアップは、現在のところ 2 ノードのレプリケーションセットアップに対応しています。レプリケーションと配布を組み合わせた RAID10 セットアップのような 4 ノードクラスタを構築することを考えてみてください… あるいは何か。少なくともこの 2 ノード HA セットアップでは、repcached は素晴らしいパフォーマンスを発揮します。

個人的には、次に 3 ノードのサークルを試してみたいです :) (おそらく、サークル内の不足を解消するためにハートビートと一緒に)。

Share: X/Twitter LinkedIn

新しい投稿を受信箱で受け取る

スパムはありません。いつでも購読を解除できます。