본문 바로가기

기타 개발 스킬

대규모 서비스를 지탱하는 기술 6~15장 (서버와 인프라 구축)

반응형

6~10장은 생략!!

과제라 정리하기 애매한 부분

6~10장까지는 데이터 압축, 알고리즘, 전문 검색 엔진 작성 등의 내용을 과제를 통해 보여준다.

그러나 읽어봤을 때 현시점에 정말 필요한 일인가? 하는 의문이 들어서 내용을 생략하려고 한다.

예를 들어 데이터 저장할 때 사이즈를 줄이기 위해서 데이터 압축을 애플리케이션 레이어에서 진행해야 하는지는 의문이다.

책에서는 과제로 정수 데이터를 압축하는 과제를 통해서 perl로 뭔가 하는거 같은데 실질적으로 그렇게까지 하는 회사가 몇 안 되는 것 같다는 생각이 들었다.

지인에게 물어봐도 압축까지 하지 않고 DBMS에서 자체적으로 최적화 해주기를 기대하는 것 같았다.

인코딩 디코딩하는데에 비용 즉, 오버 헤드도 생각하는 것 같다. (대용량 이미지 업로드, 썸네일, ...등에서는 좀 쓰이는 것으로 알고 있다만... 일반적인 데이터까지 줄이는지는 잘 모르겠다...)

알고리즘도 마찬가지로 실무에서 더 최적화시켜서 개선하는 경우가 많지 않아 애매하기 때문에 생략했다.

11. 서버/인프라 입문

엔터프라이즈 vs 웹 서비스 ? 결국은 인프라

현재는 굳이 구분짓지 않고 특성도 거의 유사해졌다는 생각이지만 아래와 같이 정리되어있다.

  • 엔터프라이즈 애플리케이션
    • 트래픽 : 많지 않음
    • 성장성 : 크지 않음
    • 신뢰성 : 극한의 신뢰성
    • 트랜잭션 : 많이 사용
  • 웹 서비스
    • 트래픽 : 극한의 트래픽
    • 성장성 : 폭발적인 성장
    • 신뢰성 : 100% 까지는 아닌 99.9%
    • 트랜잭션 : 비교적 적음

사실 웹 서비스의 핵심은 응답성이라는 것이다.

트래픽이 많기 때문에 모든 요청에 대해서 응답을 최대한 빨리 해줘야하고, 이 응답성을 높이기 위한 여러 전략 중 하나로 바로 바로 확장 가능해야 한다.

응답성과 확장성을 보장해주기 위해서 인프라로 클라우드를 고려하는게 일반적이다.

책이 쓰인 시절만 해도 AWS에서 한계도 있었던 것으로 보이는데 현 시점에서 AWS보다 신뢰할 수 있는 클라우드 시스템이 있을까 싶다.

물론 여전히 클라우드 시스템의 단점이 있다는 것을 알고는 있어야 한다.

그래서 국내 유명 IT 대기업들도 무조건 다 클라우드 시스템을 쓰지 않고 자체적인 인프라를 구축해서 사용하기도 한다.

아무래도 자체적인 인프라의 경우, 모든 것이 자유롭다는 장점이 있고 반대로 클라우드는 제약이 있다. (클라우드에서 제공하는 EC2, S3, ... 등의 인프라 자원을 100% 내 마음대로 사용할 수는 없다.)

그리고 클라우드에서 제공하는 기능에 의존할 수 밖에 없는 단점도 있다.

(요새는 DBA들이 Aurora MySQL같은 것을 좋아하는 것으로 보아 클라우드가 더 안정적일지도 모르겠다...)

12. 확장성 확보에 필요한 사고방식

용도에 맞는 튜닝

책에서는 블로그같은 서비스라 크롤링 봇 같은게 트래픽의 더 많은 지분이 있었던 것 같다.

그래서 사용자용 서버냐 봇용 서버냐에 따라 용도가 달라져서 이를 구분해서 처리해주는 것도 대규모 서비스를 제공하는데 도움이 되는 듯하다.

봇용 서버는 응답성이 조금 느려도 되지만 트래픽이 비교적 많아서 요청 처리 수를 최대화 시키는 방법으로 리소스가 충분한 서버로 로드밸런싱하도록 튜닝했고, 사용자용 서버는 응답이 빨라야하지만 시간대 별로 트래픽이 달라지므로 비교적 낮은 사양 여러 대를 통해 확장하고 축소할 수 있도록 했다고 한다.

결과적으로는 애플리케이션을 만들 때 용도가 나뉠 수 있다면 그에 따른 튜닝을 통해 리소스를 효율적으로 쓰는게 고려되면 좋다! 뭐 이런 내용인 것 같다.

13. 다중성 확보, 시스템 안정화

다중성 확보

요즘에는 데이터 동기화라든지 fail-over에 대한 장애 내성을 갖는 구성 등 너무 많은 솔루션들이 있어서 도입하기 쉬운 상황이지만 역시나 고려하긴 해야한다.

웹 서버의 경우는 로드밸런서를 통해서 몇 대의 서버가 죽더라도 대기 중인 서버로 트래픽을 분산하여 대응이 가능하다.

DB 서버의 경우는 멀티 마스터라는 전략으로, 마스터(쓰기 담당)을 여러 대로 두어 하나의 마스터가 쓰기 작업을 할 때는 다른 서버들은 슬레이브가 되고 반대로 다른 마스터가 쓰기 작업할 때는 다시 다른 서버들은 슬레이브가 되는 방식이다.

이 역시 마스터에서 쓰기 이후 짧은 시간에 동기화 문제가 발생하지만 그 정도는 감수한다고 한다. (현재는 어떻게 쓰고 있는지 잘 모르겠다. 여담으로 마스터/슬레이브는 군주/노예 느낌이라 요새는 Primary/secondary 또는 Primary/replica 로 쓰인다고 한다.)

스토리지 서버의 경우는 분산 스토리지 서버 솔루션 중에 용도에 맞게 잘 선택하면 되는 듯하다.

시스템 안정화

시스템 안정화를 위해서는 너무 빠듯하게 튜닝해서는 안된다.

어느 시스템이 망가지더라도 여유있게 대응 가능하려면 여력이 있어야 한다.

시스템 안정성을 깨는 여러 요인(사용자 기능 추가, 메모리 누수, 사용자 액세스 패턴 변화, 데이터량 증가, 외부 연계 서비스 추가, 하드웨어(메모리, 스토리지, 네트워크)장애)등이 있을 수 있다.

결과적으로 이를 해결할 수 있도록 대책을 미리 만들어야 하는데 통상적으로 앞서 말한 버퍼를 충분히 잡아놓는 것으로 대응 가능하다.

14. 효율 향상 전략

가상화와 자체제작 서버

가상화 기술의 목적

근본적인 목적 = 하드웨어 이용 효율 향상

  • 확장성
    • 오버헤드의 최소화
  • 비용대비 성능
    • 리소스 사용률 향상
    • 운용의 유연함(단순함)
  • 고가용성
    • 환경의 격리

가상화 서버 구축 정책

하드웨어 이용 효율 향상을 위해서 가상화 서버에 어떤 컨테이너, 애플리케이션, ...등 을 어떻게 구성할 것인가를 고려해봐야 한다.

  • CPU가 남아돈다 → 웹 서버를 더 띄우자!라고 생각할 수 있고,
  • I/O 리소스가 남아돈다 → DB 서버를 더 띄우자!라고 생각할 수 있고,
  • 메모리가 남아돈다 → 캐시 서버를 더 띄우자!라고 생각할 수 있다.

요즘은 도커/쿠버네티스 조합으로 즉, 컨테이너를 사용하는 것이 일반적이다. (VM안녕... 🖐🏼)

호스트 OS에 어떤 컨테이너로 조합할 것인가를 고민해볼 수 있다.

만약 A라는 호스트 OS에 Redis같은 캐시 용도의 컨테이너를 올렸다고 가정하면, 해당 컨테이너는 메모리를 많이 사용하지만 CPU나 I/O 점유율은 상대적으로 높지 않을 것이다.

이러한 경우 A라는 호스트에 추가로 컨테이너를 띄울 때, 메모리는 적게 소모하고 상대적으로 여유있는 CPU, I/O 작업이 많은 애플리케이션이 있는 컨테이너를 띄우는 것이 하드웨어 자원을 효율적으로 사용할 수 있는 방법이 될 수 있다.

가상화 기술의 단점

  • 크고 작은 오버헤드
    • CPU 효율 감소
    • 메모리 성능 감소
    • 네트워크 성능 감소
    • I/O 성능 감소
  • 네트워크 단절 등의 불안정 요인 추가

이 중에서 네트워크로 분리되면서 생기는 여러 요인과 성능저하등의 문제가 크리티컬한 부분이 되지만 가상화 기술을 도입함으로써 얻는 이득(고가용성, 자원 사용 효율 향상, 비용 절감, 확장성, ...)이 훨씬 크다면 도입하는 것이 좋을 것이다.

네트워크의 한계

  • PC 라우터의 한계 - 1초에 주고 받을 수 있는 패킷의 크기, 단위의 한계
  • 500호스트 이상 - 1 subnet의 한계
  • 글로벌 서비스 - 1 데이터센터의 한계

네트워크에도 대규모 서비스를 위해 고려해야할 것이 있다.

1기가비트랜, 10기가비트랜 등이 상용중이다.(실제 속도가 그렇지 못하다고 이슈가 되기도 했다.)

어찌되었든 PC라우터에 성능에도 한계가 있다는 것이다.

1초에 주고 받을 수 있는 패킷의 크기와 개수를 추산할 수 있는데 이것 이상이 필요하다면 PC라우터를 병렬화하는 노력도 필요하다.

ARP 테이블(IP와 MAX주소간 변환 담당)을 가지고 통신에 이용하게 되는데 이 테이블의 크기가 그리 크지 않았다. (2010년 당시 900건 전후)

여기에 너무 많은 호스트가 붙으면 특정 호스트로 ping이 가지 않는 문제가 있다고 한다.

그리고 같은 서브넷 안에 호스트를 많이 두면 브로드캐스팅 패킷이 증가하는 문제가 있다.

브로드캐스팅 패킷 수신하는 것만으로도 CPU를 약간 잡아먹는다고 한다.

CDN 사용도 고려해야한다.

CDN이란 세계 각지에 서버가 있고 거기에 미디어를 캐시하여 미디어에 접근할 때, 가장 가까운 서버로 액세스해서 미디어를 다운로드할 수 있도록 하는 것이다.

웹 서비스 구축에 필요한 실전 기술

비동기에 적합한 멀티쓰레드 작업큐

기본적으로 요청에 대해서 동기적으로 모든 처리가 끝난 다음에 응답을 리턴한다.

근데 제공해야할 서비스들이 많아지고 데이터도 많아지며 무거워진다.

그러면 꼭 동기로 처리해야하는 작업인지 아닌지를 구분하여 비동기로 처리할 수 있는 것은 비동기 처리할 수 있도록 해줘야 빠른 응답이 가능해진다.

비동기로 구분했더라도 처리는 반드시 이루어져야 하므로 신뢰성이 상당히 중요하다.

신뢰성이 필요할 때는 DB처럼 불상사가 생겨도 복구가 가능하도록 관리할 수 있는 미들웨어와 함께하는 것이 좋다.

스토리지 선택

적절한 스토리지 선택은 안정성과 성능의 균형을 가져와서 높은 수준의 서비스를 할 수 있게한다.

  • 스토리지(storage) 선택의 조건
    • 신뢰성
    • 데이터의 크기
    • 갱신빈도
    • 원본 여부(원본인지, 가공된 데이터인지, 캐시데이터인지, ...)
    • 액세스 패턴
      • 평균 크기
      • 최대 크기
      • 신규 추가 빈도
      • 갱신 빈도
      • 삭제 빈도
      • 참조 빈도

✔️ RDBMS - 단순히 어떤 DBMS를 선택하느냐도 문제 뿐만 아니라 액세스 패턴에 따라 어떤 스토리지 엔진(InnoDB, MyISAM, ... 등)이 참고되어야 한다.

물론 통상적으로는 특정 액세스 패턴에 특화된 NoSQL같은 것들이 더 적절한 경우가 많다.

✔️ 분산 Key/Value Store - 데이터를 메모리에 캐시하는 용도로 사용한다. 마찬가지로 외부 서비스에서 읽어온 데이터를 캐시해두기도 한다.

캐시로 이용하는 경우에는 메모리만 충분히 있으면 되는 장점이 있다.

저가의 하드웨어를 나열해서 캐시 풀을 구축하면 RDBMS 대수를 줄일 수도 있다.

✔️ 분산 파일 시스템

다뤄야할 파일의 크기, 실시간성이 중요한지 여부 등을 파악하여 적절한 파일 시스템을 선택해야한다. (HDFS 즉 하둡을 많이 사용하는 것으로 보인다.)

캐시 시스템

시스템 용량이 부족해지면 DB서버나 AP서버를 증설하는 것으로 대응할 수 있지만, HTTP 레벨의 캐싱을 수행하는 프록시와 리버스 프록시를 사용할 수 있다.

  • 프록시 : 클라이언트에서 서버로 접근할 때 클라이언트에 두는 프록시
    • 클라이언트의 요청을 프록시 서버가 클라이언트 대신 서버로 전달한다.
  • 리버스 프록시 : 클라이언트에서 서버에 액세스할 때 서버에 두는 프록시
    • 클라이언트 또는 프록시 서버의 요청을 서비스 서버에 전달한다.

독후감

대규모 서비스를 지탱하는 기술을 살펴보면서 어떤 통찰 을 얻기에는 나쁘지 않았다고 보여진다.

특히 OS 캐시 즉 어떻게해서든 메모리 안에서 끝낼 수 있도록 하는 것과 스케일아웃에 기반한 확장성을 갖도록 구성하는 이유와 방법등에 대해서 고민해볼 수 있는 책이었다.

아쉬운 점은 책이 쓰여진지 시간이 10년이나 되어서 강, 산이 바뀐 점이 꽤 컸다.

다른 책들도 좀 보고 대규모 서비스를 위한 인프라에 대한 지식을 채워 넣어야할 필요가 있다.

반응형