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 를 백엔드 디비 캐싱에 쓰는 방법도 괜찮은거 같아요.