[DDIA] 서론 및 Part 1-1. Reliability

Matthew Woo·2022년 2월 20일
0

Computer Science

목록 보기
7/12
post-thumbnail

시리즈 시작에 앞서..

Martin Kleppmann 의 저서 Designing-Data-Intensive-Applications 를 읽고 정리를 해놓고자 합니다.
블로그를 쓰면서 힘든 점은 이 글의 소비자를 누군지로 설정하는 것입니다. 문과출신에 토론을 좋아하고 토론 동아리에도 잠깐 몸담았던 입장에서, 글을 읽는 이가 누구인지를 정하지 않은 상태에서는 과연 좋은 글은 커녕 읽는 이를 특정하지 않고 글을 쓸 수 있는건가 싶습니다만 그게 지금 제 상황입니다.. 누가 읽을 글인지를 설정하거나 글의 컨셉, 방향은 쓰다보면 어느샌가 특정하되게 수렴하지 않을까 싶습니다.

글을 읽는이가 특정되지 않았을 때 문제점은 다음과 같습니다. 소비자가 필자인 저라고 가정해보겠습니다. 제가 공부하고 추후에 제가 보면서 다시금 상기되고 복습될 수 있게끔 작성하고, 제 생각이나 사견을 최대한 반영하게 될 것입니다. 허나 공개적으로 불특정 다수에게 전달되는 글이라고하면 다소 표현이 달라져야겠죠. 사실 불특정 다수는 고려하고 있지않지만 지금 고민은 저 혼자 추후에도 보며 처음에 든 생각이나 연관된 개념들을 자유롭게 작성을 해놓을 것이냐 아니면 지금 알고리즘 스터디를 같이하는 팀원들이나 같이 공부하는 지인들에게도 권할 수 있고 공유할 수 있을 정도로 보다 꼼꼼하게 정리하고 번역된 방식으로 남기느냐입니다. 후자로 시작해서 지인들에게 공유해도 별로 봐주시는 분들이 없어 나만 보는 글로 전향되지 않을까라는 예상도 해봅니다.

번역본링크(교보문고)
링크에 목차가 자세히 나와있지만 이 책은 크게

Part 1. Foundations of Data Systems
Part 2. Distributed Data
Part 3. Derived Data

로 나누어져있으며 각 파트당 4개정도의 챕터로 이루어져있습니다. 제가 필요한 부분을 주로 정리하게 될 것이다보니 모든 부분을 커버하지 못할 수도 있습니다. 저는 원문으로 읽고 제가 번역하여 작성하는지라 번역도 매끄럽지 못하겠지만 혹시 이 글을 보시는 분들에게도 조금이나마 도움이 되었으면 합니다.

서론 및 이 책을 읽어야하는 이유

데이터의 양, 데이터의 복잡도, 데이터의 변경 속도 와 같이 도전적인 과제를 다루는 application 을 data-intensive 하다 라고 칭합니다. 다양한 툴들과 기술둘이 이러한 data-intensive(데이터 집약적인) application 들의 데이터를 저장하고 처리할 수 있도록 발전해왔습니다. NoSQL 과 같은 새로운 타입의 데이터베이스도 많은 주목을 받아왔으나 message queues, cache, search indexes frameworks, stram processing 을 비롯한 관련 기술들 또한 상당히 중요합니다. 많은 application들이 이러한 요소들을 복합적으로 사용하고 있기 때문입니다.
많은 전문용어들도 생겼고 많은 선택지가 생긴 것이 좋은 것이지만 소프트웨어 엔지니어와 아키텍처입장에서는 이러한 다양한 기술적인 부분을 정확하고 정밀하게 이해하며 각 기술들의 trade-off가 어떻게 되는지 이해할 필요가 있습니다.

다행스럽게도 빠르게 변화가 생기는 기술들의 내면에는, 기술들의 버전이나 툴에 상관없이 적용되는 원리(principles)들 이 있습니다.이러한 원리들을 이해한다면 각 기술들이 어떻게 적용되어야 할지, 어떻게 잘 사용하며 기술적인 어려움을 피할 수 있을지 습득하게 될 것 입니다. 그래서 이 책이 나온 것이죠.

이 책은 이러한 시스템의 내면 파고들어 조명합니다. 각 시스템에 사용되는 키 알고리즘이 무엇인지 짚어내고 그것들의 원리와 그들이 가진 trade-off가 무엇인지 논의합니다. 어떻게 각 시스템이 작동하는지 파악할 뿐만 아니라 왜 그 시스템이 해당 방식으로 작동하는지, 어떤 질문들을 던져야할지도 함께 찾아낼 것 입니다.

이 책을 읽고 나면 어떤 종류의 기술을 목적에 맞게 사용하고, 훌륭한 아키텍처 설계를 위해 적합한 기술들을 결정 할 수 있습니다. 또한 당신이 사용하고 있는 시스템이 내부적으로 어떻게 작동하는지 직관적으로 파악하며 해당 시스템의 작동하는 방식을 추론할 수 있습니다.


Part 1. Foundations of Data Systems

chapter 1. Reliable, Scalable, and Maintainable Applications

오늘날 사용하는 많은 application들이 data-intensive 하며 다음과 같은 요소들을 필요로 합니다.

  • 데이터를 저장하고, 다른 application이 이후에 이를 조회 할 수 있습니다. (databases)
  • 연산의 결과를 저장하고 해당 결과를 빠르게 읽기위한 (caches)
  • 유저들이 키워드로 데이터를 찾거나 여러 방식으로 필터링할 수 있습니다. (search indexes)
  • 다른 프로세스에 메세지를 전달하고 비동기적으로 처리될 수 있도록 합니다. (stream processing)
  • 축적된 많은 데이터를 주기적으로 일괄 처리하기 (batch processing)

위 요소들은 분명 필요한 요소들이지만 시스템들이 위와 같은 요소들의 추상화(abstraction)을 잘해놓았기에 우리는 이런 요소들을 너무 의식하지 않고 사용합니다. 대다수의 엔지니어들이 application을 빌드하면서 새로운 데이터 저장을 위한 엔진을 밑단에서부터 설계하는 것을 고려하진 않는다. 이미 perfectly하게 상당히 좋은 데이터베이스들이 나와있기 때문이다. 허나.. 상당히 많은 데이터베이스 시스템들이 나와있으며 각기 다른 특징을 갖고 있다. 각 db들이 caching, search indexes 를 비롯한 다른 접근법을 이용한다. 따라서 application을 빌드할 때 어떤 것이 가장 적합할지 알아낼 수 있어야한다. 이번 챕터에서는 데이터 시스템의 세 가지 요소를 알아볼 것 입니다: reliable(신뢰성), scalable(확장성), maintainable(영속성).

Thinking About Data Systems

databases, queues, caches 등을 생각해보면 각기 다른 카테고리로 분류됩니다. databasemessage queue 는 일정 시간동안 데이터를 저장한다는 점에서 표면적으로는 비슷해보이지만 둘은 상당히 다른 access patterns 을 가지고 있으며 이는 포퍼먼스, 동작방식에서 다른 특징들이 있고 상당히 다르게 구현되어 있습니다.
근데 왜 우리는 Data systems라는 한 영역안에서 이들을 다루는 걸까요? 최근에 많은 데이터 저장 및 처리를 위한 툴들이 등장하였습니다. 그러다보니 이러한 툴들을 기존의 카테고리의 범주로 분류하기 애매한 부분들이 존재합니다.
예를들어 message queues 로도 사용되는 데이터베이스 (Redis)가 등장했고, message queue이면서 데이터베이스와 같이 데이터를 유지할 수 있는 (Apache Kafka) 등도 생겨 났습니다. 또한 굉장히 많은 application들이 생겨나면서 하나의 툴로 여러 application 들의 작업들을 처리하는 것이 아니라 각기 다른 툴을 이용하면서 이들을 같이 사용하게 되었습니다. Data systems 에 영향을 주는 것에는 많은 요소들이 존재합니다. 에를 들면 다음과 같은 요소들. (skills and experience of the people involved, legacy system dependencies, the time‐ scale for delivery, your organization’s tolerance of different kinds of risk, regulatory constraints 등등..)
이 책에서는 우리가 집중해야할, 소프트웨어 시스템에서 가장 주요하게 고려해야할 세 가지 부분에 집중 할 것 입니다.
(위에서 언급했던 세가지 - reliable(신뢰성), scalable(확장성), maintainable(영속성))

Reliability

무언가를 얘기하면서 그것이 reliable 한가? 또는 unreliable 한가(신뢰성이 있나 없나)를 구분하기 위한 직관적인 부분들이 있다. 소프트웨어에서는 다음과 같은 요소들이 포함된다.

  • application이 유저들의 예상대로 기능하며 작동하는가.
  • 사용자가 예상치 못한 방식으로 사용하거나, 실수를 하더라도 커버가 가능한가.
  • 예상된 load, 데이터 크기에 한해서는 예측되는 범위에서 괜찮은 퍼포먼스를 보여주는가.
  • 권한이 없는 접근이나 남용의 문제를 막을 수 있는가.

즉 한줄로 요약하자면, "things go wrong 하더라도 지속적으로 잘 작동하는가" 이다.
"things go wrong" 을 한 단어로 Faults 라고 불린다. fault(error) 가 전혀 발생하지 않도록 예방하는 것은 불가능하기에 fault 가 발생했을 때 처리를 잘 해주어야한다. 많은 치명적인 버그들이 fault, error handling을 잘 해주지 못하기에 발생한다. 이러한 fault 를 미리 예상하고 fault 가 발생해도 견딜 수 있도록 해야한다. 물론 보안과 같은 문제의 fault는 아에 발생하지 않도록 사전에 방지해야하지만 fault 를 예상, 유도한 뒤 이를 처리하여 안정성을 높이는 방법들도 있다.

Hardware Faults

많은 machine이 있는 큰 데이터센터에서 일하는 사람이라면 hardware fault 는 늘상 있는 일이라고 얘기할 것 입니다.
디스크, 램, 파워, 누군가 실수로 네트워크 케이블을 건들이는 등등의 하드웨어 문제가 발생하곤 합니다.
디스크는 RAID 로 구성해놓고, 서버는 power를 하나 더 둔다던지, cpu는 hot-swappable 을 이용, 데이터센터의 경우 배터리 혹은 디젤로 백업방안을 구상해 놓습니다. 허나 이러한 방안으로도 모든 하드웨어에서 발생하는 모든 문제를 예방할 수 없기에 오늘날 single-machine에 의존하는 경우는 극히 드뭅니다. data의 볼륨이 커지고 많은 컴퓨팅 파워를 요하기에
더 많은 수의 머신들을 이용하고 한 머신에서 문제가 생겼을 때는 다른 머신들을 이용해서 시스템 전체에 영향을 주지 않도록 합니다.

Software Errors

하드웨어의 손상은 연관된 다른 하드웨어에는 영향을 주진 않습니다. disk를 두개를 사용하고 있는데 하나에 하드웨어적인 이슈가가 생긴다 하더라도 이게 다른 연관된 머신들에 영향을 주진 않습니다. 허나 시스템 내에서 발생하는 소프트웨어와 관련된 에러는 예상하기도 어려우며 하드웨어에서 발생하는 이슈에 비해 많은 문제를 발생시킵니다.

대표적인 예시를 보면,

  • 잘못된 software 값, 버그 하나로 인해 server가 죽어버릴 수 있습니다.
  • 또한 프로세스 하나가 cpu, memort, disk, network bandwidth 하드웨어 자원을 독식할 수 있습니다.
  • 특정 component에서 발생한 작은 에러가 다른 component에도 연쇄적으로 fault를 발생시킬 수 있습니다.

버그는 특정 상황이 유발될 때까지는 발견되지 않다가 특정 조건에서 fault 를 발생시킵니다. 즉 소프트웨어는 특정 설정해놓은 환경에서 실행되는 것이고 예상치 못한 상황, 변수에서는 에러가 발생할 수 있는 것이기에 이를 세심하게 신경써야합니다. 이외에 software error를 예방에 도움을 줄 수 있는 몇가지 방안들이 있습니다. 철저하게 테스트를 하거나, 프로세스들을 isolation 해놓기, process가 crash 되면 재시작되도록하기, 모니터링, measuring, 출시 후 시스템 분석하기 등입니다.

Human Errors

한 연구결과에 따르면 하드웨어의 결함으로 발생하는 문제는 10%-25%에 불과하고 operator(조작하는 사람) 으로 인해 발생하는 에러가 프로그램이 멈추는 가장 큰 요인이라고 합니다. 이렇게 사람이 미숙해서 발생하는 에러를 줄이기 위한 몇가지 접근 방안들이 있습니다.

  • 잘 디자인한 추상화들, API, interface들을 만들어서 사람들이 잘 사용하게 하는 것 입니다.
    소프트웨어 개발자들도 각자가 짠 코드를 실행시켜주는 하드웨어의 세세한 부분까지는 잘 모를 수 있습니다. 개발자들이 하드웨어에 미숙하지만 system call(하드웨어와의 api)을 비롯하여 개발자들이 하드웨어까지 제어하는 코드를 작성하지 않아도 되는 이유가 이미 잘 디자인된 api들을 사용하고 있기 때문입니다. 하드웨어를 잘 추상화시켜놨기에 컴퓨터나 소프트웨어에 무지한 유치원생들까지도 컴퓨터를 사용할 수 있는 것입니다.
  • 사람들이 빈번하게 실수, 혹은 문제를 발생시킬 수 있는 지점과 사람들을 분리합니다.
  • 여러 단계에 걸친 꼼꼼한 테스트, 전체 시스템의 통합테스트, manual 테스트, 자동화 테스트
  • 사람이 실수 하더라도 그 영향을 최소화하고 빠르게 회복될 수 있도록 하기
  • 디테일하고 명료하게 error rate, 퍼포먼스 평가표 등을 모니터링 하기
    모니터링을 통해 문제가 발생하기 전에 경고 신호를 알려줄 수 있고, 예상과 다른 현상이 모니터링 된다면 에러를 사전에 예방할 수 있고 발생했을 때도 진단에 있어서 귀중한 자산이 됩니다.

프로토타입을 개발하는 경우와 같은 상황들처럼 투입되는 개발력을 줄이기 위해 일정부분 reliability를 희생하는 선택을 우리가 할 수는 있지만 이럴 때는 이런 상황을 자각하고 있는 것이 중요합니다.. reliability는 상당히 중요한 요소이기 때문입니다.


요새 알고리즘 스터디에 시간을 많이 소요하고 있지만 시간내서 가급적 빠른 시일내에 다음 글에서 Scalability(확장성)과 Maintainability(영속성)으로 이어 다루도록하겠습니다.
또한 이 책의 번역본이 있는 줄 몰랐는데 번역본이 있기에.. 제가 굳이 자세한 설명을 한다기보단 잘 풀어서 설명하는 방식으로 보다 텍스트를 좀 줄이고 요약하며 딱딱하지 않게 작성하도록하겠습니다.

profile
지속가능하고 안정적인 시스템을 만들고자 합니다.

1개의 댓글

comment-user-thumbnail
2022년 4월 30일

외국취업을 위해선 필수...!

답글 달기