[데이터 중심 애플리케이션 설계] 12. 데이터 시스템의 미래

예니·2023년 2월 25일
0
post-thumbnail

데이터 통합

데이터를 사용하는 모든 다른 상황에 적합한 소프트웨어가 있을 가능성은 낮다. 그래서 원하는 애플리케이션 기능을 제공하기 위해서는 반드시 여러 다른 소프트웨어를 함께 엮어 사용해야 한다.

파생 데이터에 특화된 도구의 결합

데이터를 다른 방식으로 표현하는 수가 늘어날수록 데이터 시스템을 통합하기가 더욱 어렵다. 데이터베이스와 검색 색인 외에도 분석 시스템에 해당 데이터의 사본을 유지해야 한다.

데이터플로에 대한 추론

  • 다른 데이터 접근 양식을 만족하기 위해 같은 데이터의 사본을 여러 저장소 시스템에 유지해야 할 때 입력과 출력을 분명히 할 필요가 있다.
  • 모든 쓰기의 순서를 결정하는 단일 시스템으로 모든 사용자 입력을 밀어넣을 수 있다면 쓰기를 같은 순서로 처리해 데이터를 다른 표현형으로 파생하기가 훨씬 쉬워진다.
  • 파생 데이터 시스템은 이벤트 로그를 기반으로 갱신하면 결정적이고 멱등성을 지녀 결함에서 복구하기가 상당히 쉬워진다.

파생 데이터 대 분산 트랜잭션

  • 서로 다른 데이터 시스템 간 일관성을 유지하는 고전적인 방법은 분산 트랜잭션이다.
  • 추상적인 수준에서 파생 데이터와 분산 트랜잭션은 다른 방식으로 유사한 목표를 달성한다.
    분산 트랜잭션파생 데이터 시스템 (CDC, 이벤트 소싱)
    쓰기 순서 결정상호 배타적인 잠금로그
    변경 효과가 정확히 한 번 나타나도록 보장하는 방식원자적 커밋결정적 재시도, 멱등성
    선형성지원함. ‘자신이 쓴 내용 읽기’ 기능 보장비동기로 갱신되므로 동시간 갱신 보장을 하지 않음
  • 훌륭한 분산 트랜잭션 프로토콜이 널리 지원되지 않는 상태에서는 로그 기반 파생 데이터가 이종 데이터 시스템을 통합하는 가장 장래성 있는 접근법으로 생각된다.

전체 순서화의 제약

  • 작은 시스템에서 이벤트 로그의 순서 전체를 보장하는 것은 가능하지만, 규모가 커지고 복잡해지면서 한계가 드러난다.
  • 이벤트의 전체 순서를 결정하는 전체 순서 브로드캐스트는 합의와 동등하다. 합의 알고리즘은 단일 노드가 전체 이벤트 스트림을 처리하기에 충분한 처리량을 가진 상황을 가정하고 설계한다. 여러 노드에서 공유하는 메커니즘은 제공하지 않으며, 단일 노드의 처리량을 넘어서는 규모의 합의 알고리즘 설계는 아직 해결되지 않은 과제이다.

인과성 획득을 위한 이벤트 순서화

  • 이벤트 간 인과성이 없는 경우 전체 순서가 정해지지 않아도 큰 문제가 아니다. 하지만 때로는 인과성이 발생하기도 한다.
  • 아직은 이 문제를 간단히 해결할 방법은 없다.

일괄 처리와 스트림 처리

일괄 처리자와 스트림 처리자는 입력을 소비해 형태를 바꾸고 필터링하고 집계해 모델을 학습하고 평가한 뒤 마지막에는 적절한 출력으로 기록하기 위한 도구다.

파생 상태 유지

입력과 출력을 잘 정의한 결정적 함수의 원리는 내결함성에 도움이 되고 조직 내의 데이터플로 추론을 단순화한다. 데이터 파이프라인은 함수형 애플리케이션 코드를 통해 한 시스템의 상태 변화를 밀어 넣고 그 결과를 파생 시스템에 적용한다.

애플리케이션 발전을 위한 데이터 재처리

  • 파생 데이터를 유지할 때 일괄 처리와 스트림 처리는 모두 유용하다.
  • 파생 뷰를 사용하면 점진적 발전이 가능하다. 이전 스키마와 새 스키마를 함께 유지해 같은 데이터 기반으로 두 개의 독립적인 파생 뷰를 만들 수 있다. 점진적으로 새 뷰를 접근하는 사용자의 비율을 늘려가서 결국에는 기존 뷰를 내릴 수 있게 된다.

람다 아키텍처

  • 람다 아키텍처의 핵심 아이디어는 입력 데이터를 불변 이벤트로서 증가하기만 하는 데이터셋에 추가하는 방식으로 기록해야 한다는 것으로 이벤트 소싱과 유사하다.
  • 람다 아키텍처 접근법에서 스트림 처리자는 이벤트를 소비해 근사 갱신을 뷰에 빠르게 반영한다. 이후에 일괄 처리자가 같은 이벤트 집합을 소비해 정확한 버전의 파생 뷰에 반영한다.
  • 람다 아키텍처의 문제점
    • 일괄 처리, 스트림 처리 양쪽 프레임워크에서 같은 로직을 유지하는 데에는 상당한 노력이 필요하다.
    • 일괄 처리, 스트림 처리의 파이프라인은 분리된 출력을 생산하므로 출력을 병합해야하는데 이것이 어렵다.
    • 전체 과거 데이터를 재처리를 자주 수행할 때 많은 비용이 든다. 증분으로 일괄 처리한다면 복잡성이 증가한다.

일괄 처리와 스트림 처리의 통합

최근에는 같은 시스템에서 일괄 처리 연산과 스트림 연산을 모두 구현함으로써 람다 아키텍처의 장점만 취할 수 있게 하는 작업이 진행되고 있다.

데이터베이스 언번들링

데이터 저장소 기술 구성하기

데이터베이스에 내장된 기능과 일괄 처리와 스트림 처리로 구축하는 파생 데이터 시스템 사이에는 유사점이 있다.

색인 생성하기

관계형 데이터베이스에 새 색인을 생성하기 위해 일관된 스냅숏을 사용한다. 파생 데이터 시스템에서의 변경 로그와 데이터베이스의 상태 스냅숏은 상당히 관련이 있다.

모든 것의 메타데이터베이스

모든 접근 패턴에 적합한 단일 데이터 모델이나 저장 형식이 없다고 할 때, 서로 다른 저장소와 처리 도구를 사용하지만 하나의 응집된 시스템으로 구성할 수 있는 두 가지 길이 있다.

  • 연합 데이터베이스 : 읽기 통합
  • 언번들링 데이터베이스 : 쓰기 통합

언번들링이 동작하게 만들기

  • 쓰기를 동기화하는 전통적인 접근법은 이종 저장소 시스템 간 분산 트랜잭션이다. 하지만 데이터가 다른 기술 사이 경계를 오간다면 멱등성을 기반으로 쓰기를 수행하는 비동기 이벤트 로그를 사용하는 편이 더 강력하고 현실적이다.
  • 로그 기반 통합의 큰 장점은 다양한 구성 요소 간 느슨한 결합이다.
    • 시스템 수준에서 비동기 이벤트 스트림을 사용하면 전체 시스템이 개별 구성 요소의 장애나 성능 저하가 생겨도 잘 견디게 만들 수 있다.
    • 이벤트 로그는 인터페이스를 제공하고 범용적이므로 소프트웨어 구성 요소를 독립적으로 유지보수할 수 있다.

언번들링 대 통합 시스템

  • 언번들링의 목표는 특정 작업부하에 대한 성능 측면에서 개별 데이터베이스와 경쟁하는 것이 아니다. 몇 개의 다른 데이터베이스를 결합해 단일 소프트웨어로 가능한 것보다 더 넓은 범위의 작업 부하에 대해 좋은 성능을 달성하기 위함이다. 깊이가 아니라 폭에 관한 것이다.
  • 필요한 모든 것을 만족하는 단일 기술이 있다면 저수준 구성 요소로부터 직접 재구현하려 하지 말고 그냥 해당 제품을 사용하는 것이 좋다. 언번들링의 장점은 요구사항을 모두 만족하는 단일 소프트웨어가 없는 상황에만 드러난다.

데이터플로 주변 애플리케이션 설계

데이터 시스템은 내결함성과 확장성이 있어야 하고 지속성있게 데이터를 저장해야 한다. 데이터 시스템은 시간이 흐름에 따라 이종 기술과도 통합이 가능해야 하고 이미 존재하는 라이브러리와 서비스를 재사용 가능해야 한다.

애플리케이션 코드와 상태의 분리

요즘 추세는 상태 관리(데이터베이스)와 상태 비저장 애플리케이션 로직을 분리한다. 즉 데이터베이스에 애플리케이션 로직을 넣지 않고 애플리케이션에 영구적인 상태를 넣지 않는다.

데이터플로: 상태 변경과 애플리케이션 코드 간 상호작용

스트림 처리자에서 애플리케이션 코드를 스트림 연산자로 실행할 수 있다.

애플리케이션 코드로 데이터베이스에 내장된 파생 함수가 일반적으로 지원하지 않는 임의 처리가 가능하다.

스트림 처리자와 서비스

  • 스트림 연산자로 데이터플로 시스템을 구성하는 것은 마이크로서비스 접근법과 유사한 특징이 있다.
  • 하지만 기반이 되는 통신 메커니즘은 매우 다르다. 마이크로서비스 접근법이 동기식 요청/응답 상호작용을 사용하지만 스트림 연산자로 구성한 시스템은 단방향 비동기식 메시지 스트림을 사용한다.

파생 상태 관찰하기

  • 쓰기 경로 시스템에 정보를 기록할 때마다 일괄 처리와 스트림 처리의 여러 단계를 거친 다음 결과적으로 기록된 데이터를 모든 파생 데이터셋에 통합해 갱신한다.
  • 읽기 경로 파생 데이터셋을 생성하는 이유는 이후에 다시 질의할 가능성이 크기 때문이다. 사용자 요청을 처리할 때 먼저 파생 데이터셋을 읽고 그 결과를 어느 정도 가공한 후 사용자 응답을 만든다.
  • 파생 데이터셋은 쓰기 경로와 읽기 경로가 만나는 장소다.

구체화 뷰와 캐싱

캐시와 색인, 구체화 뷰는 읽기 경로와 쓰기 경로 사이의 경계를 옮기는 단순한 역할을 한다. 이런 파생 데이터셋을 사용하면 쓰기 경로에서 더 많은 일을 수행해 미리 결과를 계산할 수 있기 때문에 읽기 경로의 작업이 줄어든다.

오프라인 대응 가능한 상태 저장 클라이언트

상태 비저장 클라이언트가 항상 중앙 서버와 통신한다는 가정에서 벗어나 최종 사용자 장치에서 상태를 유지하는 쪽으로 나아가면 새로운 기회가 있는 세상이 열린다. 특히 장치 상 상태를 서버 상 상태의 캐시로 생각할 수 있다. 클라이언트 앱의 모델 객체는 원격 데이터센터의 상태를 로컬에 복제한 것이고 화면의 화소는 클라이언트 앱의 모델 객체를 보여주는 구체화 뷰다.

상태 변경을 클라이언트에게 푸시하기

  • 서버 전송 이벤트와 웹소켓은 웹브라우저가 서버와 TCP 접속을 유지하면서 연결이 유지되는 동안 서버가 주도적으로 메시지를 브라우저에 보내는 방식의 통신 채널을 제공한다.
  • 쓰기 경로와 읽기 경로 모델 측면에서 상태 변화를 적극적으로 클라이언트 장치에까지 푸시하면 쓰기 경로가 최종 사용자까지 확장된다.

종단 간 이벤트 스트림

  • 상태 변경은 종단 간 쓰기 경로를 따라 흐를 수 있다. 상태 변경이 트리거된 한 장치의 상호작용으로부터 이벤트 로그를 거쳐 여러 파생 데이터 시스템과 스트림 처리자를 통해 다른 장치의 상태를 보고 있는 사람의 사용자 인터페이스까지 이어진다.
  • 쓰기 경로를 최종 사용자까지 확장하려면 요청/응답 상호작용 방식에서 벗어나 발행/구독 데이터플로 방식으로 변경해야 한다.

읽기도 이벤트다

  • 쓰기와 읽기 모두 이벤트로 표현하고 이벤트 처리를 위해 같은 스트림 연산자로 라우팅하는 것은 사실상 읽기 질의 스트림과 데이터베이스 사이의 스트림 테이블 조인 수행과 동일하다.
  • 읽기 이벤트 로그를 기록하면 잠재적으로 인과적 의존성과 시스템 전체의 데이터 출처를 추적할 수 있다는 이점이 있다.
  • 하지만 이 방법은 추가적인 저장소가 필요하고 IO비용이 더 발생한다. 해결해야하는 문제다.

다중 파티션 데이터 처리

다중 파티션 조인을 수행해야한다면 스트림 처리자를 사용해 구현하는 것보다 이 기능을 제공하는 데이터베이스를 사용하는 편이 간단하다.

정확성을 목표로

데이터베이스 같은 상태 저장 시스템은 영원히 기억하게끔 설계됐기 때문에 무언가 잘못되면 그 효과가 영원히 지속될 가능성이 있으므로, 좀 더 신중하게 생각해야 한다.

데이터베이스에 관한 종단 간 논증

연산자의 정확히 한 번 실행

정확히 한 번은 연산이 어떤 결함 때문에 실제로 연산자를 재시도했더라도 결함이 없었던 것과 동일한 결과를 최종적으로 얻기 위해 계산을 조정한다는 뜻이다.

가장 효과적인 접근법은 연산을 멱등으로 만드는 것이다.

연산 식별자

  • 여러 네트워크 통신 홉을 통과하는 연산을 멱등적으로 만들기 위해 데이터베이스가 제공하는 트랜잭션 메커니즘에 의존하는 것은 충분하지 않다. 해당 요청의 종단 간 흐름을 생각할 필요가 있다.
  • 연산의 고유 식별자를 만들어 요청마다 사용한다면 특정 ID에 대해 딱 한 번만 연산을 실행할 수 있다.

종단 간 논증

  • 문제 기능은 통신 시스템의 종단점에 위치한 애플리케이션의 지식과 도움이 있어야만 완벽하고 정확하게 구현 가능하다. 따라서 문제 기능을 통신 시스템 자체 기능으로 제공하는 것은 불가능하다.
  • TCP, 데이터베이스 트랜잭션, 스트림 처리자 자체만으로는 이러한 중복 문제를 해결할 수 없다. 이 문제는 종단 간 해결이 필요하다. 바로 최종 사용자 클라이언트로부터 데이터베이스에 이르는 모든 경로에 트랜잭션 식별자를 포함하는 방법이다.
  • 종단 간 논증은 데이터 무결성 검사, 암호화에도 적용할 수 있다.

종단 간 사고를 데이터 시스템에 적용하기

  • 애플리케이션이 직렬성 트랜잭션과 같은 비교적 강한 안전성 속성을 지원하는 데이터 시스템을 사용한다고해서 애플리케이션에 데이터 손실이나 손상이 발생하지 않는다고 말할 수 없다. 애플리케이션 자체가 중복 억제와 같은 종단 간 대책을 갖출 필요가 있다.

제약 조건 강제하기

유일성 제약 조건은 합의가 필요하다

  • 이 합의를 달성하는 가장 일반적인 방법은 단일 노드를 리더로 만들고 해당 노드가 모든 결정을 하게끔 책임을 부여하는 것이다.
  • 유일성 검사는 유일성이 필요한 값을 기준으로 파티셔닝하면 확장 가능하다.

로그 기반 메시징의 유일성

  • 스트림 처리자는 단일 스레드 상에서 한 로그 파티션의 모든 메시지를 순차적으로 소비한다. 따라서 유일성이 필요한 값을 기준으로 로그를 파티셔닝하면 스트림 처리자는 충돌이 발생한 연산 중 어떤 것이 처음 들어온 연산인지 분명하면서도 결정적으로 판결할 수 있다.
  • 이 방식은 각 파티션을 독립적으로 처리할 수 있기 때문에 파티션 수를 늘리면 쉽게 확장할 수 있어 대규모 요청을 처리할 수 있다.

다중 파티션 요청 처리

  • 파티셔닝된 로그를 사용하면 원자적 커밋 없이 동등한 정확성을 달성할 수 있다.
  • 다중 파티션 트랜잭션을 서로 다르게 파티셔닝된 두 단계로 나누고 종단 간 요청 ID를 사용하면 결함 존재 여부와 상관없이, 그리고 원자적 커밋 프로토콜을 쓰지 않고도 동일한 정확성 속성을 달성할 수 있다.

적시성과 무결성

일관성이라는 용어는 두 가지 요구사항이 합쳐진 것이다.

  • 적시성 (Timeliness) 적시성은 사용자가 시스템을 항상 최신 상태로 관측 가능하다는 의미다. 적시성 위반은 최종적 일관성이고, 무결성 위반은 영구적 불일치다.
  • 무결성 (Integrity) 무결성은 손상이 없다는 뜻이다. 즉 누락된 데이터도, 모순된 데이터도, 잘못된 데이터도 없다는 뜻이다.

데이터플로 시스템의 정확성

  • ACID 트랜잭션은 대개 적시성과 무결성 양쪽 모두 보장한다.
  • 이벤트 기반 데이터플로 시스템은 적시성과 무결성을 분리한다.
  • 정확히 한 번이나 결과적으로 한 번 시맨틱은 무결성을 보존하는 메커니즘이다.

느슨하게 해석되는 제약 조건

  • 많은 비즈니스 맥락에서 제약 조건을 일시적으로 위반하고 나중에 사과해 바로잡는 것은 실제로 수용 가능한 방법이다.
  • 이런 경우에는 적시성이 반드시 필요한 것은 아니지만, 무결성은 반드시 요구된다.

코디네이션 회피 데이터 시스템

데이터플로 시스템은 코디네이션 없이도 많은 애플리케이션용 데이터 관리 서비스를 제공할 수 있고 여전히 무결성을 강력하게 보장한다. 이런 코디네이션 회피 데이터 시스템은 동기식 코디네이션이 필요한 시스템보다 성능이 더 좋고 더 나은 내결함성을 가진다.

믿어라. 하지만 확인하라

시스템 모델은 이원 접근법을 사용한다. 어떤 상황은 발생할 수 있고 다른 어떤 상황은 절대 발생하지 않는다고 가정한다.

소프트웨어 버그가 발생해도 무결성 유지하기

약속을 맹목적으로 믿지 마라

검증하는 문화

대부분의 시스템은 정확하게 작동한다고 가정한다. 이 가정은 합리적이지만 항상 올바르게 작동한다는 가정과는 다르다. 정확성 보장이 절대적이라고 가정하며 희박한 데이터 손상 가능성은 대비하지 않는다. 무결성 확인을 백지 위임하기보다는 스스로 무결성 확인을 지속적으로 수행하는 자가 검증이나 자가 감사 시스템이 필요하다.

NoSQL의 기치 아래 완화된 일관성 보장이 표준이 됐고, 감사 메커니즘이 더 중요해졌다.

감사 기능 설계

  • 트랜잭션은 왜 이런 변경을 수행했는지 명확한 모습을 알 수 없고, 이 변경을 결정한 애플리케이션 호출은 일시적이라서 재현할 수 없다.
  • 이벤트 기반 시스템은 결정적이고 반복 가능하다. 같은 버전의 파생 코드를 통해 같은 이벤트 로그를 실행하면 동일한 상태 갱신 결과를 만들 수 있다.
  • 데이터플로를 명시적으로 만들면 데이터의 유래가 더욱 명확해져서 무결성 확인이 좀 더 수월해진다.

다시 종단 간 논증

  • 시스템의 모든 개별 구성 요소가 절대로 손상되지 않는다고 완전히 믿기 어렵다면 최소한 데이터의 무결성만이라도 주기적으로 확인해야 한다.
  • 데이터 시스템의 무결성을 확인하는 방법은 종단 간 방식이 최선이다. 무결성 확인이 가능한 시스템이 많을수록 처리 과정의 어떤 단계에서 손상이 발견되지 않을 가능성이 낮아진다. 종단 간 무결성 확인을 꾸준히 하면 시스템이 정확하다는 확신이 높아져 더 빠르게 옮겨갈 수 있다.

감사 데이터 시스템용 도구

현재 감사 기능을 최고 수준으로 고려하는 시스템은 많지 않다.

무결성을 증명하려고 많은 도구들이 사용된다.

트랜잭션 로그, 암호화 도구 (암호화폐, 블록체인, 분산 원장)

옳은 일 하기

소프트웨어 개발에 윤리적 선택이 갈수록 중요해진다.

예측 분석

편견과 차별

알고리즘이 내린 결정이 사람이 내린 결정보다 반드시 좋거나 나쁜 것은 아니다.

예측 분석 시스템은 오직 과거로부터 추정한다. 데이터와 모델은 도구여야지 주인이 돼서는 안된다.

책임과 의무

의사결정 자동화는 아직 책임과 의무에 대한 문제가 해결되지 않았다. 알고리즘이 실수했을 때 누가 책임을 질 것인가?

사생활과 추적

데이터 수집은 그 자체로 윤리적 문제가 있다.

동의와 선택의 자유

사용자가 데이터 제공에 동의했기 때문에 데이터를 수집했다고 주장할 수 있다. 하지만 사용자는 무슨 데이터가 수집되는지, 그 데이터로 무엇을 하는지 알 수 없다. 또한 데이터 제공에 대한 대가로 받는 서비스를 협상하거나 선택할 수도 없다.

하지만 이 데이터 제공에 동의하지 않을 수 없다. 서비스를 반드시 사용해야하는 환경에 처해있기 때문이다. 선택의 자유가 없다.

사생활과 데이터 사용

사생활은 누구에게 어떤 것을 보여주고 공개할 것인지, 어떤 것을 비밀로 할지 고를 수 있는 자유를 가진다는 의미다. 데이터 제공을 통해 이런 사생활 관리가 기업으로 대규모 이전된다.

자산과 권력으로서의 데이터

타게팅 광고를 위해서 행동 데이터는 핵심 자산이다. 데이터 중개상도 존재한다.

산업 혁명의 기억

데이터는 정보화 시대의 본질적 특징이다.

산업 혁명이 주요한 기술과 농업의 발전을 통해 이뤄졌고 많은 문제가 있었던 것처럼 이런 문제들은 시대가 바뀌면서 직면하는 문제들이다.

법률과 자기 규제

데이터 보호법으로 개인의 권리를 보호할 수 있다. 하지만 법률로 보호하는 데에는 한계가 있기 때문에 각 개인은 스스로의 사생활을 보호할 수 있어야 한다.

1개의 댓글

comment-user-thumbnail
2023년 4월 27일

이 책이 쉬운 내용이 아닌데 단 시간내에 다 읽으셨네요. 매일매일 읽는 것이 쉬운 일이 아니었을 건데 너무 멋있어요.

답글 달기