[AWS] WordPress-CloudFront-S3 최적의 조합 구성 방법

안녕하세요, 누리클라우드입니다. CMS(Content Management System) 시장에서 WordPress는 2021년도 기준 전세계 압도적 1위를 유지하고 있습니다. 이런 명성에 반해서 WordPress를 기본설정으로만 운영하게 되면 무겁고 느려서 이벤트 등으로 인해 접속자가 늘게 되었을 때 백엔드에 과부하를 발생시키는 단점이 있습니다. 과부하는 곧 사이트 접속 지연 혹은 장애로 이어져 이를 당장 해결하기 위해 급하게 과도한 스펙으로 웹서버나 디비서버를 업그레이드해야 해서 비용발생의 주범이 되기도 합니다.
이번 글에서는 WordPress를 빠르고 가벼우면서도 백엔드에 부하를 주지 않고 비용 발생을 최소화할 수 있는 최적의 조합을 AWS 환경에서 구성하는 방법을 알아봅니다.

들어가기 전에

본 기능 구성에 사용하게 될 AWS 서비스는 VPC 기반의 EC2와 ALB 그리고 S3와 CloudFront입니다. WordPress 설치 및 구성은 간편하고 빠른 설정을 위해 AWS Marketplace에서 제공하는 Bitnami의 AMI를 사용할 것이며, S3 및 CloudFront와의 편리한 연동 구성을 위해 WordPress Plugin인 "W3 Total Cache"를 사용할 것입니다.

기본 개념

기본 구성도는 아래와 같습니다.

전체적으로는 3개의 레이어로 구성하고, Multi-AZ구성을 하여 실제로 리소스를 배치하지는 않아도 유사시에 대비할 수 있도록 합니다.
워드프레스가 설치된 EC2 인스턴스는 프라이빗 서브넷에 구성하고 외부와의 통신은 NATGateway를 통해서 하며 외부로부터의 관리적 접속은 EC2 시리얼 콘솔을 사용합니다.
EFS를 사용하여 두 서버 간 실시간 볼륨 공유를 구성하면 편리하기는 하지만, 워드프레스가 페이지를 생성할 때 수많은 작은 파일들을 읽게 되는데 네트워크 파일의 특성상 이런 상황에서는 전체적인 로딩이 매우 느려지게 되어 권장하지 않습니다. 첨부파일, 테마파일, cs, js 등 주요 정적파일은 워드프레스의 W3 Total Cache 플러그인을 사용하여 간편하게 S3에 업로드하고 공유합니다.
디비서버는 안정적이고 확장성과 성능이 뛰어난 Amazon Aurora RDS를 사용하고, Elasticache는 주요 쿼리와 쿼리결과를 캐싱하여 디비서버의 부하를 덜어줍니다.
CloudFront를 통해 모든 정적인 컨텐츠를 최대한 캐싱하여 로딩 속도를 향상시킵니다. 상황에 따라 사이트 전체를 CloudFront에 배포할 수도 있습니다.

구성하기

여기서는 각 구성 단계별 세부적인 내용을 설명하지는 않으며, 주요 구성 과정에서 주의해야 할 사항들에 대해서 다룹니다.

1. VPC 생성

VPC는 위의 구성도와 같이 기본 VPC가 아닌 별도로 CIDR을 정하여 구성하는 것이 좋습니다. Internet Gateway, NatGateway를 구성하고 적절하게 라우팅 테이블을 설정합니다. VPC엔드포인트는 이 블로그의 [AWS] VPC 엔드포인트를 사용하여S3 – EC2간 프라이빗 통신 구성하기를 참고하시면 좋습니다. 보안그룹도 위 구성도를 참조하여 미리 생성해 둡니다.

2. 웹서버, 로드밸런서 생성

웹서버 용 EC2는 마켓플레이스에서 AMI를 검색하여 'WordPress Certified by Bitnami and Automatic' 이름의 AMI를 선택하여 우선 1개를 생성합니다. 나머지 1개는 모든 구성을 완료하고 커스텀 AMI를 만들어서 복제 생성하는 것이 좋습니다.

로드밸런서를 Application 타입으로 퍼블릭 서브넷에 생성하여 배치하고 위에서 생성한 두 웹서버를 멤버로 하는 타깃그룹을 생성하여 로드밸런서에 연결합니다.

3. RDS, Elasticache 생성

동일한 서브넷에 Amazon Aurora RDS MySQL과 Elasticache Redis를 생성합니다. Redis 서비스 포트인 6379를 보안그룹에서 웹서버 그룹에 대해 허용 설정해 줍니다.
Elasticache는 Total Cache 플러그인을 통해 워드프레스의 디비 캐시, 오브젝트 캐시, 페이지 캐시, Minify 등에 사용되어 동적 컨텐츠의 로딩 속도 향상에 중요한 역할을 합니다.

4. S3 버킷 생성

S3 버킷은 워드프레스에서 포스팅한 글에 포함되는 이미지 등의 첨부파일을 저장하고 공유합니다. 또한, 테마파일이나 스타일 정의파일, 자바스크립트 파일, 폰트파일 등의 정적 컨텐츠를 저장하고 CloudFront의 정적 컨텐츠 오리진으로서 역할을 하게 됩니다.
이 버킷에는 오직 워드프레스가 설치된EC2에서 위에서 구성한 VPC엔드포인트를 경유하는 접근만 허용하도록 VPC 라우팅 및 S3버킷 정책을 설정합니다. 버킷 정책에는 나중에 추가로 CloudFront에서도 읽기 접근이 가능하도록 설정을 추가해야 합니다.
워드프레스에서 나중에 설정하게 될 W3 Total Cache 플러그인은 현재 Access Key 방식으로만 버킷 인증방법을 제공합니다. 따라서, 이를 위한 워드프레스 정적 오브젝트 저장용 버킷을 위한 IAM User를 생성하고 이 유저의 IAM권한의 Access Key를 발행해 둡니다.

<워드프레스 정적 오브젝트 저장용 버킷에 대한 IAM User의 정책 예>

5. CloudFront 배포 생성

S3 버킷에 저장된 워드프레스의 정적 컨텐츠를 빠르게 로딩할 수 있도록 AWS의 CDN 서비스인 CloudFront배포를 생성하고 아래와 같이 안전한 접근과 최대의 캐싱 성능을 내도록 배포 항목을 설정을 합니다.

Behavior 항목:
Compress objects automatically – Yes
Allowed HTTP methods – GET, HEAD
Cache key and origin requests – Headers: None, Query strings: None, Cookies: None

Origin 항목:
S3 bucket access – Yes use OAI (bucket can restrict access to only CloudFront)
; 미리 생성해 둔 OAI가 없다면 여기서 바로 생성하고 버킷 정책도 자동으로 추가해 줄 수 있다.

여기까지 하였다면 이제 본격적으로 워드프레스를 최적화할 준비가 되었습니다.

6. W3 Total Cache 플러그인 설치 및 설정

W3 Total Cache 플러그인은 워드프레스의 성능을 향상시키는 강력하고 다양한 그리고 편리한 기능을 구현해줍니다. 여기서는 이 플러그인의 많은 기능들 중에서 ElastiCache Redis와 CloudFront와 관련된 내용만 다루도록 하겠습니다.

플러그인 설치는 워드프레스 관리자 페이지 > 플러그인 설치 메뉴에서 플러그인 이름 "W3 Total Cache"로 검색하여 나오는 플러그인을 설치 버튼을 눌러 간단히 할 수 있습니다.

설치 후에 관리자 페이지 메뉴에 "Performance"라는 항목이 새로 생기고 여기에서 이 플러그인의 모든 설정을 할 수 있습니다.

이 플러그인은 Page Cache, Minify, Opcode Cache, Database Cache, Object Cache, Browser Cache, CDN, Reverse Proxy 등 8가지 항목에 대한 설정을 지원하고 있습니다. general 메뉴에서 각 항목에 대해 활성화를 하기 전에 먼저 S3, CloudFront CDN, Redis의 연결 설정을 완료하고 또 S3 버킷에 theme files, wp-includes, custom files 등을 업로드해 두어야 합니다. S3 버킷에 업로드는 사용자가 직접 하지 않고 플러그인 페이지에서 편리하게 할 수 있도록 기능을 제공하고 있습니다.

1) CloudFront CDN 설정

아래는 General Settings에서 CDN에 대한 방법을 선택하는 곳입니다. 아직 CDN은 활성화하지 말고, 지원하는 다양한 방식 중 Origin Push방식인 "Amazon CloudFront Over S3"를 선택해 둡니다.

아래는 CDN메뉴에서 정적 오브젝트를 저장할 S3 버킷과 그 버킷을 Origin으로 하는 배포를 입력한 예입니다. 입력 후 업로드 및 배포 테스트도 바로 해볼 수 있어, 설정 오류로 인한 문제를 빠르게 확인할 수 있습니다.

<W3 Total Cache 플러그인의 CDN 설정 예>

아래는 CDN 메뉴에서 각 항목에 대한 캐싱을 CDN으로 할지 여부를 선택하는 곳입니다. 선택하였다면 오른쪽의 업로드 버튼을 눌러서 해당 오브젝트들을 S3 버킷에 업로드해 줍니다. 파일의 개수에 따라 업로드 하는데 다소 시간이 소요될 수 있습니다.

주요 설정을 완료하고 저장한 다음 마지막으로 General Settings 메뉴에서 CDN기능을 활성화합니다.

2) ElastiCache Redis 설정

CDN에서 누락되거나 캐싱할 수 없는 오브젝트에는 디비 캐시를 보완적으로 활용할 수 있습니다. 사실 소규모 사이트라면 굳이 CDN을 사용하지 않고 디비 캐시만 잘 활용해도 가시적인 성능 향상 효과를 볼 수 있습니다. 여기서는 AWS에서 제공하는 관리형 Redis를 사용합니다.

관리형 Redis를 구성도와 같은 서브넷에 생성하고, 접속정보를 설정이 필요한 곳에 입력합니다. 접속이 정상으로 확인되기 전까지는 아래와 같이 캐시 방법만 Redis로 선택하고 기능을 비활성화로 유지합니다.


Redis 접속정보 설정이 필요한 Page Cache, Database Cache, Object Cache 메뉴에서 아래와 같이 Redis에 대한 연결 설정을 입력합니다.

마지막으로, General Settings메뉴에서 각 캐시 기능을 활성화해 줍니다.

접속 테스트

모든 항목에 대한 설정이 완료되고 파일 업로드까지 완료되었다면 캐시가 잘 작동하는지 확인합니다. 페이지가 변경되었는데도 캐시가 동작하게 되면 브라우저에는 새로 고침을 하여도 잘 반영되지 않습니다. 정확한 확인을 위해서는 플러그인 페이지에서 "Purge" 혹은 "empty" 버튼을 클릭하여 캐시를 삭제하여야 합니다. CDN 캐시에서 다수의 파일을 삭제하려면 플러그인 페이지에서 제공하는 방법보다는 직접 AWS 콘솔에서 CloudFront 배포의 invalidation 탭에서 하는 것이 좋습니다.

CDN 캐시를 활성화한 후에는 로딩되는 웹페이지의 소스보기에서 워드프레스로 서비스하는 웹페이지의 이미지를 포함하여 모든 정적 파일들의 경로가 Cloudfront 배포의 URL로 교체된 것을 확인할 수 있습니다.

맺음말

이상으로 WordPress + CloudFront + S3 구성으로 워드프레스의 성능을 향상하는 방법에 대해 설명 드렸습니다. 이 글이 워드프레스의 서버 과부하로 인해 어려움을 겪고 있는 분들에게 다소나마 도움이 되기를 바라겠습니다.