본문 바로가기

개발관련

안정적인 서비스 운영을 위한 정리

반응형

슬라이드 링크  : https://www.slideshare.net/cybaek/201403?from_action=save

 

안정적인 서비스 운영 (설계에서 모니터링까지)

 

설계(Architect)

스케일링이란? - 어떠한 정책에 따라서 서비스에 대한 시스템을 늘리고 줄여주는 서비스

  • Scale Up : 하드웨어 성능을 높이는 방법. ) cpu, ram, storage 업그레이드
  • Scale Out : 하나의 서버 보다는 여러대의 서버를 이용하여 일을 나눠서 처리하도록 하여 성능을 높이는 방법

 

서버 한대에서 시작

  • 쉽게 시작할  있지만 원만한 운영 어려움
  • 이유는 하나의 서버안에  들어가 있으므로  서버가 죽으면 서비스가 멈춤
  • 그리고 디비의 경우 자원이 계속해서 필요하므로(저장) 하드웨어 스케일업을 계속 시켜줘야함
  • 따라서  서버가 주기적으로 멈춰야함

 

두대의 서버(웹서버 1, 디비 서버 1)

  • SPOF(Simple Point Of Failure : 단일장애점)
  • 웹서버가 죽던, 디비서버가 죽던 둘중 하나만 죽으면 모두 정상적인 동작이 안됨.
  • 이유는  서버는 디비서버에 의존하고있고, 클라이언트는 웹서버만 바라보고 있으므로 웹서버가 죽던 디비서버가 죽던 클라이언트는 정상적으로 서비스를 이용할  없는 것임.

 

세대의 서버(웹서버 2, 디비 서버 1)

  • 웹서버가 2 이상이 되면, 트래픽 분산을 위해 로드밸런서를 앞단에 둔다.
  • 로드밸런서를 앞단에 두는 이유는 클라이언트의 진입점을 하나로 두기 위함도 있다.
  • 웹서버를 다중화하여 안전성을 꾀했지만 여전히 DB가 죽으면 서비스안됨. SPOF 이슈가 아직 남아 있음

 

네대의 서버(웹서버 2, 디비서버 2)

  • DB 쓰기는 Master, 읽기는 두대 모두에서
  • 읽기 처리는 두배로 증가
  • 써야할 양도 두배로 증가(Master - Slave간의 데이터 싱크)
  • DB서버를 다중화하여 SPOF 이슈는 해결했지만 DB 관리 포인트가 늘음
  • 어떻게 DB를 잘 관리할 것이냐가 관건

 

셀 아키텍쳐(웹서버 2대, 디비서버 2대)

  • http://highscalability.com/blog/2012/5/9/cell-architectures.html
  • 데이터를 특정 속성 중심으로 물리적 분할
  • 웹서버, 디비서버를 물리적으로 분할
  • 대규모 확장에는 병렬화가 필요하고 병렬화에는 구성 요소가 서로 분리되어야 한다는 아이디어를 기반으로함
  • 약간 MSA(Micro Service Architecture)와 비슷한 느낌임
  • 장점
    • 사용자 기반이 커짐에 따라 모든 크기로 저장할 수 있는 병렬화 단위를 제공함
    • 더 많은 용량이 필요함에 따라 셀이 증분 방식으로 추가됨(셀 단위 스케일링)
    • 하나의 셀 아키텍쳐가 장애가 났을 시 다른 셀에 영향을 미치치 않음(장애를 특정 셀로 고립 가능)
  • 단점
    • 많은 장비가 필요(비용 증가)
    • 제공하는 기능에 따라 셀간 데이터를 조합해야할 수도 있음

로드밸런서(Load Balancer)

    • 로드밸런싱 : 부하 분산을 위해서 가상 IP 통해 여러 서버에 접속하도록 분배하는 기능을 말함
    • 성능 향상, 무중단 서비스 구축(안정성), Scale Up 보다는 비교적 저렴
    • 로드밸런서는 하드웨어가  수도있고, 소프트웨어가  수도 있다.
    • 로드밸런서에도 부하가 많이 물리면 병목현상(Bottle Neck)이 생길 수 있으므로 이중화 하는 것이 좋다.(아니면 DSR 세팅으로 부하 감소를 꾀하거나..)

로드밸런서 이중화 예시

 

 

  • 로드밸런서
    • 로드밸런싱 : 부하 분산을 위해서 가상 IP 통해 여러 서버에 접속하도록 분배하는 기능을 말함
    • 성능 향상, 무중단 서비스 구축(안정성), Scale Up 보다는 비교적 저렴
    • 로드밸런서는 하드웨어가  수도있고, 소프트웨어가  수도 있다.
    • 로드밸런서 동작 알고리즘
      • Round Robin
        • 순차 방식
        • 요청을 순서대로  서버에 균등하게 분배하는 방식
        • 서버 커넥션 수나 응답시간에 상관 없이 모든 서버를 동일하게 처리
        • 다른 알고리즘에 비해서 가장 빠름
        • DNS RR
      • Least Connection
        • 최소 접속 방식
        • 서버에 연결되어 있는 커넥션 개수만 갖고 단순 비교하여 가장 적은 곳에 연결
      • Weighted Least Connections
        • 가중치 최소 접속 방식
        • 서버에 부여된 Weight값을 기반으로 커넥션 수의 개수와 함께 고려하여 연결
      • Fastest Response Time
        • 응답시간방식
        • 가장 빨리 응답하는 서버에 이용자 요구를 연결하는 방법
        • 응답시간은  서버가 패킷 형태의 요구를 송수신하는데 걸리는 시간을 측정한 것이다
      • Adaptive
        • 최소대기방식
        • Open 또는 Pending중인 커넥션을 적게 가지고 있는 서버로 네트워크 커넥션 방향을 지정한다
        • Pending 커넥션은 Full TCP Handshake 완성하지 않은 것으로, 이것은 초당 클라이언트 Thread 수가 증가할  더욱  수행된다
      • Hash
        • 특정 클라이언트는 특정 서버로만 할당시키는 방법
        • 경로가 보장되며 접속자수가 많을수록 분산 및 효율이 뛰어나다
        • 다만 접속자수가 적을수록 공평하게 분산이 안될수도 있다
      • 보통 단순하게 한가지 알고리즘만 선택하지 않고 Least Connection 알고리즘 선택  동등한 수의 Connection 경우 Round Robin 선택하는 방식으로 결합하여 사용한다.

 

    • 로드밸런서 동작방식(Mode )
      • DSR(Direct Server Return) 방식
        • 서버에서 결과를 바로 클라이언트에게 리턴
        • 이러한 모드가 나온 배경은, 인바운드 트래픽 대비 아웃바운드의 트래픽이 높아 나오게됨
        • 기존은 Client -> L4 -> Server -> L4 -> Client 이렇게 . L4 인바운드, 아웃바운드 트래픽이 모두 물려 부하가 크고 리소스 소모가 
        • 이러한 문제를 해결하기 위해 나온 DSR 이렇게 동작함: Client -> L4 -> Server -> Client
        • 아웃바운드 트래픽을 L4 전달하지 않고 직접 클라이언트에게 전달함
        • 사용자가 real server 접근할  출발지와 목적지의 IP 주소를 변조하지 않고, L4에서 관리하는 real server MAC 주소 테이블을 확인해서 MAC주소만 변조한다.
        • 클라이언트의 Request 서버로 전달함에 있어 어떤 헤더를 이용하는지에 따라 L2/L3 DSR 구분하게 된다.
        • L2DSR : MAC 주소 변경을 통해 클라이언트의 Request 전달
        • L3DSR : IP Header 변조하여 서버에 Request 전달
      • Bridge/Transparent Mode
        • 사용자가 서비스를 요청하면 L4 전달된 목적지 IP 주소를 REAL SERVER IP 주소로 변조하고 MAC 주소를 변조해서 목적지를 찾아가는 방식
        • 요청 전달  변조 :
          • 사용자 -> L4 -> NAT(IP/MAC 주소 변조) -> real server
          • 사용자가 L4 호출하면 중간에 NAT(Network Address Translation) 목적지 IP 주소를 real server IP 주소로 변조하고 MAC 주소도 변조한다
        • 응답 전달  변조 :
          • Real server -> NAT -> L4 -> 사용자
          • real server에서 L4 거치면서 출발지(source) IP 주소를 L4 가상 IP 주소로 변조한다
          • 동일 네트워크 대역이므로 MAC 주소는 변조하지 않는다
      • Router Mode
        • Bridge/Transparent Mode 유사하지만 출발지(source) MAC 주소도 변조된다
      • One Arm Mode
        • 사용자가 real server 접근할  목적지 IP L4 스위치 IP 바라본다.
        • L4 도달하면 L4 클라이언트에게 받은 목적지 IP 주소를 L4 IP 주소에서 real server IP real server MAC 주소로 변조한다
        • 되돌아가는 IP L4 IP pool IP 주소로 변조한다.
      • NAT(Network Address Translation)
        • private IP public IP 바꾸는데 사용하는 통신망의 주소변조기

 

    • 대표적인 로드밸런서
      • L4 (Transport Layer) :
        • OSI 7계층  4 Layer 라우팅 하는 스위치
        • Transport Layer(IP + Port) Load Balancing
        • TCP, UDP 프로토콜
        • Port 기반 스위칭 지원
        • VIP(Virtual IP) 이용하여 여러대를 한대로 묶어 부하 분산
        • 주로 Round Robin 방식 사용
      • L7 (Application Layer) :
        • Application Layer(Client Request) Load Balancing
        • HTTP, FTP, SMTP, 프로토콜

 

    • 오픈소스 로드밸런서 HAProxy
      • 기존의 하드웨어 스위치를 대체하는 소프트웨어 로드밸런서로, 네트워크 스위치에서 제공하는 L4, L7 기능  로드밸런서 기능을 제공한다.
      • Proxy 
        • Forward Proxy :
          • 클라이언트 앞단에 존재하며 프록시 서버가 클라이언트 대신 서버에 요청하고 전달받은 결과를 클라이언트에게 전달하는 역할 수행
          • Backend Server에게 Client를 숨길 때 사용
          • Client <=> Forward Proxy → Backend Server
        • Reverce Proxy :
          • 실제 서버 요청에 대해서 서버 앞 단에 존재하면서, 서버로 들어오는 요청을 대신 받아서 서버에 전달하고 요청한 곳에 그 결과를 다시 전달하는 역할 수행
          • Client에게 Backend를 숨길 때 사용
          • Client → Reverse Proxy Server <=> Backend Server
      • HAProxy 기본 동작 방식 
        • HAProxy 기본적으로 reverse proxy형태로 동작한다
          • 1. 최초 접근  서버에 요청 전달
          • 2. 응답  쿠키(cookie) 서버 정보 추가  반환
          • 3. 재요청  proxy에서 쿠키 정보 확인 -> 최초 요청 서버로 전달
          • 다시 접근  쿠키 추가 없이 전달 -> 클라이언트에 쿠키 정보가 계속 존재함(쿠키 재사용)
          • 참고 : https://d2.naver.com/helloworld/284659

HAProxy 동작방식

 

  • HAProxy를 운용하는 다양한 방법이 있으나, 상세한 내용은 링크를 참고할 것 

 

데이터베이스(Database)

  • 데이터베이스 : 고가용성 보장 필요
  • 고가용성이란? (High Avaliability) : 서버와 네트워크, 프로그램 등의 시스템이 상당히 오랜기간동안 지속적으로 정상운영이 가능한 성질을 말함. 가용성이 높다는 뜻으로서, 절대 고장나지 않음을 의미한다. 가용성 99.99%
  • DB 중요하기 때문에 고가용성을 보장하는 것이 가장 중요하다.
  • 고가용성을 보장하는 디비 구성
    • 액티브-스텐바이
      • 하나의 DB 서버는 Active 두고, 다른 하나의 DB 서버는 대기상태인 StandBy 둔다.
      • 만약 Active 장애가 나면, StandBy 절체되어서 고가용성을 보장한다.
      • StandBy 종류
        • Hot StandBy : StandBy측은 가동  즉시 이용가능한 구성. 이게 전환시간이 가장 짧지만 비용이 비싸다.
        • Warm StandBy : StandBy측은 가동  이용가능하게 하기 위해서 나름대로의 준비가 필요한 구성
        • Cold StandBy : StandBy측을 정지시켜 두는 구성. 절체  가동.
      • 액티브-액티브
        • 두개의 DB 서버를 모두 Active 두는 것이다.
        • 장점은 두개  하나가 죽어도 고가용성을 보장한다.
        • 단점은 두개의 DB 서버의 데이터 정합성을 유지해야하기 때문에 속도가 느리다.
      • 마스터-슬레이브(Read Replication)
        • 하나의 DB 서버를 Master 두고 n개의 DB 서버를 복제본(Replication)으로 둔다
        • Insert, update, delete Master에서 수행하고 select Replication에서 수행하여 부하를 분산한다.
        • 데이터가 많아지면 많아질수록 Slave Master 복제하는 시간이 늘어난다. (데이터 싱크)
        • 데이터 싱크 문제로 인해 정말 Select한게 맞는지 재차 확인하는 로직 필요.
    • 클러스터링 : DB의 다중화
    • 샤딩(Sharding) 
      • 파티셔닝의 한 종류, 수평으로 데이터를 쪼개는 방식이다
      • Mysql의 경우 5.1 미만의 버젼에서는 지원하지 않음
    • 파티셔닝(Partitioning)
      • 성능, 고가용성, 유지보수성을 목적으로 논리적인 데이터를 다수의 엔티티로 분할하는 행위
      • 큰 테이블이나 인덱스를 관리하기 쉬운 파티션이라는 작은 단위로 물리적으로 분할하는것을 의미함.
      •  장점
        • 물리적인 파티셔닝으로 인해 전체 데이터의 훼손 가능성이 줄어들고 데이터 가용성이 향상됨
        • 큰 테이블들을 제거하여 관리를 쉽게 해줌
        • 성능이 향상됨
      • 단점 
        •  테이블간의 Join에 대한 비용 발생
        • 테이블과 인덱스를 별도로 파티셔닝할 수 없음. 테이블과 인덱스를 같이 파티셔닝해야함
      • 종류
        • 수평 단편화(Horizontal Partitioning, Sharding)
          • 기존에 하나로 구성될 스키마를 다수의 복제본으로 구성하고 각각의 샤드에 어떤 데이터가 저장될지를 샤드키를 기준으로 분리한다.
          • 예를 들면, 나는 고객의 데이터베이스에서 CustomerId 컬럼을 샤드키로 사용하여 샤딩하기로 하였다. 0 ~ 10000 번 고객의 정보는 하나의 샤드에 저장하고 10001 ~ 20000 번 고객의 정보는 다른 샤드에 저장하기로 하였다. DBA는 데이터 엑세스 패턴과 저장 공간 이슈(로드의 적절한 분산 , 데이터의 균등한 저장)를 고려하여 적절한 샤드키를 결정하게 된다.
        • 수직 단편화(Vertical Partitioning)
          • 하나의 엔티티에 저장된 데이터들을 다수의 엔티티들로 분리하는 것을 말한다.
          • 관계형 DB에서 3정규화와 비슷한 개념으로 접근하면 이해하기 쉽다.
          • 하지만 수직 파티셔닝은 이미 정규화된 데이터를 더 잘게 분리하는 과정이다.

수평단편화, 샤딩 예시
수직단편화 예시

 

사용자인증(Authentication & Authorization)

  • Authentication(인증) : 사용자 인증. 클라이언트가 자신이 주장하는 사용자와 같은 사용자인지를 확인
  • Authorization(인가) : 권한 인증. 클라이언트가 하고자 하는 작업이 해당 클라이언트에게 허가된 작업인지를 확인
  • 세션 : 일정 시간동안 사용자로부터 들어오는 일련의 Request 하나의 상태로 보고  상태를 일정하게 유지시키는 기술
    • 보통 사용자 인증(Log in) 사용
    •  세션 데이터를 서버 어플리케이션을 통해 물리적으로 어떠한 저장 공간에 저장한다.
    • 따라서 보안성은 굉장히 우수하지만, 세션에 대한 서버의 저장공간을 필요로 한다는 단점이 있다.
    • 서버의 메모리에 세션정보를 저장함으로 인하여 병목현상이 생길  있다.
    • 웹서버가 2 이상이면 세션정보에 대해서 모든 웹서버들이 동기화 해야한다. 따라서 구현이 복잡하고  성능적으로 속도가 저하된다.
    • 이런 복잡함과 성능적인 저하 문제를 해결하기 위해 DB Redis, memCached같은 메모리 DB 사용하여 세션 관리 role 분리하는 구현 방식이 탄생함
    • 하지만 이마저도 동기화에 대한 부분만 해소되었을  요청이 많아지면 많아질수록 필요한 메모리도 늘어나고(비용증가) 이에 따라 병목현상이 발생(성능저하)한다는 이슈가 남아있음
    • 이런 부분까지 해결하기 위해 사용자 인증  인증에 대한 정보 저장을 Client 넘기는 구현방식이 탄생함.
    • OAuth2.0 혹은 Json Web Token 사용한 사용자 인증이 이것임.
  • OAuth2.0
    • 사용자 인증  Access Token Refresh Token 전달받아 사용
    • 권한에 대한 부분을 Access Token 사용하여 api 기능을 이용하고, Access Token lifetime 만료되면 Refresh Token 가지고 새로운 Access Token 발급받는다.
  • JWT(Json Web Token)
    • 사용자 인증  Json 형태로  Json Web Token 전달받아 사용
    • 권한에 대한 부분을 JWT 사용하여 api 기능을 이용하고, JWT lifetime 만료되면 다시 사용자 인증을 한다.

 

 

배포(Deploy)

  • 배포가 번거로운 일이 되면 안됨
  • 빠른 롤백이 가능해야함 → 빠른 배포보다 중요!
  • 배포 전에 롤백 시 필요한 작업 미리 준비 → 엔터 한번으로 롤백이 되도록!
  • 모든 장비의 설정 내용이 같은가?
    • Terraform
    • Cloudformation(AWS)
    • Docker

 

속도 개선

  • 어디가 느린지 파악하는 것이 우선
  • 캐쉬적용 → 정적인 파일 
    • 시간적 지역성
      • 한번 읽은 데이터를 곧 다시 읽을 수 있다
      • LRU(Least Recently Used)
        • 사용한지 가장 오래된 element를 자동으로 캐시에서 제거해나가며 데이터를 캐싱할 수 있도록 해주는 자료구조
    • 공간적 지역성
      • 읽은 곳 근처의 데이터를 접근하는 경우가 있다
        • prefetch
          • 연산에 필요한 data들을 미리 가져오는 것을 의미
          • CPU가 연산을 하는 동안 prefetcher가 다음 연산에 필요할 데이터를 유추해서 미리 CPU에서 가장 가까운 cache에 넣어놓음
  • 정책 변경
    • 예) 조회수가 꼭 정확해야하나?
  • 스토리지 
    • RAID
      • RAID(Redundant Array of Inexpensive Disks)의 약자
      • 여러 개의 디스크를 배열하여 속도의 증대, 안정성의 증대, 효율성, 가용성의 증대를 하는데 쓰이는 기술
      • 정책으로 스토리지 속도를 최적화
  • 웹, WAS
    • 각 URI별 응답속도 관리
      • 클라이언트와 가장 가까운 리젼으로부터 Response 받도록
      • 정적인 파일을 내려받는 경우(예, 이미지, 동영상 등) 파일 사이즈를 줄여 최적화 했는지
      • 클라이언트 렌더링 방식이 Lazy Loading이 적용되어있는지
      • 백엔드에는 Slow Query가 없는지
  • 가장빠른 해결책 : 증설

 

운영(Operational)

  • 서비스 오픈은 끝이 아니라 시작
  • 신규 서버 설치
    • 장비를 받아 10분 내에 설치할 수 있도록
    • 코드로 인프라관리(Infrastructure As a Code)
      • Terraform
      • Ansible Playbook
      • AWS Cloudformation
    • 하지만 온프레미스 환경은..?
      • 방법 1 : Shell Script 작성해놓고 실행하면 다 세팅되도록 구성 → Shell 노가다 필요 
      • 방법 2 : 가상머신으로 기본 환경세팅이 되어있는 이미지파일을 만들어 사용
      • 방법 3 : Docker를 쓰자
  • 자동 복구
    • 장애 시 루틴하게 하는 작업
    • 예, 프로세스 재구동 등을 특정 조건일 때 자동으로 수행하도록
  • 배치작업
    • 필요한 기본 인프라
      • 실패시 알림 → Slack
      • 과거 작업 이력 조회 → Jira
      • 여러 서버 묶어서 실행 → Infrastructure As a Code
      • feat. Jenkins
  • 로그처리
    • 수집 + 처리 + 모니터링
    • 흔히 이야기하는 ELK, EFK 스텍
    • 로그로테이션
      • 한정적인 서버 자원 안에서 계속해서 쌓여가는 로그를 주기적으로 저장하고, 삭제하여야함
    • 보관
      • 로그를 얼마나 오랫동안 보관할 것인가는 정책의 문제
    • 조회
      • 얼마나 많은 범위의 데이터를 얼마나 빠르게 처리할 것인가
      • 잘 구축하면 CS처리를 비개발자에게 이관 가능
        • Kibana
        • ReDash
    • 보안
      • 개인정보 저장X 혹은 격리 및 암호화
  • 백업
    • AWS AMI
    • 어떻게 복구하는가
      • 주기적인 인스턴스 백업 → 복구 시 백업했던 AMI 사용하여 복구
  • 품질 관리
    • 각 서버 구간별 처리 속도 관리
    • 데이터베이스
      • Slow Query를 만들지 않는다 → Slow Query 자동 검출 시스템 만들면 좋음 → AWS RDS는 기능을 지원함
      • 동적 쿼리 지양 → ORM 사용 권장
  • 서비스 HealthCheck
  • HTTP 에러 페이지 설정
    • 사용자들은 무의식적으로 새로고침을 반복 → 트래픽!!
    • 에러 페이지는 별도로 정적인 화면을 내려주도록 설정해야함
  • 불필요한 로그는 남기지 말자 → 로그를 찍는 것도 일

 

모니터링(Mornitoring)

  • 경고와 장애 수준으로 분리
    • 장애 이전에 알림이 오도록 해야함
    • 평상시 사용률 20%를 유지하고 있다면, 90%가 아니라 50% 수준에서 경고 알람을 받아야함
    • 주기적으로 수치 점검
      • 시스템의 기능과 사용자 수는 계속 변함
      • 따라서 경고, 장애, 최저 값 세 수치는 주기적으로 리뷰해야함
  • 테스트 활용하여 기능 체크
    • 사용자 인터페이스 레벨의 테스트 모듈을 주기적으로 돌려 서비스 상태 체크
      • 개발 문화 TDD를 지향하자
  • 외부 API를 이용할 경우
    • 외부 서비스에 의존하고있으므로 주기적인 API 체크가 필요
    • 내가 직접 관리하는 서비스가 아니라고 방치해서는 안됨

 

장애 대응

  • 전파 : 메일링 리스트를 이용하여 유관자에게 전파
  • 롤백이 가능하면 롤백이 우선
  • 중요기능 우선 대응
  • 장애 발생 후 꼭 회고를 하도록
    • 모니터링 항목으로 등록
  • 장애 원인을 자동으로 알 수 있다면 스크립트화 시킨다
반응형