Memcached 설치 · 5 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로 memcached가 복제를 처리하도록 하여 복제를 쉽게 하세요

이러한 문제는 개발자들이 애플리케이션에 집중하고 HA, 로드 밸런싱 및 확장성에 대해 너무 신경 쓰고 싶지 않을 때 혼란을 줄 수 있습니다. repcached를 사용하면 최소한 2노드 HA 솔루션을 쉽게 투명하게 설정할 수 있습니다.

간단한 패치로 memcached에 멋진 마스터-마스터 복제를 추가합니다. 이제 로컬 memcached에 연결하기만 하면 복제를 자체적으로 처리합니다.

따라서 애플리케이션은 단순하고 간단하게 유지될 수 있으며, 로컬 POSIX 파일 시스템(이는 DRBD, GlusterFS 등으로 복제될 수 있음), 로컬 데이터베이스(복제를 자체적으로 처리하는 “데이터베이스”)에 연결하고 “memcached 클러스터”의 로컬 인스턴스에 연결합니다. 이 설정은 쉽고 가벼운 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"

그렇게 하면 init 스크립트를 설정하는 것이 매우 간단해집니다. debian 스켈레톤을 사용하고 수정하여:

init 스크립트

#! /bin/sh
### BEGIN INIT INFO
# 제공:             memcached
# 필수 시작:       $syslog
# 필수 중지:        $syslog
# 시작해야 함:         $local_fs
# 중지해야 함:          $local_fs
# 기본 시작:        2 3 4 5
# 기본 중지:         0 1 6
# 간단한 설명:    memcached - 복제된 메모리 캐싱 데몬
# 설명:          memcached - 복제된 메모리 캐싱 데몬
### END INIT INFO
# 작성자: Marcus Spiegel <[email protected]>
#
# 위의 "작성자" 줄을 제거하고 복사하여 수정할 경우
# 자신의 이름으로 바꾸십시오.
# "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 ‘^]’.

이제 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

반대로 시도해보고 즐기세요! 그리고 마지막으로 메모리에 더 많은 값을 푸시한 후 이 노드 중 하나를 종료하세요. 실행 중인 노드는 여전히 모든 데이터에 응답합니다 - 훌륭합니다.

진짜 재미있는 부분은, 사용 불가능한 노드를 다시 시작하면 다른 마스터에서 “잃어버린” 모든 데이터를 얻는 것입니다. 직접 시도해보세요. 이제 다른 노드를 종료하고 다시 시작하면 같은 일이 발생합니다. 한 노드에 설정된 데이터도 다른 노드가 다운되어 있는 동안 설정된 데이터는 시작 후에 오는 노드에 추가됩니다.

이 설정은 현재 2노드 복제 설정만 가능합니다. 4노드 클러스터를 구축하여 복제와 분배를 결합한 RAID10 설정을 생각해보세요… 또는 다른 무언가. 적어도 이 2노드 HA 설정에서 repcached는 매력적으로 작동합니다.

개인적으로는 다음에 3노드의 원을 시도해보고 싶습니다 :) (아마도 그 원의 부족을 메우기 위해 heartbeat와 함께).

Share: X/Twitter LinkedIn

새 게시물을 받은 편지함에서 받기

스팸은 없습니다. 언제든지 구독 해지 가능합니다.