지난번에 redis를 이용한 tomcat 세션 클러스터링에 대해 간단히 알아봤었는데요. 오늘은 redis 와 함께 AWS ElastiCache 에서 서비스하는 클러스터엔진 중 하나인 Memcached를 이용하여 PHP의 세션을 클러스터링하는 방법에 대해 알아보도록 하겠습니다.
Memcached란
memcached는 범용 분산 캐시 시스템으로, 메모리에 데이터와 객체들을 캐시처리함으로써 웹사이트의 속도를 높이기 위해 사용됩니다.
메모리에 키, 값 형식으로 데이터를 저장한다는 점에서 redis와 비슷한 특징을 가지고 있지만, redis는 데이터를 메모리 뿐만아니라 파일 형태로 백업(스냅샷)도 가능하고, 자체적으로 클러스터링(센티넬) 기능을 지원하며, memcached 에 비해 좀 더 다양한 데이터 타입을 지원한다는 점에서 기능 면에서는 redis 가 더 다양한 목적을 위해 사용하기 적합하다고 합니다.
다만, redis 와 달리 memcached 는 멀티쓰레드를 지원하여 다중 처리 속도면에서 redis 보다 더 나을 것으로 생각되며, 휘발성 데이터 캐시를 목적으로 단순하게 사용하기에는 memcached 도 나쁘지 않은 선택이 될 것 같습니다.
구성 및 테스트 환경
테스트 환경은 haproxy 를 통해 라운드로빈 방식으로 로드밸런싱되고 있는 2개의 아파치 웹서버에 그누보드를 설치하여 세션 클러스터링 전과 후의 특이사항을 확인하는 방법으로 진행하였으며, 이미 두 개의 아파치 웹서버에 php 모듈이 연동되어 있고, 그누보드를 설치한 환경을 가정하여 진행하였습니다.
세션 클러스터링이 되어 있지 않을 때
PHP의 경우 기본 값으로 /var/lib/php/session 디렉토리에 파일 형태로 세션 정보가 저장되며, 세션 클러스터링이 되어 있지 않을 때의 경우 2개의 웹서버로 번갈아가며 접속이 이뤄지기 때문에 웹서버1에서 받아온 쿠키(PHPSESSID)를 웹서버2에서 만료된 쿠키로 인식하여 새로운 쿠키를 전송(Set-Cookie)하고 다시 웹서버2에서 받아온 쿠키를 웹서버1에서 만료된 쿠키로 인식하여 새 쿠키를 전송하기 때문에 매번 페이지를 새로고침할 때마다 쿠키가 변경되는 것을 확인할 수 있습니다.
그누보드에서도 이와 마찬가지로, 로그인을 하여도 생성된 세션에 해당하는 쿠키 값을 클라이언트가 유지하지 못하고 계속 쿠키 값이 변경되기 때문에 로그인 창이 계속 나타나는 현상이 발생합니다.
Memcached 설치
Memcached를 설치하기 위해서는 yum 을 통한 설치, 소스 컴파일을 통한 설치, 도커 컨테이너로 생성하는 방법 중 적합한 방법을 선택하여 진행합니다.
# yum 설치
yum install memcached
memcached -h
# 소스컴파일 설치
yum install -y libevent libevent-devel
wget http://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/memcached/memcached-1.4.15.tar.gz
tar zxvf memcached-1.4.15.tar.gz
cd memcached-1.4.15
./configure –prefix=/usr/local/memcached
# 소스컴파일의 경우 실행(-u 옵션은 memcached를 실행할 유저, -l 옵션은 수신에 사용할 아이피주소, -p 옵션은 수신에 사용할 포트)
/usr/local/memcached/bin/memcached -u root -d -l 0.0.0.0 -p 11211
# 도커 컨테이너로 생성
docker run -d -p 11211:11211 --name memcached memcached
php 에 memcached 연동 설정
php 에 memcached 를 연동하기 위해서는 memcached 모듈 혹은 memcache 모듈이 사용됩니다. 두 모듈은 이름이 매우 흡사하지만 별도의 모듈로 memcached 모듈이 상대적으로 더 다양한 함수 사용이 가능합니다.
# memcached 모듈
https://www.php.net/manual/en/book.memcached.php
# memcache 모듈
https://www.php.net/manual/en/book.memcache.php
테스트 구성에서는 memcached 모듈을 사용한여 연동하는 방법을 설명합니다.
# php 연동 모듈(memcached) 설치(yum)
yum install -y php-pecl-memcached
# php 연동 모듈(memcached) 설치(컴파일)
yum -y install libmemcached libmemcached-devel
git clone https://github.com/php-memcached-dev/php-memcached.git
cd php-memcached
git checkout php7
phpize # /usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make && make install
# php.ini 수정
vi /etc/php.ini로 열어서 파일 아래에 아래 내용을 추가한다.
[memcached]
memcache.allow_failover=1
memcache.max_failover_attempts=20
memcache.chunk_size=8192
memcache.default_port=11211
session.save_handler = memcached
session.save_path = "memcached_서버의_아이피_혹은_도메인:11211"
(참고) yum 설치한 httpd의 경우 /etc/httpd/conf.d/php.conf 파일에 session.save_handler, session.save_path 설정값이 중복으로 있기 때문에 주석처리 해줄 것
세션 클러스터링 전과 비교
세션 클러스터링 후 동일하게 클라이언트와 서버가 어떤 쿠키를 주고 받는지 확인합니다. 아래와 같이 동일한 쿠키(PHPSESSID=q9r3ej4asaank9pajp9c2ijlv3)를 통해 웹서버1과 웹서버2에 정상적으로 접속이 되는 것을 확인할 수 있습니다.
또한 그누보드에서도 로그인 창이 계속 나타나는 현상이 확인되지 않고 정상적으로 로그인되는 것을 확인할 수 있습니다.
Memcached 에 저장된 데이터 확인
Memcahced 에 저장된 데이터를 확인하기 위해서는 특이하게 telnet을 이용하여 간단하게 확인이 가능합니다.
# Memcached 서버로 접속(기본 포트 11211인 경우)
telnet memcached서버의_아이피_혹은_도메인 11211
# slab(커널이 사용하는 정규 메모리 할당의 최소 단위) 상태 확인
stats slabs
# 해당 slab의 캐시 덤프(slab 넘버는 stats slabs 명령어를 통해 확인, 아이템의 갯수를 0으로 하면 all)
stats cachedump slab넘버 리스팅할_아이템의_갯수
예시) stats cachedump 7 0
위의 스크린샷 확인 시 PHPSESSID 쿠키의 값과 동일한 이름의 q9r3ej4asaank9pajp9c2ijlv3" 세션 아이디를 확인할 수 있습니다. 저장된 모든 세션 정보 값을 삭제하려면 "flush_all" 명령어로 삭제합니다.
결론
memcached 를 이용하여 php의 세션을 클러스터링하는 방법을 알아보았습니다. php가 연동된 다수의 아파치 서버를 운열할 때에 세션 연동은 필수적이기 때문에 쿠키와 세션의 개념 및 간략한 연동 방식을 알아두는 것은 아키텍쳐를 이해하는데에 도움이 될 것으로 생각됩니다.
또한 AWS에서 서비스하고 있는 ElastiCache(memcached)의 경우 위와 같은 memcahed를 관리형으로 제공하는 것이기 때문에 ElastiCache(memcached)를 실제로 어떻게 활용할 수 있는지 간략하게나마 테스트해봄으로써 실제 사용자가 해당 서비스를 어떻게 활용하는 지 이해할 수 있는 경험이 되었습니다.