쿠버네티스 마스터

분산 시스템 디자인 패턴

Sidecar pattern

메인 어플리케이션 컨테이너 + 사이드카 컨테이너

보통 메인 어플리케이션은 사이드카 컨테이너의 유무에 영향받지 않도록 해야됨. 그에 따라 사이드카 컨테이너가 수행하는 부분에 수정사항이 발생해도 메인 어플리케이션 컨테이너는 수정하지 않고 배포할 수 있음. 그리고 사이드카 컨테이너가 수행하는 작업이 메인 어플리케이션에게 부하를 주지도 않음.

ex) log aggregation side car container. 메인 어플리케이션은 로컬에다가 로그를 파일로 쌓고 사이드카 컨테이너는 그 파일을 읽어서 로그 서버로 보내는 역할만 수행. 메인 어플리케이션은 사이드카 컨테이너가 있던지 없던지 정상적으로 작업 수행

Ambassador pattern

메인 어플리케이션 컨테이너 + 엠베서더 컨테이너

외부 서비스를 마치 로컬에 있는 것 처럼 구성하는 패턴. 외부의 서비스를 참조해서 각종 작업을 대행해주는 로컬 엠베서더 컨테이너를 하나 띄워놓고 메인 어플리케이션 컨테이너는 모두 이 로컬 컨테이너를 통해서 작업을 수행하는 방식. 이렇게 하면 위와 마찬가지로 서비스 구성이 바뀌거나 했을 때 메인 어플리케이션 변경 없이 엠베서더 컨테이너만 갈아끼우면 된다는 장점이 생김. 뿐만 아니라 로컬 엠베서더 컨테이너에 failover나 load balancing같은 추가기능을 넣을 수 있고 마찬가지로 메인 어플리케이션에 관계없이 변경이 가능.

ex) Consul을 이런 식으로 구성할 수 있는데, 실제 Consul 서비스는 외부에 Server모드로 3대를 띄워서 쿼럼을 구성해놓고, 로컬에다가 Client모드로 1대 띄워서 외부 쿼럼을 참조하도록 세팅. 이렇게 하면 consul에다가 kv 요청같은걸 보낼 때 localhost:8500으로 쏘기만 하면 외부 쿼럼의 존재유무를 몰라도 원하는 대로 동작하게 할 수 있음.

Adapter pattern

메인 어플리케이션 컨테이너 -> 어뎁터 컨테이너

서로 버전이 다른 컨테이너가 있고, breaking change가 발생하여 서로 output이 다른 상황에서 동일한 output을 만들어주기 위해서 사용하는 패턴. 어댑터 컨테이너는 모든 업데이트가 끝나고 output이 동일해질 때 까지만 유지.

쿠버네티스 API 구성

Kubernetes API

가장 기본되는 API. Pod, Service 등 쿠버네티스의 기본 요소들에 대한 CRUD는 물론 그 이상의 API도 포함.

일반적으로 /api/{api version}/{api path} 의 형태로 구성되어있음.

Autoscaling API

Node의 resource에 따라 Pod group을 생성, 삭제 등 관리하는 autoscaler 제어용 API

/apis/autoscaling/v1/{path}

Batch API

배치 API를 통해서 작업을 수행하게 되면 1회용 Pod이 생성되고 작업이 끝나면 종료된다.

쿠버네티스 컴포넌트 구성

마스터 컴포넌트

마스터는 일반적으로 하나의 노드에게 일임하는게 보통. 필요하다면 여러 노드에 분산시킬 수도 있음.

API 서버

API서버는 scale out이 쉽도록 stateless로 구성되어있음. 모든 데이터는 etcd에 저장.

Etcd

분산 데이터 저장소. 전체 클러스터 상태를 기록.

컨트롤러 매니저

여러 매니저를 하나의 바이너리로 통합한 도구. 복제 컨트롤러, 포드 컨트롤러, 서비스 컨트롤러, 엔드포인트 컨트롤러 등이 포함되어있으며 내부적으로는 쿠버네티스 API를 호출하는 식으로 동작.

스케쥴러

Node를 사용해서 Pod를 Scheduling. Resource 상태, 서비스 상태, 하드웨어 및 소프트웨어 정책 제약 사항, 친화 및 비친화 명세 항목. 데이터 지역성, 마감시간 등 고려할 사항이 많음.

DNS

1.3부터 표준 클러스터에 포함되어있음. 일반적인 포드와 동일하게 스케쥴링됨. headless service를 제외하고 모든 서비스와 pod는 DNS domain을 가짐.

노드 컴포넌트

마스터 노드와 상호작용하면서 작업 수행 및 상태 업데이트.

프록시

각 노드마다 있으며 low level 네트워크 관리업무 수행. 서비스를 지역적으로 반영하고 TCP, UDP forwarding을 수행하며 설정 및 Environment, DNS를 통해서 클러스터 IP 탐색.

큐브릿

쿠버네티스 노드의 핵심 컴포넌트. 마스터와 통신하는 주체이며 pod들을 관리 및 감독.

  1. API 서버에서 pod secret 다운로드
  2. volume mount
  3. pod container 실행
  4. node, pod state report
  5. container health check

쿠버네티스 런타임

런타임 인터페이스

쿠버네티스는 특정한 구현 코드 및 바이너리를 제공하지는 않고 오직 인터페이스만 정의해서 제공한다. 이 인터페이스는 주로 Pod과 컨테이너를 연결하고 관리하는 종류가 많다. 쿠버네티스는 실질적으로 컨테이너를 제공하고 명령을 실행하는 런타임 엔진을 별도로 요구한다.

런타임 엔진

  1. Docker
  2. rkt : Core OS에서 파생됨. 데몬을 가지지 않고 systemd와 같은 OS init system에 따라 수행됨. 쿠버네티스 런타임 엔진으로 Rktnetes 제공. Core OS 기반 클러스터를 운영해야되는 경우 고려해봄직함
  3. hyper container : cgroup 대신에 hypervisor을 사용해서 격리기능을 구현한게 특징이며 여타 가상화 방식에 비해 자체 guest kernel을 통해서 가벼운 VM을 사용. 베어메탈에서 동작. 쿠버네티스 런타임 엔진으로 Hypernetes 제공. Openstack 컴포넌트와 hyper container으로 구성되어있음. host kernel을 공유하지 않기 때문에 다른 경쟁자에 비해서 좀 더 높은 격리도.

appc 표준?

CI/CD

이미지 생성시 smart labeling을 통해서 일종의 태깅 또는 버저닝 가능

전체 클러스터를 로컬에서 실행 가능. 필요하다면 데이터 스냅샷 및 테스트용 데이터 제공해야 함.

중앙 집중 로깅

2개 이상의 노드, 포드, 컨테이너를 가지는 시스템의 경우 중앙 집중 로깅 또는 클러스터 수준 로깅 필요. 각 노드에 로그 에이전트를 실행시키고 노드의 모든 메세지르 메타데이터와 함께 중앙 저장소로 전송 및 안전하게 저장하는 것.

필요한 이유

  1. 각각의 포드 또는 컨테이너의 로그를 매번 찾아가서 확인하는 것은 지나치게 큰 노력이 필요하고 덕분에 실무에 적용하기 어려움
  2. 전체 시스템을 모니터링하기 힘드며 필터링되는 로그가 많음
  3. 컨테이너의 휘발성 생성주기에 따라 발생하는 로그의 손실을 막기 위하여

fluentd, elasticsearch, kibana 등을 활용할 수 있음.

노드 문제 탐지

Node에서 생길 수 있는 문제

  • cpu 손상
  • 메모리 손상
  • 디스크 손상
  • kernel deadlock
  • filesystem 손상
  • docker daemon 손상

이 경우 문제가 발생한 node에 지속적으로 pod을 스케쥴링하면 전체적인 서비스에 문제가 생길 수 있음. kubelet이나 cAdvisor은 이러한 부분을 감지할 수 없으므로 다른 수단 필요.

노드 문제 탐지기

kubenetes의 모든 node에서 실행되고 위에서 언급한 문제를 감지할 수 있는 pod. 따라서 node에 문제가 발생해도 정상작동할 수 있어야하고 낮은 오버헤드로 마스터에 부하를 주면 안됨.

node에 생길 수 있는 문제는 너무 다양하고 또 새롭게 생기고 사라질 수 있기 때문에 모든 문제를 한꺼번에 처리하는 코드를 짜는 것은 불가능. 따라서 노드 문제 탐지기는 master에게 node에 발생한 문제를 보고하는 핵심 기능과 특정 문제를 탐지하는 기능 두 가지로 나눠서 설계되어야 함. 이 때 보고를 위한 API는 일반적인 조건 및 이벤트를 기반으로 함.

DaemonSet

모든 node를 위한 pod. DaemonSet을 정의하면 클러스터에 자동으로 추가되고 모든 node에서 하나씩 pod을 생성해서 가져온다. node와 daemonSet pod은 1:1로 매핑되고 pod 인스턴스가 죽으면 재생성.

Problem Daemons

문제 탐지는 각 컨테이너에서 독립된 Problem Daemon으로 실행되어야함. 이렇게 하면 유연하게 변화에 맞춰 새로운 문제 탐지기를 추가하고 개선할 수 있음. 그리고 master의 control plane은 복구 가능한 노드 문제는 알아서 자가 치료하도록 remedy controller를 포함.

문제 예방 및 해결법

견고한 시스템 설계

발생 가능한 장애의 종류, 위험성 및 발생 가능성과 그 영향, 비용을 아는 것이 우선. 그 이후에 예방 및 완화법, 손실 방지, 복구 전략 등을 취할 수 있음.

하드웨어 장애

  1. 노드의 응답이 없는 경우
    1. 로그, 진단 정보를 사용할 수 없어 어느 문제인지 판단하기 어려움.
    2. 우선 노드의 응답이 언제까지 있었는지 확인할 것.
    3. 만약 방금 클러스터에 새로 추가된 노드라면 노드 설정 문제일 가능성이 큼.
    4. 클러스터에 이미 노드가 추가되어있던 상태라면 모니터링 데이터나 로그를 확인할 수 밖에 없음.
  2. 노드의 응답이 있는 경우
    1. 디스크, 코어 장치 등 하드웨어 장애일 가능성이 있음.
    2. 문제 탐지기가 동작하는 상태라면 장애 감지 가능.
    3. 또는 Pod 재시작 및 작업에 걸리는 시간이 지연되는 것으로 예상 가능

클라우드 환경이라면 그저 새로운 VM으로 갈아끼우는 것으로 해결 가능. 만약 여분의 노드 풀을 가지고 있다면 사설 호스팅 및 베어 메탈에서도 가능한 방법. 문제 해결 컨트롤러를 사용해서 문제 또는 누락된 상태 검사를 확인하고 잘못된 노드를 자동으로 빼거나 고치도록 설정 가능.

할당량, 공유, 제한

잘못된 케이스

  1. 노드의 자원이 부족해서 pod 스케쥴링이 이루어지지 않는 경우
  2. pod 구성이 잘못되어서 노드의 자원이 낭비되고 있는 경우
    1. 노드에 비해서 pod이 너무 적거나 작은 경우
    2. pod이 요구하는 cpu, memory, nerwork 등 자원 비율과 노드의 자원 비율이 다른 경우

잘못된 설정

  1. 부정확한 라벨링
  2. 복제 컨트롤러 없는 포드 스케줄링
  3. 부정확한 서비스 포트 명세
  4. 부정확한 ConfigMap

이 외에도 가능한 시나리오가 너무 많으므로 가능하면 자동 배포 프로세스를 갖추고 로그 및 모니터링 시스템을 확실히 갖추는게 좋다.

비용 대 성능

클라우드

필요에 따라 탄력적으로 자원을 할당하고 해제하는 것이 가능. 그러나 DDOS 공격이 발생하면 예상 외의 큰 비용이 발생할 수 있으므로 신중하게 모니터링하고 신속하게 대응할 수 있어야 함.

고가용성과 신뢰성

장애가 발생하는 것은 피할 수 없는 일이므로 몇 개의 컴포넌트에 장애가 발생해도 전체 시스템에 문제가 생기지 않도록 신뢰성 있는 시스템을 설계해야 함.

중복성

  • 장애 발생 시 즉시 갈아끼울 수 있도록 컴포넌트를 중복해서 구성
  • 쿠버네티스는 복제 컨트롤러와 복제 집합 형태로 stateless pod를 관리되지만 etcd와 마스터 컴포넌트의 경우에는 따로 중복 구성해둘 필요가 있음
  • 클라우드 플랫폼이 아니라면 여분의 하드웨어 리소스도 필요

핫 스와핑

  • 시스템 정지 없이 일부 컴포넌트를 즉시 교체할 수 있게 만드는 것
  • 말하자면 무중단 서비스
  • 컴포넌트를 저장소 컴포넌트와 stateless 컴포넌트로 엄격하게 구분해서 설계해야 핫 스와핑이 간단해짐.
  • stateful한 컴포넌트의경우 두 가지 선택지 존재
    • 진행중인 트랜잭션 포기
      • 클라이언트에 retry 로직이 있을 경우 손쉽게 구현됨
      • 상대적으로 쉬운 방법
    • 핫 레플리카 동기 유지
      • 모든 트랜잭션에 대해서 두 개 이상의 복사본이 필요
      • 성능상 상당한 오버헤드 발생
      • 상대적으로 복잡하고 손상되기 쉬움

리더 선출

  • 상호 협력 및 작업 분배가 가능한 여러 동일 컴포넌트를 구성하고 그 중 하나를 리더로 선출해서 일부 작업을 직렬화
  • 중복성과 핫 스와핑의 조합
    • 컴포넌트는 모두 중복 배치되고 만약에 리더 컴포넌트가 장애가 발생하면 다른 컴포넌트 중 하나로 핫 스와핑

스마트 로드밸런싱

  • 요청이 들어오면 여러 컴포넌트에 적절하게 분배
  • 일부 컴포넌트에 장애 발생 시 그 컴포넌트는 분배 대상에서 제외, 서비스 용량 복구 작업을 위해 새로운 컴포넌트를 프로비저닝하고 다시 컴포넌트 리스트를 업데이트할 수 있어야 함
  • 쿠버네티스는 endpoint, label을 통해서 로드밸런싱 지원

멱등성

  • 동일한 작업을 여러번 수행해도 같은 결과를 보장해야 함
    • 분산 환경에서 요청이 적어도 한번 수행되도록 보장하는 것은 쉬운 편이지만 정확하게 한번만 수행되도록 강제하는 것은 어렵거나 비용이 훨씬 많이 드는 편
    • 어떤 컴포넌트에서 장애를 감지하고 다른 컴포넌트로 그 작업을 옮겼을 때, 원래 컴포넌트에서도 작업을 수행하고 새로 옮긴 컴포넌트도 작업을 수행해서 결과적으로 같은 작업을 여러 번 하게 될 수 있음

자가 치료

  • 컴포넌트에 장애가 발생하는 경우 사람이 직접 손대지 않아도 자동으로 치료될 수 있게 구성하는 것
  • 쿠버네티스의 복제 컨트롤러와 복제 집합
  • 장애가 한 pod를 넘어 여러 pod으로 전파될 경우 치료 컨트롤러와 같은 컴포넌트 필요
  • 자동 문제 탐지, 자동화 솔루션이 요구됨
  • 할당량 및 제한을 둬서 DDOS 공격 등의 상황에서 예상치 않은 동작을 예방해야함

고가용성 쿠버네티스 구성

고가용성 클러스터 생성

  • 마스터 컴포넌트 반드시 중복 구성
    • etcd는 클러스터로 배포되어야 함
    • 쿠버네티스 API 서버가 중복 구성되어야함
    • 힙스터 저장소 등 보조 클러스터 관리 서비스도 중복 구성되어야 함

안정적인 노드 생성

  • 대부분의 장애는 일시적 장애, 따라서 docker daemon, kubelet이 이러한 상황에 자동 재시작되도록 구성하면 대부분의 기본적인 장애에 대응할 수 있음
  • OS의 init 시스템 등에 등록해두는게 일반적
  • monit 사용 고려

클러스터 상태 보호

쿠버네티스는 클러스터의 상태 정보들을 etcd에다가 저장

etcd 클러스터링

적어도 3개 이상의 노드를 사용해서 클러스터를 구성해야하며 더 많은 홀수 노드로 구성할 수록 신뢰성을 확보할 수 있음.

정적 탐색

각 etcd의 ip, hostname을 수동으로 관리하는 방법. 쿠버네티스의 외부에 있는 etcd 클러스터를 쓴다는 이야기는 아니다. etcd 노드는 마찬가지로 pod으로 동작한다.

etcd 탐색

기존 클러스터와 새로운 클러스터 노드를 서로 찾을 수 있게 만듬. 보통 etcd bootstraping에만 사용. discovery 토큰을 생성해서 직접 구성하거나 공용 etcd 탐색 서비스를 사용해도 됨.

DNS 탐색

== etcd DNS discovery

etcd.yaml

etcd 인스턴스에 대한 설정파일. 탐색방법마다 다르지만 보통 노드마다 하나씩 존재. 노드의 /etc/kubernetes/manifests 를 복사해서 사용한다. 이 파일은 일반적인 kubenetes service 설정파일과 동일하며, etcd에 관련된 설정을 할 수 있다.

etcd 클러스터 확인

etcdctl 도구를 사용해서 클러스터 상태 및 상황을 검사하는데 exec명령어를 써서 직접 cli로 수행이 가능하다.

etcd 2 vs 3

  • REST JSON에서 gRPC22 protobuf으로 전환해서 성능 향상
  • 임대와 자세한 핵심 TTL 지원
  • 각 watch에 대해서 하나의 connection 를 맺는 대신에 gRPC를 사용해서 단일 connection으로 여러 watch 가능

데이터 보호

  • 클러스터의 손상은 일시적으로 서비스 중단을 가져올 수 있지만 결과적으로 재구축이 가능. 그러나 데이터의 손상은 복구불가능한 타격을 줄 수도 있는 중요한 문제.
  • 따라서 duplication, backup 필수.
  • 라이브 데이터의 경우 일부 손상을 감내할 수 있으므로 주기적으로 스냅샷을 생성하고 문제 발생 시 이를 통해 복원.

리더 선출

  1. kubenetes master component
    1. 스케쥴러, 컨트롤러 매니저 등 몇몇 마스터 컴포넌트들은 race condition에 의해 제약받아 여러 인스턴스를 동시에 실행하는게 불가능.
    2. --leader-elect 옵션을 사용해서 리더 선출 활성화 가능
    3. 이 컴포넌트들이 pod 재시작을 담당하기 때문에 새로운 pod을 생성해서 대체하는것이 불가능. 미리 대체 컴포넌트들을 여러개 실행해둬야 함
  2. application component
    1. 직접 구현하는 방법
    2. 구글이 제공하는 leader-elector 컨테이너를 사이드카 컨테이너로 구성하는 방법
      1. ResourceVersion Annotations 두 가지가 결합된 쿠버네티스 엔드포인트 사용

고가용성 테스트 환경 만들기

비용 절감을 위한 조치

  1. 한시적 HA 준비: 테스트 환경을 지속적으로 유지하는게 아니라 필요한 순간만 유지하고 삭제.
  2. 시간 절약: 테스트 환경을 구축하기에 앞서 관심있는 이벤트 스트림과 시나리오를 미리 작성, 환경 구축 이후에는 빠르게 준비된 데이터를 바탕으로 시뮬레이션 진행
  3. 성능과 스트레스트 테스트를 결합하여 HA 테스트: 각 테스트를 별도로 진행하지 말고 동시에 진행. 신뢰성과 고가용성 설정을 통한 트래픽 조절 방법 관찰

고가용성 테스트

  • 신중하게 계획하고 시스템에 대해 깊이 이해하고 있어야 함
    • 포괄적인 발생 가능한 장애 리스트
    • 장애 시나리오 별 시스템 대응 방법
    • 장애 유발 방법
    • 시스템 반응 관찰 방법
  • 목표는 시스템 설계 및 구현의 결함 발견. 더 나아가면 결함의 조치 및 해결을 보장하는 것
  • 임의의 고장을 발생시켰을 때 시스템이 스스로 복원되면 신뢰성 및 고가용성을 갖췄다고 볼 수 있음
  • 가능한한 간섭이 없도록 해야 함

라이브 클러스터 업그레이드

롤링 업그레이드

컴포넌트의 버전을 점진적으로 업그레이드 하는 방법

  1. 마이너 업데이트
    1. deployment resource 자체 기능으로 쉽게 올리면 됨
  2. 메이저 업데이트 (브레이킹 체인지 포함)
    1. 버전 업데이트에 따라 달라진 API를 맞춰주는 일종의 어댑터 서비스를 사용. 나중에 모든 컴포넌트가 버전업하게되면 자연스럽게 이 어댑터 서비스만 제거하면 됨. 이는 각 컴포넌트의 복잡도가 높아지지 않도록 도와줌.

블루그린 업그레이드

  • 전체 컴포넌트 및 운영 환경 복제본을 마련하는 방법.
  • 기존 환경은 블루, 복제한 환경은 그린.
  • 모든 요청에 대한 응답은 블루가 하고 있는 상황에서 그린을 충분히 테스트하고, 테스트가 모두 통과하면 블루와 그린을 교체 및 활성화하는 방법.
  • 어떤 문제가 발생했을 때 롤백이 아주 쉬움.
  • common persistence layer는 공유 (DB, 파일 저장 서버 등), stateless 컴포넌트만 교체
  • 저장소에 변경이 있거나 외부에서 접근하는 API에 큰 변경이 있었을 경우 별도의 추가작업 필요
    • 블루와 그린이 서로 제각각 DB를 가지고 있는 경우, 모든 요청은 블루와 그린에게 모두 들어가야하며 그린은 교체되기 전에 블루의 모든 데이터를 동기화해와야 함.

data contract 변경 관리

data contract는 데이터 구성의 방법과 구조적 메타데이터를 의미. 일반적으로는 DB의 스키마, 프로퍼티 구조, API 도큐먼트 등을 포함.

런타임 오류의 원인이 될 수 있으므로 신중한 관리 필요

데이터 마이그레이션

  • 하드웨어의 발전 속도보다 데이터의 증가 속도가 훨씬 빠르고 그에 따라 데이터 마이그레이션은 대량의 시간 소요
  • 일반적으로 사용중인 도구, 인프라, 서드파티 종속성, 프로세스의 확장성 문제에 직면
  • 수적인 변경이 아니라 질적인 변경이기도 함.

API 지원 중단

  1. 내부 API
    1. 팀 또는 조직에서 전부 제어 가능
    2. 빠른 시간 내로 모든 사용자가 새로운 API로 업그레이드 되는 것을 보장해야 함
  2. 외부 API
    1. 직접적인 영향권 밖에 있는 사용자, 서비스가 사용
    2. 규모가 큰 조직이라면 내부 API도 외부 API로 공개되어야할 때가 있음
    3. 가능하다면 외부 API를 자동으로 업데이트는 애플리케이션 또는 웹 인터페이스로 숨겨서 업그레이드를 용이하게 하는 것이 좋음

지원 중단 대책

  1. API 지원 유지: 기존 API를 확장하거나 이전 API를 활성화 상태로 유지하며 천천히 줄여나가는 방법. 테스팅 및 운영 부담 존재
  2. 클라이언트 라이브러리 제공 (sdk): 개발 리소스가 충분하다는 전제하에 가장 좋은 방법. 프로그래밍 언어 인터페이스를 안정적으로 유지하며 사용자에게 영향없이 API 자유롭게 변경 가능.
  3. 지원 중단 사유 설명: 어쩔 수 없는 경우 명확히 이유를 설명하고 업그레이드에 필요한 충분한 시간을 제공. 또한 가능한 범위에서 최대한 지원.

대규모 클러스터 성능 비용 설계 균형

시스템에 따라 신뢰성과 가용성 요구사항이 다르므로 항상 최선의 선택을 해야 함. 언제나 모든 것이 완벽한 해결책은 존재하지 않음.

  1. 유지보수 시간: 서비스를 내리고 업데이트 등을 하는 것. 쿠버네티스를 쓴다면 유지보수 시간 대신에 블루그린 등을 대안으로 생각해보자.
  2. 빠른 복구: 블루그린, 롤링 업데이트 등의 전략을 쓰고있다면 롤백을 통해서 빠른 복구가 가능하다.
  3. 무중단: 분산 시스템 자체가 무중단을 위한 설계. 물론 완벽한 무중단 시스템은 존재하지 않는다.
    1. 모든 레벨에서 중복: SPOF를 없애야 한다
    2. 장애 컴포넌트의 자동 핫 스와핑
    3. 모니터링 및 알람으로 문제 발생 시 조기 탐지
    4. Real 배포 전 세밀한 테스트: 단계별 종합 테스트 수행. 인프라와 애플리케이션 모두 테스트해야 한다. 가장 좋은 방법은 블루그린 배포 등으로 완전히 동일한 환경에서 테스트하는 것이 좋다. 그게 안 된다면 적어도 가능한한 같아지도록 설정해야 한다.
      1. unit test
      2. parameter test
      3. benchmark
      4. stress test
      5. rollback test
      6. data recovery test
      7. Penetration test
  4. 로우 데이터 유지: 만일에 대비해서 가공되지 않은 데이터를 저장해두는 편이 좋다. 물론 데이터의 크기가 클 가능성이 높으므로 좀 더 저렴한 스토리지에 저장하는 방법이 있겠다.
  5. 최후 수단으로 가동 시간 인지

성능과 데이터 일관성

CAP 이론 참고. 고가용성은 일관성의 훼손을 발생시킨다. 그러나 이는 데이터의 손상 또는 잘못된 데이터가 저장되는 것을 의미하는 것이 아니다. 핵심은 결과적 일관성이다. 일시적으로 데이터가 불일치할 수 있지만 최종적으로는 완성된 데이터가 들어가도록 하면 서비스에 이슈 없이 성능적으로 큰 향상을 볼 수 있다.

results matching ""

    No results matching ""