본문 바로가기
Software Engineering/시스템 설계

시스템 설계 가이드

by 부뚜기 2023. 5. 5.
반응형

왜 시스템 설계를 배워야 하나?

지난 20년간 대규모 웹 애플리케이션에 많은 발전이 있었다. 이러한 발전은 소프트웨어 개발에 대한 생각 방식을 재정의했다. 페이스북, 인스타그램, 트위터와 같이 우리가 매일 사용하는 모든 앱과 서비스는 확장 가능한 시스템이다. 전 세계 수십억 명이 동시에 이러한 시스템에 액세스 하기 때문에 대규모의 트래픽과 데이터를 처리할 수 있도록 설계되어야 한다. 이것이 바로 시스템 설계가 필요한 이유다.

 

소프트웨어 개발자로서, 시스템 설계 개념을 이해하고 적용하는 능력이 점점 더 필요하다. 초기에 시스템 설계를 학습함으로써, 소프트웨어 설계 문제를 더 자신 있게 해결할 수 있으며, 일상적인 업무에 설계 원칙을 적용할 수 있다. 레벨에 관계없이, 시스템 설계는 중요한 요소가 된다.

반응형

이 가이드의 내용은 다음과 같다.

 

시스템 설계란?

시스템 설계는 특정 요구 사항을 충족하는 시스템의 아키텍처, 인터페이스 및 데이터를 정의하는 과정이다. 시스템 설계는 일관되고 효율적인 시스템을 통해 비즈니스나 조직의 요구 사항을 충족해야 한다. 비즈니스나 조직이 요구 사항을 결정하면 고객의 요구 사항을 해결하는 물리적 시스템 설계를 구축하기 시작할 수 있다. 시스템을 설계하는 방법은 맞춤형 개발, 상용 솔루션 또는 두 가지의 조합을 선택하는 것에 따라 다르다.

 

시스템 설계 기본 개념

수평 및 수직 확장

확장성은 애플리케이션이 지연 시간을 희생하지 않고 증가된 워크로드를 처리하고 견딜 수 있는 능력을 의미한다. 애플리케이션이 잘 확장되려면 탄탄한 컴퓨팅 성능이 필요하다. 서버는 증가하는 트래픽 부하를 처리할 수 있을 정도로 강력해야 한다. 응용프로그램의 크기를 조정하는 두 가지 주요 방법은 수평 및 수직 확장이다.

수평 확장 또는 스케일 아웃은 기존 하드웨어 자원 풀에 더 많은 하드웨어를 추가하는 것을 의미한다. 전체 시스템의 연산 능력이 증가한다. 수직 확장 또는 스케일 업은 서버에 더 많은 파워를 추가하는 것을 의미한다. 응용 프로그램을 실행하는 하드웨어의 파워가 증가한다.

두 가지 유형의 스케일링에는 각각 장단점이 있다. 사용 사례에 따라 트레이드오프를 고려하고 어떤 유형의 스케일링이 가장 적합한지 결정해야 한다. 

 

마이크로서비스 (Microservices)

Microservices 또는 Microservices 아키텍처는 클라우드 네이티브 아키텍처 접근 방식 중 하나로, 하나의 애플리케이션을 여러 개의 느슨하게 결합된 독립적으로 배포 가능한 작은 컴포넌트, 즉 서비스로 구성한다. 이러한 서비스는 자체적인 기술 스택(데이터베이스 및 데이터 관리 모델 포함)을 가지고 있다. 마이크로서비스 아키텍처를 사용하면 애플리케이션을 보다 쉽게 확장하고 더 빠르게 개발할 수 있으며, 이를 통해 혁신을 가속화하고 새로운 기능의 출시 시간을 단축시킬 수 있다.

마이크로아키텍처 시스템에서, 각 마이크로서비스는 담당 팀에 의해 관리 되어 진다.
#1 팀은 변화하는 요구사항을 충족하기 위해 마이크로 서비스를 쉽게 확장할 수 있다.

마이크로서비스는 독립적인 서비스들로 구성된 아키텍처로, 각 서비스는 자체적인 비즈니스 로직과 데이터베이스를 가지고 있다. 이러한 서비스들은 API를 통해 서로 통신할 수 있다.

마이크로서비스는 전통적인 단일 서비스에 비해 더 빠르고 신뢰성이 높은 속도로 운영될 수 있다. 모든 서비스가 자체 로직과 코드베이스를 가지고 있기 때문에, 이 서비스들은 API를 통해 서로 통신한다. 이러한 모듈화 된 아키텍처로 인해 마이크로서비스는 확장이 더 용이하며, 팀 내 커스터마이징도 가능하다. 특히, 대규모 또는 성장하는 조직에서 마이크로서비스는 더욱 적합하다.

 

프락시 서버 (Proxy servers)

프락시 서버 또는 포워드 프락시는 사용자와 인터넷 사이에서 채널 역할을 한다. 이는 엔드 유저와 그들이 브라우징 하는 웹사이트를 분리한다. 

프락시 서버는 사용자 요청을 전달하는 것뿐만 아니라 다음과 같은 이점을 제공한다.

  • 개선된 보안성
  • 개선된 개인 정보 보호
  • 차단된 리소스에 대한 접근
  • 직원 및 아이들의 인터넷 사용 제어
  • 데이터 캐시를 통한 요청 속도 개선

사용자가 엔드 서버의 주소에 대한 요청을 보내면, 그 트래픽은 목적지 주소로 가는 동안 프락시 서버를 통과한다. 요청이 사용자에게 다시 돌아올 때는 동일한 프락시 서버를 통해 사용자에게 전달된다.

 

CAP 정리 (CAP theorem)

CAP 정리(CAP theorem)는 시스템 설계 분야에서 기본적인 정리이다. 이는 분산 시스템이 일관성(consistency), 가용성(availability), 그리고 분할 허용성(partition tolerance) 중 두 가지 특성만을 동시에 제공할 수 있다는 것을 말한다. 이 정리는 분할이 있을 때 일관성과 가용성 사이의 트레이드오프를 공식화한다.

이중화 및 복제 (Redundancy replication)

이중화(Redundancy)는 시스템의 신뢰성이나 전반적인 성능을 높이기 위해 시스템의 중요한 구성 요소를 복제하는 과정이다. 일반적으로 백업 또는 페일 세이프의 형태로 제공된다. 이중화는 시스템에서 단일 장애 지점을 제거하고 필요할 때 백업을 제공하는 데 중요한 역할을 한다. 예를 들어 운영 환경에서 실행 중인 서비스 인스턴스가 두 개 있는데 그중 하나가 실패하면 시스템이 다른 인스턴스로 페일오버될 수 있다.

복제(Replication)는 중복된 자원 사이에서 일관성을 보장하기 위해 정보를 공유하는 프로세스이다. 소프트웨어나 하드웨어 구성 요소를 복제함으로써 신뢰성, 장애 허용성, 또는 접근성을 향상시킬 수 있다. 복제는 일반적으로 기존 자원과 복사본 간의 주-복제(Primary-Replica) 관계로 많은 데이터베이스 관리 시스템(DBMS)에서 사용된다. 주 서버에서 모든 업데이트를 수신하고, 이러한 업데이트는 복제 서버를 통해 전달된다. 각 복제 서버는 업데이트를 성공적으로 수신하면 메시지를 출력한다.

 

스토리지 (Storage)

데이터는 모든 시스템의 핵심이다. 시스템을 설계할 때는 데이터를 저장하는 방법을 고려해야 한다. 시스템의 요구 사항에 따라 구현할 수 있는 다양한 저장 기술이 있다.

 

블록 스토리지 (Block storage)

블록 스토리지는 데이터를 동일한 크기의 블록으로 분할하고, 각 블록에는 쉽게 접근할 수 있도록 고유한 식별자가 부여되는 데이터 저장 기술이다. 이러한 블록은 물리적 스토리지에 저장된다. 고정 경로를 따르는 것과 달리, 블록은 시스템 내 어디에든 저장될 수 있으므로, 리소스를 더 효율적으로 사용할 수 있다.

특정 위치의 고정 크기 블록

파일 스토리지 (File storage)

파일 스토리지는 계층적 저장 방법이다. 이 방법을 사용하면 데이터가 파일에 저장된다. 파일은 폴더에 저장된 다음 디렉터리에 저장된다. 이 저장 방법은 주로 구조화된 데이터인 제한된 양의 데이터에만 적합하다.

고정된 논리적 순서의 특정 폴더

객체 스토리지 (Object storage)

객체 스토리지는 대량의 비정형 데이터를 처리하도록 설계된 스토리지다. 객체 스토리지는 동적 확장성을 제공하기 때문에 데이터 아카이빙 및 데이터 백업에 선호되는 데이터 스토리지 방법이다. 운영 체제에서 개체 저장소에 직접 액세스 할 수 없다. 통신은 애플리케이션 수준에서 RESTful API를 통해 이루어진다. 이러한 유형의 스토리지는 백업, 비정형 데이터 및 로그 파일이 모든 시스템에 중요하기 때문에 시스템에 엄청난 유연성과 가치를 제공한다. 대규모 데이터셋을 사용하여 시스템을 설계할 경우 조직에 객체 스토리지가 적합하다.

메타데이터 기반의 확장 가능한 스토리지

중복 Disk 어레이 (Redundant Disk Arrays (RAID))

RAID는 여러 개의 디스크를 동시에 사용하여 더 빠르고 더 크고 안정적인 디스크 시스템을 구축하는 기술이다. 외부적으로 RAID는 디스크처럼 보인다. 내부적으로는 여러 개의 디스크, 메모리 및 시스템을 관리하는 하나 이상의 프로세서로 구성된 복잡한 구조다. 하드웨어 RAID는 컴퓨터 시스템과 비슷하지만 디스크 그룹을 관리하는 작업에 특화되어 있다. RAID 레벨은 다양하며, 모든 RAID 레벨은 서로 다른 기능을 제공한다. 복잡한 시스템을 설계할 때는 RAID 스토리지 기술을 구현해야 할 수도 있다.

RAID 1 기술: 미러링

메시지 큐 (Message queues)

메시지 큐는 송신자에서 수신자로 또는 소스에서 목적지로 메시지를 전달하는 큐이다. 이는 FIFO (선입선출) 정책을 따른다. 먼저 보내진 메시지가 먼저 전달된다. 메시지 큐는 비동기 동작을 용이하게 하며, 기본 작업을 방해하지 않고 모듈이 서로 통신할 수 있도록 한다. 또한 교차 모듈 통신을 용이하게 하며, 메시지가 소비자에 의해 처리되고 사용될 때까지 메시지를 일시적으로 저장한다. 

 

Kafka

아파치 카프카는 2011년 LinkedIn의 메시징 시스템으로 시작되었지만, 지금은 대규모 분산 이벤트 스트리밍 플랫폼으로 성장했다. 카프카는 하루에 수조 개의 레코드를 처리할 수 있는 분산 시스템으로, 서버와 클라이언트로 구성되어 TCP 네트워크 프로토콜을 통해 통신한다. 이 시스템을 사용하여 이벤트를 읽고, 쓰고, 저장하고, 처리할 수 있다. 카프카는 데이터 파이프라인을 구축하고 스트리밍 솔루션을 구현하는 데에 주로 사용된다.

 

파일 시스템 (File systems)

파일 시스템은 스토리지 디스크의 데이터가 저장되는 방법과 위치를 관리하는 프로세스다. 스토리지 디스크의 내부 작업을 관리하고 사용자 또는 응용 프로그램이 디스크 데이터에 액세스 하는 방법을 설명한다. 파일 시스템은 다음과 같은 여러 작업을 관리한다.

  • 파일 이름 지정
  • 스토리지 관리
  • 디렉터리
  • 폴더
  • 액세스 규칙

파일 시스템이 없으면 파일을 식별, 파일을 검색하거나 개별 파일에 대한 권한 부여를 관리하기가 어렵다.

 

Google 파일 시스템 (GFS)

Google 파일 시스템(Google File System, GFS)은 Gmail이나 YouTube와 같은 대용량 데이터 중심 애플리케이션을 위해 디자인된 확장 가능한 분산 파일 시스템이다. GFS는 대량의 데이터 세트를 처리하기 위해 구축되었다. GFS는 사용자 간 통신보다는 시스템 간 상호작용을 위해 설계되었다. 그리고 확장성과 장애 허용성을 가지고 있다. 이 아키텍처는 하나의 마스터와 여러 청크 서버로 이루어진 GFS 클러스터로 구성되며, 이 클러스터는 다중 클라이언트에서 액세스 할 수 있다.

 

하둡 분산 파일 시스템 (HDFS)

Hadoop Distributed File System (HDFS)는 대용량 데이터 집합을 다루고 일반적인 하드웨어에서 실행되는 분산 파일 시스템이다. 비정형 데이터를 저장하기 위해 구축되었다. HDFS는 GFS의 간소화된 버전이다. 그 중요한 구조 결정은 GFS 설계에서 영감을 받았다. HDFS는 가장 효율적인 데이터 처리 패턴이 "한 번 쓰고 여러 번 읽기" 패턴인 것으로 생각하고 구축되었다.

 

시스템 설계 패턴 (System Design patterns)

시스템 설계 패턴을 아는 것은 모든 유형의 분산 시스템에 적용할 수 있기 때문에 매우 중요하다. 시스템 설계 패턴은 분산 시스템 및 그 솔루션과 관련된 일반적인 설계 문제를 의미한다. 일반적으로 사용되는 패턴을 살펴본다. 

 

블룸 필터 (Bloom filters)

Bloom 필터는 집합 내에 요소가 존재하는지에 대한 질문에 답변하기 위해 설계된 확률론적 데이터 구조다.

Bloom 필터는 공간을 매우 효율적으로 사용하며 실제 항목을 저장하지 않는다. 항목이 집합에 없거나 항목이 집합에 존재할 가능성이 있다. 항목이 집합에 확실히 포함되어 있는지는 알 수 없다. 비어있는 Bloom 필터는 모든 비트가 0으로 설정된 비트 벡터다. 아래 그림에서 각 셀은 비트를 나타낸다. 비트 아래의 숫자는 10비트 벡터에서의 해당 비트의 인덱스이다.

비어 있는 블룸 필터

 

일관성 해시 (Consistent hashing)

일관된 해싱은 데이터를 물리적 노드에 매핑하고 서버를 추가하거나 제거할 때 작은 키 집합만 이동하도록 보장한다. 일관된 해시는 분산 시스템에서 관리하는 데이터를 링에 저장한다. 링의 각 노드에는 데이터 범위가 할당된다. 이 개념은 분산 시스템 내에서 중요하며 데이터 파티셔닝 및 데이터 복제와 긴밀하게 작동한다. 

 

쿼럼 (Quorum)

쿼럼은 분산 시스템에서 분산 작업이 전체적으로 성공하기 위해 성공적으로 수행되어야 하는 최소 서버 수다.

 

체크섬 (Checksum)

분산 시스템의 구성 요소 간에 데이터를 이동할 때 노드에서 가져온 데이터가 손상된 상태로 도착할 수 있다. 이러한 손상은 스토리지 장치, 네트워크, 소프트웨어 등의 결함으로 인해 발생한다. 시스템이 데이터를 저장할 때 데이터의 체크섬을 계산하고 데이터와 함께 체크섬을 저장한다. 클라이언트는 데이터를 검색할 때 서버에서 수신한 데이터가 저장된 체크섬과 일치하는지 확인한다. 

 

Merkle 트리 (Merkle trees)

머클 트리(Merkle tree)는 각 내부 노드가 두 자식 노드의 해시이고, 각 리프 노드는 원본 데이터의 일부의 해시인 이진트리이다. 복제본은 많은 데이터를 포함할 수 있다. 전송할 데이터가 너무 많기 때문에 전체 범위를 분할하여 비교를 위해 체크섬을 계산하는 것은 매우 실현 가능하지 않다. 머클 트리를 사용하면 범위의 복제본을 쉽게 비교할 수 있다.

 

리더 선출 (Leader election)

리더 선출(Leader election)은 여러 컴퓨터에 분산된 작업의 조직자로 한 프로세스를 지정하는 과정이다. 각 노드가 특정 노드를 작업 리더로 인식할 수 있도록 하는 알고리즘이다. 네트워크 노드는 서로 통신하여 누가 리더가 될지 결정한다. 리더 선출은 효율성을 향상시키고 아키텍처를 간소화하며 작업을 감소시킨다. 

 

데이터베이스 (Databases)

관계형 데이터베이스 (Relational databases)

관계형 데이터베이스 또는 SQL 데이터베이스는 구조화되어 있다. 번호와 주소를 저장하는 전화번호부처럼 미리 정의된 스키마를 가지고 있다. SQL 데이터베이스는 데이터를 행과 열에 저장한다. 각 행에는 단일 엔터티에 대해 사용할 수 있는 모든 정보가 포함되어 있으며 각 열에는 별도의 데이터 점이 모두 포함되어 있다. 널리 사용되는 SQL 데이터베이스는 다음과 같다.

  • MySQL
  • Oracle
  • MS SQL Server
  • SQLite
  • PostgreSQL
  • MariaDB

MySQL

MySQL은 테이블과 행에 데이터를 저장하는 오픈 소스 관계형 데이터베이스 관리 시스템(RDBMS)이다. SQL(구조화된 쿼리 언어)을 사용하여 데이터를 전송하고 액세스 하며 SQL 조인을 사용하여 쿼리와 상관관계를 단순화한다. 클라이언트-서버 아키텍처를 따르고 멀티스레딩을 지원한다. 

 

PostgreSQL

PostgreSQL은 오픈소스 RDBMS로서 확장성과 SQL 준수를 강조한다. Postgres는 데이터베이스에 액세스 하고 조작하기 위해 SQL을 사용한다. 더 복잡한 쿼리를 수행할 수 있는 PL/pgSQL이라는 Postgres의 버전인 SQL을 사용한다. Postgres 트랜잭션은 ACID 원칙을 따른다. 관계형 구조를 갖기 때문에 전체 스키마는 생성 시에 설계 및 구성되어야 한다. Postgres 데이터베이스는 데이터 정규화를 유지할 수 있도록 외래 키를 사용한다. 

 

SQL 조인 (SQL joins)

SQL 조인은 두 개 이상의 테이블에서 동시에 정보를 검색할 수 있게 해 준다. 또한 데이터 중복성을 낮춰주어 데이터 이상 현상을 삭제하거나 업데이트할 때 애플리케이션에서 발생하는 문제를 줄일 수 있다.

 

비관계형 데이터베이스 (Non-relational databases)

비관계형 데이터베이스 또는 NoSQL 데이터베이스는 구조화되어 있지 않는다. 사용자의 주소와 전화번호부터 Facebook 좋아요 및 온라인 쇼핑 기호에 이르기까지 정보를 저장하는 파일 폴더와 같은 동적 스키마를 가지고 있다. NoSQL에는 다양한 유형이 있다.

가장 일반적인 유형은 다음과 같다.

  • Redis와 DynamoDB와 같은 키-값 스토어
  • MongoDB와 CouchDB와 같은 문서 데이터베이스
  • Cassandra와 HBase와 같은 wide-column 데이터베이스
  • Neo4J와 InfiniteGraph와 같은 그래프 데이터베이스

MongoDB

MongoDB는 데이터 저장을 위해 테이블이나 행 대신 문서를 사용하는 NoSQL 비관계형 데이터베이스 관리 시스템(DBMS)이다. 이 데이터 모델을 사용하면 단일 데이터베이스 작업에서 관련 데이터를 조작할 수 있다. MongoDB 문서는 자바스크립트가 지원되는 JSON과 같은 문서와 파일을 사용한다. 문서 필드는 다양할 수 있으므로 시간이 지남에 따라 구조를 쉽게 변경할 수 있다. 

 

데이터베이스 선택 방법

데이터베이스는 소프트웨어 개발의 기본 기반이다. 모든 크기와 유형의 프로젝트를 구축하는 데 많은 다른 목적으로 사용된다. 데이터베이스 구조를 선택할 때는 속도, 신뢰성 및 정확성을 고려하는 것이 중요하다. 데이터 유효성을 보장할 수 있는 관계형 데이터베이스와 이벤트 일관성을 보장할 수 있는 비관계형 데이터베이스가 있다.

데이터베이스 구조를 선택할 때는 다음과 같은 데이터베이스 기본 원칙을 고려해야 한다.

  • ACID
  • BASE
  • SQL joins
  • Normalization
  • Persistence
  • Etc.

데이터베이스 결정은 시스템 설계 인터뷰에서 중요한 부분을 차지하므로 고유한 사용 사례를 기반으로 의사 결정을 내리는 데 익숙해지는 것이 중요하다. 선택한 데이터베이스는 프로젝트에 따라 달라진다.

 

데이터베이스 스키마

데이터베이스 스키마는 데이터베이스에 저장된 데이터의 구조를 나타내는 추상적인 설계다. 이는 주어진 데이터베이스 내의 데이터 조직 및 테이블 간의 관계를 설명한다. 데이터베이스 스키마는 필요한 구성 요소와 그들이 어떻게 서로 연결되는지를 사전에 계획하여야 한다. 데이터베이스 스키마는 데이터를 보유하지 않지만 데이터의 형태와 다른 테이블 또는 모델과의 관계를 설명한다. 데이터베이스 내의 항목은 데이터베이스 스키마의 인스턴스다.

 

스키마의 서로 다른 부분을 정의하는 두 가지 기본 데이터베이스 스키마 유형, 즉 논리적 스키마 유형과 실제 데이터베이스 스키마 유형이 있다.

데이터베이스 스키마에는 다음이 포함된다.

  • 모든 중요하거나 관련된 데이터
  • 모든 데이터 항목에 대한 일관된 형식 지정
  • 모든 항목 및 데이터베이스 개체에 대한 고유 키
  • 테이블의 각 열 이름과 데이터 유형

데이터베이스 스키마의 크기와 복잡성은 프로젝트의 크기에 따라 달라진다. 데이터베이스 스키마의 시각적 스타일을 사용하면 코드로 이동하기 전에 데이터베이스와 데이터베이스 관계를 적절하게 구성할 수 있다. 데이터베이스 설계를 계획하는 과정을 데이터 모델링이라고 한다. 데이터베이스 스키마는 DBMS 및 RDBMS 설계에 중요하다.

 

데이터베이스 쿼리

데이터베이스 쿼리는 데이터베이스에서 데이터를 조작하거나 검색하기 위해 데이터에 액세스 하는 요청이다. CRUD 작업과 가장 밀접한 관련이 있다. 데이터베이스 쿼리를 사용하면 쿼리에 대한 응답으로 얻은 정보로 논리를 수행할 수 있다. 쿼리 문자열 사용부터 쿼리 언어로 쓰기, GraphQL과 같은 QBE(Query by Example) 사용에 이르기까지 쿼리에 대한 다양한 접근 방식이 있다.

 

ACID 특성

데이터베이스의 무결성을 유지하려면 모든 트랜잭션이 ACID 속성을 따라야 한다. ACID는 원자성, 일관성, 격리 및 내구성을 나타내는 약어이다.

  • 원자성(Atomicity): 트랜잭션은 원자적 단위이다. 트랜잭션 내의 모든 명령문은 성공적으로 실행되거나 실행되지 않아야 한다.
  • 일관성(Consistency): 데이터베이스는 초기에 일관된 상태에 있으며, 모든 트랜잭션 이후에도 일관된 상태를 유지해야 한다.
  • 독립성(Isolation): 여러 트랜잭션이 동시에 실행되는 경우에도 서로 영향을 미치지 않아야 하며, 순차적으로 실행되는 경우와 결과가 동일해야 한다.
  • 지속성(Durability): 데이터베이스에 커밋된 변경 사항은 소프트웨어나 시스템 장애가 발생해도 유지되어야 한다.

 

데이터베이스 샤딩과 파티셔닝 (Sharding and Partitioning)

데이터베이스 샤딩을 할 때는 데이터를 파티션으로 나누어서 각각을 샤드라고 하는 서로 다른 작은 조각으로 분할한다. 각 샤드는 테이블, Postgres 스키마 또는 별도의 데이터베이스 서버 인스턴스에 저장될 수 있다. 데이터베이스의 일부 데이터는 모든 샤드에 존재하고 일부 데이터는 단일 샤드에만 나타난다. 이 두 가지 상황은 수직 샤딩과 수평 샤딩이라고 할 수 있다. 아래는 시각적으로 보여준다.

데이터를 샤딩하려면, 컬렉션의 모든 문서에 존재하는 인덱스 필드 또는 인덱스 복합 필드를 샤딩 키로 결정해야 한다. 샤딩 키를 결정하는 일반적인 규칙은 없으며, 애플리케이션에 따라 다르다.

샤딩은 애플리케이션이 적은 수의 쿼리를 생성하도록 할 수 있다. 요청을 받았을 때, 애플리케이션은 어디로 요청을 전송해야 하는지 알고 있다. 이는 전체 데이터베이스를 검색하는 대신에 적은 양의 데이터를 검색하게 되므로, 애플리케이션의 전반적인 성능과 확장성이 향상된다.

데이터 파티셔닝은 대규모 데이터베이스를 더 작은 부분으로 분할하는 기술이다. 이 과정은 애플리케이션의 성능, 가용성, 부하 분산 및 관리 용이성을 향상시킬 수 있다. 

 

데이터베이스 인덱싱

데이터베이스 인덱싱은 테이블에서 빠르고 쉽게 원하는 행 또는 열을 찾을 수 있도록 한다. 인덱스는 데이터베이스 테이블의 하나 이상의 열을 사용하여 생성할 수 있으며, 빠른 임의 검색과 순서대로 된 정보에 대한 효율적인 액세스를 제공한다. 인덱스는 데이터 검색 속도를 높이지만, 크기 때문에 데이터 삽입 및 업데이트 속도가 느릴 수 있다.

 

분산 시스템이란?

분산 시스템은 우리가 애플리케이션을 지수적으로 확장하는 것을 용이하게 한다. 많은 최고의 기술 기업들은 수십억 건의 요청을 처리하고 다운 타임 없이 업데이트를 수행하는 복잡한 분산 시스템을 사용한다. 분산 시스템은 여러 대의 컴퓨터가 함께 작동하여 최종 사용자를 위해 하나의 컴퓨터를 형성하는 컴퓨터 집합이다. 모든 컴퓨터는 같은 상태를 공유하며 동시에 작동한다. 이러한 시스템은 전체 시스템에 영향을 미치지 않고 독립적으로 실패할 수도 있다.

분산 시스템은 배포와 유지 관리가 어려울 수 있지만, 다음과 같은 많은 이점을 제공한다.

 

  • 스케일링: 분산 시스템을 사용하면 더 많은 트래픽을 고려하여 수평으로 확장할 수 있다.
  • 모듈식 확장: 얼마나 확장할 수 있는지에 대한 제한이 거의 없다.
  • 내결함성: 분산 시스템은 단일 시스템보다 내결함성이 높다.
  • 비용 효율적: 초기 비용은 기존 시스템보다 높지만 확장 가능한 용량 때문에 비용 효율성이 빠르게 향상된다.
  • 짧은 대기 시간: 여러 위치에 노드를 둘 수 있으므로 트래픽이 가장 가까운 노드에 도달한다.
  • 효율성: 분산 시스템은 복잡한 데이터를 더 작은 조각으로 나눈다.
  • 병렬 처리: 분산 시스템은 여러 프로세서가 복잡한 문제를 더 작은 덩어리로 나누는 병렬화를 위해 설계될 수 있다.

 

분산 시스템 실패 (Distributed system failures)

분산 시스템에서는 여러 유형의 장애가 발생할 수 있다.

네 가지 기본적인 고장 유형은 다음과 같다.

 

시스템 장애 - 
소프트웨어 또는 하드웨어 장애로 인해 시스템 장애가 발생한다. 일반적으로 시스템 장애로 인해 기본 메모리의 내용이 손실되지만 보조 메모리는 안전하게 유지된다. 시스템 오류가 발생할 때마다 프로세서가 실행을 수행하지 못하고 시스템이 재부팅되거나 중지될 수 있다.

통신 매체 고장 - 
통신 매체 장애는 통신 링크 장애 또는 노드 이동의 결과로 발생한다.

보조 스토리지 오류 -
보조 스토리지 디바이스의 정보에 액세스 할 수 없는 경우 보조 스토리지 오류가 발생한다. 노드 충돌, 미디어 오염, 패리티 오류 등 다양한 결과가 될 수 있다.

메서드 오류 - 
메서드 오류는 일반적으로 분산 시스템을 중지시키고 실행을 전혀 수행할 수 없게 만든다. 시스템은 메서드 오류 중에 교착 상태에 들어가거나 보호 위반을 수행할 수 있다.

 

분산 시스템 기본 개념

분산 시스템 분야의 몇 가지 기본 개념에 대해 설명한다.

 

MapReduce

MapReduce는 대량의 데이터를 효율적으로 처리하기 위해 Google에서 개발한 프레임워크이다. MapReduce는 데이터 관리 및 분배를 위해 많은 서버를 사용한다. 이 프레임워크는 사용자 명령 실행 중 발생하는 여러 하위 프로세스에 대한 추상화를 제공한다. 이러한 프로세스 중 일부는 장애 허용성, 데이터 파티셔닝 및 데이터 집계 등이 있다. 이러한 추상화는 사용자가 프로그램의 고급 로직에 집중할 수 있도록 도와준다. 동시에 하위 프로세스가 원활하게 계속되도록 프레임워크에 신뢰를 가질 수 있도록 한다.

MapReduce 워크플로우는 다음과 같다.

파티셔닝(Partitioning): 데이터는 보통 큰 청크로 제공된다. 맵 워커가 효율적으로 처리할 수 있도록 데이터를 작은 조각으로 분할하는 것이 필요하다.

맵(Map): 맵 워커는 키-값 쌍 형태로 데이터를 받는다. 이 데이터는 사용자가 정의한 맵 함수에 따라 처리되어 중간 키-값 쌍이 생성된다.

중간 파일(Intermediate files): 데이터는 R(R은 리듀스 워커의 수) 개의 파티션으로 분할된다. 이 파일은 기본 노드에서 리듀스 워커로 전달될 때까지 메모리에 버퍼링 된다.

리듀스(Reduce): 리듀스 워커가 버퍼에 저장된 데이터를 받으면 키에 따라 데이터를 정렬하고 그룹화한다.

집계(Aggregate): 기본 노드는 리듀스 워커가 작업을 완료하면 알림을 받는다. 마지막으로, 정렬된 데이터가 집계되어 사용자를 위해 R개의 출력 파일이 생성된다.

 

Stateless and stateful systems

상태(State)와 무상태(Stateless) 시스템은 분산 시스템의 중요한 개념이다. 시스템은 무상태 시스템 또는 상태 시스템 중 하나다. 무상태 시스템은 과거 이벤트의 상태를 유지하지 않는다. 입력에 따라 실행된다. 상태 저장 시스템은 상태를 유지하고 변형시키는 역할을 한다.

 

Raft

Raft는 복제된 상태 시스템의 개념과 관련 복제된 명령 로그를 1등급 시민으로 설정하고 기본적으로 여러 번의 연속적인 합의를 지원한다. 컨센서스 그룹 또는 Raft 클러스터를 구성하는 노드 집합이 필요하다.

각 상태는 다음 세 가지 상태 중 하나일 수 있다.

  • Leader
  • Follower
  • Candidate

 

분산 시스템 설계 패턴

디자인 패턴은 특정 유스케이스에 맞는 시스템을 구축하는 방법을 제공한다. 이는 시스템을 처음부터 만들지 않고 기존 지식을 활용할 수 있는 건축 블록과 같다. 이러한 패턴은 시스템 디자인을 위한 표준 모델 집합을 생성하여 다른 개발자들이 특정 시스템과 상호 작용하는 방법을 이해할 수 있도록 한다.

생성 패턴은 새로운 객체를 만들 때 기준을 제공한다. 구조 패턴은 솔루션의 전체 구조를 정의한다. 행동 패턴은 객체와 객체 간의 통신 방식을 설명한다. 분산 시스템 디자인 패턴은 서로 다른 노드 간의 통신 방식, 특정 작업을 처리하는 노드, 다양한 작업에 대한 프로세스 흐름을 나타내는 소프트웨어 아키텍처를 제공한다. 

대부분의 분산 시스템 디자인 패턴은 다음과 같은 기능에 따라 세 가지 범주로 나눌 수 있다.

  • 객체 통신: 시스템 구성 요소 간의 메시징 프로토콜 및 권한을 설명한다.
  • 보안: 인가되지 않은 액세스로부터 시스템을 안전하게 보호하기 위한 기밀성, 무결성 및 가용성 관련 문제를 처리한다.
  • 이벤트 기반: 시스템 이벤트의 생성, 감지, 소비 및 응답을 설명한다.

확장 가능한 웹 애플리케이션

DNS와 로드 밸런싱 (DNS and load balancing)

DNS (도메인 이름 시스템)은 간단한 도메인 이름을 IP 주소에 매핑하여 웹사이트를 방문할 때 긴 IP 주소를 기억하지 않아도 되도록 한다. 대규모 애플리케이션 및 시스템에서는 DNS 로드 밸런싱을 설정하여 다른 데이터 센터의 서로 다른 클러스터에 사용자 트래픽을 분산해야 한다. 

로드 밸런싱은 스케일링 노력에 매우 중요하다. 이는 트래픽 증가에 대응하여 효과적으로 확장하고 높은 가용성을 유지하는 데 도움이 된다. 로드 밸런싱은 로드 밸런서라는 역방향 프락시 역할을 하는 장치에 의해 실행된다. 로드 밸런서는 다양한 알고리즘을 사용하여 네트워크 트래픽을 여러 서버로 분산하는 역할을 한다. 트래픽의 분산은 모든 트래픽이 클러스터의 단일 머신이나 몇 대의 머신으로 집중되는 위험을 방지한다. 트래픽이 몇 대의 머신으로 수렴하면 이는 과부하를 유발하여 이러한 머신들을 다운시킨다. 

로드 밸런싱을 사용하면 이러한 문제를 피할 수 있다. 애플리케이션이 사용자 요청을 처리하는 동안 서버가 다운된 경우 로드 밸런서는 자동으로 작동하는 서버로 미래의 요청을 라우팅 한다.

N-tier 애플리케이션

N-계층 애플리케이션 또는 분산 애플리케이션은 세 개 이상의 컴포넌트가 관련된 애플리케이션이다. 

이러한 컴포넌트는 다음과 같습니다.

  • 캐시
  • 메시지 큐
  • 로드 밸런서
  • 검색 서버
  • 대량 데이터 처리에 관련된 컴포넌트
  • 웹 서비스로 알려진 이종 기술로 실행되는 컴포넌트

인스타그램, 페이스북, 우버와 같이 대형 애플리케이션들은 N-계층 애플리케이션이다.

 

HTTP와 REST

HTTP는 HyperText Transfer Protocol의 약자다. 이 프로토콜은 메시지의 형식, 메시지를 언제, 어떻게 보내고, 적절한 응답과 메시지 해석 방법을 지정한다. HTTP 메시지는 요청 또는 응답일 수 있다. HTTP API는 HTTP 요청이 서버에 액세스 할 수 있도록 API 게이트웨이로 엔드포인트를 노출한다. 타깃의 사용 사례에 따라 다양한 형태로 제공되며, 생성 시 사용되는 아키텍처적 설계 원칙에 따라 더 분류될 수 있다.

REST는 Representational State Transfer의 약자다. 웹 서비스를 구현하는 소프트웨어 아키텍처 스타일이다. REST는 클라이언트와 서버 간 데이터 공유를 위한 최상의 방법을 정의하는 규칙 집합이다. 구성 요소의 확장성과 인터페이스의 간소성을 강조한다. REST 응용 프로그램은 GET, POST, DELETE, PUT과 같은 HTTP 메서드를 사용한다.

REST API는 REST 아키텍처 원칙을 준수하는 API다. 클라이언트와 서버 간 통신이 HTTP를 통해 이루어지는 인터페이스 역할을 한다. REST는 서버가 응용 프로그램 성능을 향상시키는 응답 캐시를 활용할 수 있게 한다.

HTTP와 REST는 시스템 설계에서 클라이언트-서버 통신에 대한 중요한 개념과 고려 사항이다.

 

스트림 처리 (Stream processing)

스트림 처리(Stream processing)는 연속적인 데이터 스트림을 실시간으로 처리하는 컴퓨터 프로그래밍 아키텍처를 말한다. Kafka, Storm, Flink 등의 인기 있는 스트림 처리 도구가 있다.

 

캐싱 (Caching)

캐시는 데이터에 빠르게 액세스 할 수 있도록 데이터를 임시로 저장하는 데 사용하는 하드웨어 또는 소프트웨어다. 캐시는 일반적으로 매우 작기 때문에 비용 효율적이고 효과적이다. 웹 브라우저, CPU, 운영 체제 및 DNS 서버와 같은 캐시 클라이언트에서 사용된다. 캐시에서 데이터에 액세스 하는 것은 기본 메모리나 다른 유형의 스토리지에서 액세스 하는 것보다 훨씬 빠르다. 

 

캐싱이란 무엇인가? 어떻게 작동하나?

클라이언트가 일부 데이터에 액세스 하려고 한다고 가정해 보자. 첫째, 클라이언트는 데이터가 캐시에 저장되어 있는지 확인할 수 있다. 데이터를 찾으면, 즉시 고객에게 반환될 것이다. 이를 캐시 히트라고 한다. 데이터가 캐시에 저장되지 않으면 캐시 누락이 발생한다. 이 경우 클라이언트는 기본 메모리에서 데이터를 가져와 캐시에 저장한다.

 

캐시 무효화 (Cache invalidation)

캐시 무효화는 컴퓨터 시스템이 캐시 항목을 "비활성"으로 선언하고 제거하거나 대체하는 프로세스다. 이 프로세스의 기본 목적은 클라이언트가 영향을 받는 내용을 요청할 때 최신 버전을 반환하는 것이다.

세 가지 정의된 캐시 무효화 체계가 있다.

 

Write-through cache

Write-around cache

Write-back cache

 

캐시 소거 (Cache eviction)

캐시가 여유 공간이 있다면, 데이터를 쉽게 삽입할 수 있다. 하지만 캐시가 가득 차면 일부 데이터가 삭제된다. 무엇이 삭제되는지와 그 이유는 사용하는 삭제 정책에 따라 다르다.

일반적으로 사용되는 몇 가지 캐시 삭제 정책은 다음과 같다.

  • 선입선출(FIFO): 캐시는 가장 먼저 접근한 블록을 가장 먼저 삭제한다. 블록이 얼마나 자주 액세스되었는지나 얼마나 많이 액세스 되었는지와는 관계가 없다.
  • 후입선출(LIFO): 캐시는 가장 최근에 접근한 블록을 가장 먼저 삭제한다. 블록이 얼마나 자주 액세스되었는지나 얼마나 많이 액세스 되었는지와는 관계가 없다.
  • 최근에 사용하지 않은 항목 삭제(LRU): 캐시는 사용하지 않은지 가장 오래된 항목을 먼저 삭제한다.
  • 최근에 사용한 항목 삭제(MRU): 캐시는 가장 최근에 사용한 항목을 먼저 삭제한다.
  • 가장 적게 사용된 항목 삭제(LFU): 캐시는 항목이 필요한 빈도를 계산한다. 가장 적게 사용된 항목이 먼저 삭제된다.
  • 임의 대체(RR): 캐시는 후보 중에서 임의의 항목을 선택하고 그것을 삭제한다.

기계 학습과 시스템 설계

기계 학습 (ML) 응용 프로그램과 시스템은 다양한 산업에서 점점 더 인기가 있어지고 있으며, 계속해서 성숙하고 확장되면서 이러한 ML 응용 프로그램과 시스템을 설계하고 구축하는 방법에 대해 보다 깊이 생각해야 한다. 기계 학습 시스템 디자인은 특정 요구 사항을 충족하기 위해 기계 학습 시스템을 위한 소프트웨어 아키텍처, 알고리즘, 인프라 및 데이터를 정의하는 과정이다.

 

컨테이너화(Containerization)와 시스템 설계

컨테이너화는 소프트웨어 코드와 해당 의존성을 패키징하여 어떤 인프라에서든 실행할 수 있는 "컨테이너"를 생성하는 것을 의미한다. 컨테이너를 가상 머신(VM)의 보다 경량화된 버전으로 생각할 수 있으며, 자체 운영 체제가 필요하지 않다. 호스트의 운영 체제를 공유하는 모든 컨테이너는 많은 시스템 리소스를 절약한다. 컨테이너화는 Docker가 등장하기 전까지는 매우 접근하기 어려웠다. Docker는 컨테이너를 빌드하고 실행하는 데 사용할 수 있는 오픈 소스 컨테이너화 플랫폼이다. Docker 컨테이너는 응용 프로그램 계층에서 추상화 계층을 생성한다.

Docker는 종종 Kubernetes와 혼동된다. Kubernetes는 또 다른 인기 있는 컨테이너화 도구이며, 두 기술은 보완적으로 사용되며 자주 함께 사용된다. Docker는 컨테이너화 플랫폼이지만, Kubernetes는 컨테이너화 소프트웨어로 컨테이너 및 VM을 제어하고 관리할 수 있다. Kubernetes를 사용하면 Docker 컨테이너를 실행하고 컨테이너화된 애플리케이션을 관리할 수 있다. 컨테이너는 파드로 그룹화되며, 이러한 파드는 원하는 대로 확장하고 관리할 수 있다. 

ML 기술과 마찬가지로, 컨테이너화 기술도 인기가 높아지며 다양한 산업분야에서 점차 보급되고 있다. 이에 따라, 컨테이너화 시스템의 설계 및 구현도 점점 중요해지고 있다.

 

클라우드(Cloud)와 시스템 설계

클라우드 컴퓨팅은 인터넷에 연결된 오프사이트 데이터 센터를 통해 스토리지 또는 개발 플랫폼과 같은 서비스에 대한 온디맨드 액세스를 허용한다. 데이터 센터는 제 3자 회사 또는 클라우드 제공업체에 의해 관리된다. 클라우드 컴퓨팅 모델은 온프레미스 시스템에서 발생하는 문제뿐만 아니라 더욱 비용 효율적이고 확장 가능하며 편리하다.

서로 다른 클라우드 제공업체는 스토리지, 보안, 액세스 관리 등과 같은 다양한 클라우드 서비스를 제공한다.  클라우드 서비스를 사용하면 유연하고 효율적인 시스템을 설계하고 구현할 수 있는 도구를 제공한다. 클라우드 서비스는 크기와 복잡성이 다양하며, 다양한 클라우드 배포 모델을 활용할 수 있다.

다양한 클라우드 시스템 아키텍처는 다음과 같다.

  • 멀티 클라우드
  • 하이브리드 클라우드
  • 싱글 클라우드
  • 퍼블릭 클라우드
  • 프라이빗 클라우드

클라우드 컴퓨팅은 계속해서 인기를 얻고 있다. 시스템 설계와 아키텍처에서 이러한 서비스와 모델에 대해 알아둘 필요가 있다.

반응형

'Software Engineering > 시스템 설계' 카테고리의 다른 글

시스템 설계 시작하기  (0) 2023.05.05

댓글