프로젝트 지식(2) - 웹서버와 Redis
웹 서버
기본 역할
로컬 서버의 특정 폴더, 디렉토리에 HTML, CSS, JS 등을 넣어두면 이 폴더를 외부에서 접근가능하도록 개방해준다. 그래서 서버에 지정된 웹사이트 주소로 접속하면 이것들을 받아갈 수 있도록 한다.
정적 웹일 때는 단지 정적 파일을 건네주는 편의점 알바, 동적 웹일 때는 직접 파일을 다루는 요리사 역할을 한다.
또한 식당 매니저로 일하기도 하는데 톰캣이나 Django, Node.js 내장 서버 등의 전문 요리사들과 손님들 사이에서 서빙이나 매니지먼트를 담당한다.
WAS
위에서 말한 톰캣이 WAS인데 웹 또는 API 어플리케이션을 실행할 때 이러한 WAS(Web Application Server)가 사용된다. 웹 서버는 PHP 같은 분식은 처리할 수 있지만 Spring 같은 고급한정식이나 일식으로 넘어가면 톰캣과 같은 전문 요리사와 같이 작업해야 한다.
사실 다 정의하기 나름이고 진영마다 배포 구조들도 달라서 다른 언어에서는 딱히 어떤 것이 WAS의 역할이다라고 정의내리는 것이 힘들다. 파이썬의 경우 Gunicorn이 비슷할 수 있는데 이것은 WSGI라고 조금 다른 개념으로 정의되고 Node.js에서처럼 어플리케이션이 WAS 역할까지 하는 경우도 있다.
어쨌든 공통적인 것은 웹서버를 앞 단에 두고, 즉 방문자들을 이 웹서버가 응접실에서 접대하도록 하고 그 뒤에서 WAS가 요리를 하고 있다는 것이다.
Django에서의 웹 서버
Django를 조금 더 살펴보면 장고는 장고만의 웹서버를 사용한다. 개발 목적으로 가벼운 WSGI를 사용한다. 장고도 웹 서버인 것이다. 하지만 프로덕션 과정에서는 따로 웹 서버를 두어 사용해야 한다. 즉 배포를 하려면 다른 툴을 이용하여야 한다는 것이다.
장고에서도 웹 서버(Nginx)와 웹 애플리케이션(Django)간의 연결을 중계하는 WAS가 있는데 Gunicorn, uWSGI 등이 대표적이다.
웹 서버와 WAS를 같이 사용하는 이유
사실 WAS로 정적이든 동적이든 모든 리소스를 제공할 수 있다. WAS로 모든 것을 처리할 수 있는데 왜 웹 서버와 같이 사용하는 것일까?
이는 아파치와 NginX가 정적 또는 가벼운 동적 리소스를 제공하는 역할 외에도 여러 다양한 기능을 가지고 있기 때문이다. reverse_proxy가 대표적인데 이것은 우리가 흔히 알고 있는 forward proxy(사용자가 자신의 정보를 감추고 서버에 접근)과 반대로 사용자들에게 서버의 정보를 감추는 역할을 한다. 서버 내부적으로 파일들이 어느 폴더에 들어있는지, 서비스가 몇 번 포트로 돌고 있는지 등을 감춘다. 이를 통해 보안 문제를 해결할 수 있다.
또한 로드 밸런스를 통해 사용자가 몰릴 때 WAS를 분산해서 사용하게 하는 기능도 있다. 캐싱을 통해 한 번 꺼내온 것들을 다시 힘들게 안 꺼내도 되게끔 따로 모아두게 할 수도 있는데, reverse proxy의 캐싱으로 서버 단 사이에서의 캐싱을 하여 서버로 찾아오는 사용자들이 자주, 반복적으로 찾을 만한 리소스들을 쌓아뒀다가 꺼내준다.
정리하자면 웹서버는 보안과 운영에 더 특화되어 있기 때문에 사용자들을 직접 상대하고, WAS는 뒤에서 동적 요소들을 만들어내는데 집중한다.
Apache vs NginX
Apache가 더 전통적이지만 NginX가 점점 점유율을 따라잡는 추세이다. Apache는 다중 프로세스, NginX는 이벤트로 일을 처리한다.
Apache는 사용자가 새로 올 때마다 테이블을 따로 가져오는 방식이다. 그리고 테이블을 계속 돌아다니면서 여러 손님들을 동시에 상대하는 것이다. 그렇기 때문에 컴퓨터 자원을 많이 소모한다. 반면 NginX는 작은 데스크 하나만 두고 사용자들을 일렬로 세우는 방식이다. 아무래도 컴퓨터에 부담이 덜 하다.
성능과 가벼움을 중요시하는 서비스에서는 NginX, 다양하고 검증된 기능들을 필요로 하는 곳에서는 안정성을 갖춰온 Apache를 사용한다.
Redis
Remote dictionary server의 줄임말로 외부에 있는 딕셔너리라는 자료구조를 이용하는 서버이다.
기본적으로 DB는 데이터를 영속적으로 저장해야 하기 때문에 SSD에 저장한다. 하지만 기술이 점차 발달하면서 메인 메모리에 더 자주 접근하고 덜 자주 바뀌는 데이터를 저장하여 더 빠르게 접근할 수 있게 되었다.
기본적으로 Redis에서 사용하는 캐시는 다음과 같은 순서로 사용한다.
- 웹 서버는 클라이언트 요청을 받아서, 데이터가 존재하는지 캐시를 먼저 확인한다.
- Cache 에 데이터가 있으면 그걸 꺼내주는데, 만약 없으면
- DB 에서 읽어서 -> 먼저 캐시에 저장한다음 클라이언트에게 데이터를 돌려준다.
Redis를 사용할 때 주의할 점이 있다. 우선 Single Thread 서버이기 때문에 시간 복잡도를 반드시 고려해야 한다. 또한 In-memory 특성상 메모리 파편화, 가상 메모리 등의 이해가 필요하다.
Leave a comment