Redis를 페이지 캐시저장소로 이용해 워드프레스 퍼포먼스를 향상 시켜보자.
워드프레스 퍼포먼스때문에 캐시 서버를 사용한다거나, 웹서버의 캐시기능을 사용하거나, 혹은 간단하게 플러그인으로 웹페이지 컨텐츠를 캐싱 해두어 퍼포먼스 를 올리는 경우가 많다.
검색창에 “워드프레스 캐시” 라고만 쳐도 여러가지 사례 및 정보들이 무수히 나온다.
Redis도 깔아봤을겸 이왕 깐김에 해볼만한거 다해보고 싶어서,
검색하다 보니 워드프레스에도 Redis를 이용해 캐싱을 할수 있다는것을 알아내었다.
그리고 사용해보니 흥미가 있는 사람들에겐 꾀 괜찬은거 같아 블로깅 해둔다.
필요파일 다운로드
wp-index-redis.zip 압축을 풀면 php 파일이 나오는데, 이것과 predis.php 두개의 파일을 워드프레스가 설치되어있는 루트 디렉토리에 저장한다.
그리고 wp-index-redis.php 파일이 index.php로 파일명을 수정해야 한다.
(기존에 index.php 파일은 다른이름으로 수정하여 백업해두는것이 좋을거라 생각된다.)
동작방식
소스를 보면 알겠지만 index.php 로 워드프레스가 시작될때
인증 체크를 해서 로그인한 상태면 캐싱 되지 않는 데이터를 보여주고,
아닐 경우 캐시값 확인후 없을 경우 웹페이지 컨텐츠를 캐시로 저장하며, 캐싱된 데이터를 보여주는 구조다.
사용방법 및 주의사항
- Pages are not cached when you are logged in. – 로그인 중에는 캐시 되지 않는다.
 - Cached pages do not expire not unless explicitly deleted or reset (deleting the entire domain cache). – 페이지 캐시는 명시적으로 지우거나 리셋되기전까지는 남아있다.
 - Appending a ?c=y (e.g. domain.com/?c=y) to a url deletes the entire cache of the domain. Only works when you are logged in. – url에 ?c=y 라고 넣어주면 해당 도메인에 대한 모든 캐시는 제거된다. (로그인이 되어있을경우에만 가능하다.)
 - Appending a ?r=y to a url deletes the cache of that url. – url에 ?r=y 라고 넣어주면 해당 페이지의 캐시는 제거된다.
 - Refreshing (F5) a page deletes the cache of that page. – F5 키로 리프레쉬 하면 해당페이지 캐시가 제거된다.
 - Script still works even if allow_fopen is disabled in php. – php 설정으로 allow_fopen이 disabled 라도, 스크립트는 정상적으로 작동한다.
 - Submitting a comment deletes the cache of that page. – 코멘트가 저장될경우에는 캐시는 지워진다.
 - Includes a debug mode, stats are displayed at the bottom most part after . Won’t be deleted by CloudFlare. – 디버그 모드경우, 최하단에 상태가 표시된다. CloudFlare로는 삭제되지 않는다.
 
동작 확인
redis-cli 의 모니터로 상황을 모니터링 해보자.
첫번째 엑세스
1475656746.347044 [0 127.0.0.1:34716] "HEXISTS" "421aa90e079fa326b6494f812ad13e79" "c9db569cb388e160e4b86ca1ddff84d7" 1475656746.374942 [0 127.0.0.1:34716] "HSET" "421aa90e079fa326b6494f812ad13e79" "c9db569cb388e160e4b86ca1ddff84d7" "<!DOCTYPE html>\n<html lang=\"ja\">\n<head>\n<meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <link rel=\"profile\" href=\"http://gmpg.org/xfn/11\">\ . . . \n\n</body>\n</html>\n"
해시 데이터로 저장되는것을 알수 있다.
두번째 엑세스
1475656988.084666 [0 127.0.0.1:34760] "HEXISTS" "421aa90e079fa326b6494f812ad13e79" "c9db569cb388e160e4b86ca1ddff84d7" 1475656988.084772 [0 127.0.0.1:34760] "HGET" "421aa90e079fa326b6494f812ad13e79" "c9db569cb388e160e4b86ca1ddff84d7"
저장되어있는 해시데이터를 불러 오는것을 알수있다.
다른 페이지에 엑세스
1475657088.155784 [0 127.0.0.1:34784] "HEXISTS" "421aa90e079fa326b6494f812ad13e79" "ce1c99c77908f46f2536d4e676c6939f" 1475657088.190624 [0 127.0.0.1:34784] "HSET" "421aa90e079fa326b6494f812ad13e79" "ce1c99c77908f46f2536d4e676c6939f" "<!DOCTYPE html>\n<html lang=\"ja\">\n<head>\n<meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <link rel=\"profile\" href=\"http://gmpg.org/xfn/11\">\n <link rel=\"pingback\" href=\"http://localhost/xmlrpc.php\"> . . \n\n</body>\n</html>\n"
hset {해당 워드프레스 키} {해당 페이지컨텐츠 의 키}
이런 형태로 페이지 마다 캐싱되는것을 알수 있다.
이 기능을 이용해 자작 플러그인을 만들어 특별한 기능을 구현할수 있을거 같기도하다.
뭐 이미 이런 플러그인이 있을지도 모르겠지만…
Apache Bench 로 속도 측정
간단하게 Apache Bench로 동시접속수 100에 10000번의 요청을 시도한다는 가정으로 테스트 해본다.
WordPress
$ ab -n 10000 -c 100 http://localhost/
.
.
Server Software:        nginx/1.11.4
Server Hostname:        localhost
Server Port:            80
Document Path:          /
Document Length:        18728 bytes
Concurrency Level:      100
Time taken for tests:   118.959 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      189260000 bytes
HTML transferred:       187280000 bytes
Requests per second:    84.06 [#/sec] (mean)
Time per request:       1189.593 [ms] (mean)
Time per request:       11.896 [ms] (mean, across all concurrent requests)
Transfer rate:          1553.68 [Kbytes/sec] received
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.5      0       7
Processing:    55 1184  78.6   1182    1386
Waiting:       55 1183  78.6   1182    1386
Total:         62 1184  78.2   1182    1386
Percentage of the requests served within a certain time (ms)
  50%   1182
  66%   1203
  75%   1218
  80%   1228
  90%   1253
  95%   1276
  98%   1301
  99%   1319
 100%   1386 (longest request)
WordPress + Redis
$ ab -n 10000 -c 100 http://localhost/
.
.
Server Software:        nginx/1.11.4
Server Hostname:        localhost
Server Port:            80
Document Path:          /
Document Length:        18728 bytes
Concurrency Level:      100
Time taken for tests:   5.541 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      188650000 bytes
HTML transferred:       187280000 bytes
Requests per second:    1804.77 [#/sec] (mean)
Time per request:       55.409 [ms] (mean)
Time per request:       0.554 [ms] (mean, across all concurrent requests)
Transfer rate:          33248.98 [Kbytes/sec] received
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       4
Processing:     3   55   9.1     52      93
Waiting:        3   55   9.1     51      93
Total:          7   55   9.0     52      93
Percentage of the requests served within a certain time (ms)
  50%     52
  66%     56
  75%     61
  80%     64
  90%     69
  95%     73
  98%     76
  99%     79
 100%     93 (longest request)
Requests per second (초당 처리횟수) 를 보면 알다 싶이 엄청난 차이가 있다.
뭐 페이지 캐싱 이라 당연한거 일수도 있지만…
나름 재밌는 테스트다.
소감
사실 이전에 varnish나 nginx reverse proxy cache로 적용 햇을때가 더 빨르고 올바른 길(?)이지만
Redis의 memory 저장소를 이용하면 어떻게 될까? 라는 호기심이 있어 테스트 해보았는데, 이 역시도 충분히 괜찬은 퍼포먼스 대안이 되지 않을까 싶다.
참고
http://qiita.com/azusanakano/items/3de81c292117d291123c
http://qiita.com/azusanakano/items/19dff3ea63e1e651b62c
http://www.geek.sc/archives/586
																			
														
쿠테
•6년 ago
varnish 를 프론트엔드단 캐싱에 쓰고, redis 를 백엔드 디비 캐싱에 쓰는 방법도 괜찮은거 같아요.