최신 트랜잭션 스택

최신 트랜잭션 스택

최신 트랜잭션 스택 PlatoBlockchain 데이터 인텔리전스. 수직 검색. 일체 포함.

트랜잭션 데이터베이스는 오랫동안 애플리케이션 디자인의 가장 중요한 구성 요소였습니다. 왜? 안정적인 데이터베이스는 일반적으로 지저분하고 분산된 세상에서 정확성을 위한 궁극적인 시행 지점이기 때문입니다. 그것들이 없으면 우리는 초과 지불하고 과소 청구할 것입니다. 우리는 공항에서 집으로 가려고 하는 라이더를 잃을 것이고 장바구니에 있는 품목을 잃을 것입니다. 우리의 온라인 계정은 분실, 복제 또는 손상되어 사용할 수 없게 됩니다. 

실제로 트랜잭션 데이터베이스(일반적으로 OLTP - 온라인 트랜잭션 처리의 줄임말 - 데이터베이스)는 응용 프로그램 개발의 중심 역할을 하여 시간이 지남에 따라 점점 더 많은 응용 프로그램 기능을 사용하게 되었습니다. 그러나 마이크로서비스 및 기타 최신 애플리케이션 아키텍처는 애플리케이션 설계에 새로운 복잡성을 도입했습니다. 개발자는 다양한 서비스에서 데이터를 관리하고 서비스 간의 일관성을 보장해야 했기 때문에 복잡한 데이터 동기화 및 처리 메커니즘을 사내에서 구축해야 했습니다. 

따라서 업계에서는 거래 보증이 기존 모델 외부에서 필요하다는 인식이 높아지고 있습니다. 우리는 보고있다 데이터베이스를 넘어 분산 앱 자체로 강력한 트랜잭션 보장을 확장하는 시스템의 출현

우리는 지난 몇 년 동안 이러한 솔루션을 추적해 왔습니다. 일반적으로 확장 문제를 일으키지 않고 최신 프로그래밍 환경을 제공하면서 대규모 분산 앱에서 상태의 트랜잭션 관리를 허용하기 위해 노력합니다. 

이러한 솔루션은 대략 두 가지 범주로 나뉩니다. 하나의 카테고리는 워크플로 오케스트레이션. 이는 기본적으로 오류가 발생하더라도 코드 블록이 완료될 때까지 실행되도록 보장합니다. 따라서 불안정하지 않고 결정론적으로 분산 상태 머신을 관리할 목적으로 사용할 수 있습니다. 두 번째 카테고리는 데이터베이스 + 워크플로우, 기존 OLTP 데이터베이스 설계를 확장하여 동일한 목적으로 임의의 코드를 실행할 수 있습니다. 

이것은 여전히 ​​초기 단계이며 명명법, 각 도구가 실제로 어떻게 사용되는지, 누가 사용해야 하는지에 대해 많은 혼란이 있습니다. 더 나은 이해를 돕기 위해 선도적인 엔지니어링 조직의 실무자들에게 트랜잭션 스택에 대해 질문하고 트랜잭션 워크로드의 세 가지 핵심 개념인 애플리케이션 상태, 비즈니스 논리 및 비즈니스 데이터에 대해 어떻게 생각하는지 물었습니다. 

그러나 이 새로운 스택을 검토하기 전에 여기까지 온 방법을 이해하는 데 도움이 되는 간단한 준기술적 여담이 있습니다.

거래, 보증 및 최신 앱 

매우 대략적인 버전은 다음과 같습니다. 모든 작업을 수행하거나 전혀 수행하지 않으려는 일련의 작업(트랜잭션)이 있습니다. 그 사이에 있는 모든 것(부분적으로 수행됨)은 손상된 상태로 끝납니다. 보장이 어렵네요 아무것도 분산 시스템에서는 데이터베이스가 트랜잭션을 잘 수행합니다. 따라서 많은 시스템에서 보증을 처리하는 가장 쉬운 방법은 대부분의 항목을 트랜잭션으로 만들고 데이터베이스에서 처리하도록 하는 것입니다.

최신 앱은 많은 사용자가 많은 작업을 수행하는 대규모 분산 시스템입니다. 따라서 앱 상태를 일관되게 유지하는 것(예: 체크아웃 흐름에서 다른 사용자가 있는 위치 추적)은 분산 트랜잭션 문제로 바뀝니다. 기존의 모놀리식 아키텍처에서는 OLTP 데이터베이스와 함께 SQL을 사용하여 트랜잭션을 관리하는 것이 어느 정도 효과적이었습니다. 그러나 더 높은 수준의 API(예: REST 또는 gRPC)를 통해 상호 작용하는 새롭고 복잡한 마이크로 서비스 세계에서는 트랜잭션 요구 사항이 본질적으로 분산되었습니다. 

그러나 마이크로서비스로의 여정을 진행 중인 많은 회사는 강력한 트랜잭션 보장을 데이터베이스 이상으로 확장하기 위해 많은 노력을 기울이지 않았습니다. 그리고 실제로는 거의 언제나 좋아요. 그러나 애플리케이션이 확장됨에 따라 데이터의 불일치가 증가하고 비즈니스 데이터의 버그 및 조정되지 않은 오류가 발생합니다. 물론 큰 문제가 될 수 있습니다. 이로 인해 애플리케이션 개발자는 광범위한 장애 시나리오 및 충돌 해결 전략을 처리하고 서로 다른 아키텍처 패턴을 통해 자체 전략을 제시함으로써 상태 일관성을 보장해야 합니다.

정의

비즈니스 데이터("데이터") 지속성과 처리를 위해 전통적으로 OLTP 데이터베이스에 저장되는 비즈니스 크리티컬 데이터를 말합니다(예: 이름, 주소, 신용 점수 등과 같은 사용자 프로필 정보).

애플리케이션 상태 시스템의 현재 상태를 나타냅니다. 응용 프로그램 상태는 데이터 저장 시스템에 저장된 값과 유한 상태 기계에서 프로그램 실행 단계(예: "주문 접수", "재고 확인", "신용 확인"과 같은 주문 상태)에 의해 결정됩니다. ,' '배송됨', '반품됨').

비즈니스 로직 실행 세부 정보 대신 애플리케이션이 실제로 작동하는 방식 또는 수행하는 작업을 처리하는 프로그램의 일부를 나타냅니다(예: "사용자 소득 > $100K & 신용 점수 >650 ⇒ 모기지 승인 = TRUE").

이 논의의 목적을 위해 애플리케이션 상태와 비즈니스 데이터를 구분하는 것이 중요합니다. 예를 들어 고객이 신용 카드를 입력했지만 체크아웃하지 않은 것을 아는 것은 애플리케이션 상태입니다. 신용 카드 데이터와 애플리케이션 카트의 항목이 비즈니스 데이터입니다. 

최신 트랜잭션 스택 PlatoBlockchain 데이터 인텔리전스. 수직 검색. 일체 포함.

일반적인 흐름에서 요청은 프런트 엔드에서 오고 인증된 다음 API 게이트웨이 또는 GraphQL을 통해 관련 엔드포인트로 라우팅됩니다. 

이 단일 API 끝점은 이제 최종 고객에게 비즈니스 트랜잭션을 제공하기 위해 수십 또는 수백 개의 마이크로 서비스를 조정해야 합니다. 여기에서 개발자는 일반적으로 모든 것을 비즈니스 논리 blob으로 묶은 다음 대기열, 캐시 및 손으로 코딩한 재시도 메커니즘의 조합을 사용하여 데이터를 데이터베이스로 가져옵니다. 전체 트랜잭션으로 커밋되기를 바랍니다.

애플리케이션의 규모가 커짐에 따라 대기열 및 캐시 관리의 복잡성과 문제 발생 시 조정 논리의 날카로운 모서리 수가 증가합니다. 

워크플로 중심 및 데이터베이스 중심 트랜잭션 스택의 부상

좋아요, 거래가 중요합니다. 데이터베이스의 LAMP는 확장하기에 충분하지 않았습니다. 그리고 대기열과 재시도 논리의 거대한 털뭉치는 너무 부서지기 쉽습니다. 이 문제를 해결하기 위해 지난 몇 년 동안 우리는 트랜잭션 논리에 온전함을 되돌려주는 새로운 솔루션의 출현을 목격했습니다. 워크플로 중심 접근 방식과 데이터베이스 중심 접근 방식으로 크게 분류할 수 있습니다.

현재까지 워크플로 엔진은 비즈니스 데이터가 아닌 애플리케이션 상태에서 주로 작동하며 기존 데이터베이스와 통합할 때 종종 약간의 복잡성이 필요합니다. 데이터베이스 중심 접근 방식은 비즈니스 데이터와 함께 애플리케이션 논리를 추가하지만 워크플로 엔진과 동일한 코드 실행 정교함을 아직 갖추지 못했습니다. 

아래 다이어그램은 워크플로 및/또는 데이터베이스 중심 접근 방식이 Javascript/Typescript 애플리케이션에서 사용되는 방식에 대한 대략적인 스케치를 제공하며 둘 다 사용 중이라고 가정합니다. 그것들은 오늘날 이 아키텍처의 별개의 부분이지만 데이터베이스가 워크플로우 기능을 통합하고 워크플로우가 내구성 있는 스토리지를 채택하기 시작하는 추세의 초기 징후를 보았습니다. 이러한 기능의 병합은 현대 아키텍처에서 두 접근 방식 사이의 경계가 흐려지고 덜 뚜렷해지고 있음을 나타냅니다. 

최신 트랜잭션 스택 PlatoBlockchain 데이터 인텔리전스. 수직 검색. 일체 포함.

워크플로 중심 접근 방식 세부 정보 

워크플로는 응용 프로그램 상태 시스템을 발전시키는 이벤트 또는 타이머를 기반으로 실행되는 단순한 코드 블록입니다. 트랜잭션 워크플로는 강력한 보장으로 코드 실행을 보장하여 애플리케이션에서 부분적이거나 의도하지 않은 상태를 방지합니다. 개발자는 로직을 작성하고 워크플로 엔진은 트랜잭션, 변형 및 멱등성을 처리합니다. 서로 다른 워크플로우 엔진은 트랜잭션 세부 정보가 개발자에게 얼마나 많이 노출되는지에 대해 서로 다른 장단점을 만듭니다. 

예를 들어, 아래는 Orkes(Conductor)에서 실행되는 체크아웃 워크플로우의 시각적 표현입니다. 

최신 트랜잭션 스택 PlatoBlockchain 데이터 인텔리전스. 수직 검색. 일체 포함.

다음의 두 가지 거친 접근법 워크플로 엔진이 견인력을 얻습니다. 하나(Temporal.io로 대표됨)에서 개발자는 표준 백엔드 프로그래밍 언어(예: Go 또는 Java)를 사용하여 코드를 작성하고 시스템은 코드 실행을 완료하도록 보장합니다., 실패 중에도. 이 모델에서는 코드가 차단 호출이 완료(예: 읽기 또는 쓰기)되기를 기다리는 경우에도 프로그램 호출 스택이 유지됩니다. 이를 위해 오류 발생 시 부분 코드 실행을 방지하도록 언어 런타임이 수정됩니다. 이 접근 방식의 장점은 개발자가 친숙한 언어로 작성하고 유지 관리되는 호출 스택을 사용하여 쉽게 디버그할 수 있다는 것입니다. 크고 정교한 앱을 다루는 백엔드 팀에서 이 접근 방식을 가장 많이 사용합니다. 

단점은 응용 프로그램 개발자에게 유용하고 안전한 인터페이스를 노출하기 위해 많은 통합 작업과 래퍼 코드가 필요한 경우가 많다는 것입니다. 또 다른 단점은 기본 언어가 아닌 사용자 지정 실행 계층에 의존하고 실행이 네이티브 언어 런타임과 다른 극단적인 경우가 있다는 것입니다. 따라서 개발자는 익숙한 언어를 사용할 수 있지만 여전히 기본 시스템이 작동하는 방식을 이해해야 합니다.  

애플리케이션 개발자(특히 Typescript/Javascript)에게 더 인기 있는 다른 접근 방식은 워크플로 엔진이 비동기 함수의 오케스트레이터 역할을 합니다. (예: Ingest, Defer 및 Trigger). 이 모델에서 타사 이벤트 또는 함수는 워크플로 엔진으로 전달되며, 애플리케이션 프로그래머가 등록한 로직을 전달합니다. 프로그래머는 다른 비동기 함수를 차단해야 할 필요성이 발생하면 제어권을 다시 돌려줘야 합니다. 장점은 이것이 프로그램에 통합하는 훨씬 더 가벼운 방법이라는 것입니다. 또한 작업하는 팀이 더 쉽게 이해할 수 있도록 코드에 충분한 구조를 적용합니다. 그러나 이 접근 방식은 도구 지원 없이 디버깅하기가 더 어려울 수 있으므로 디버깅은 플랫폼에 따라 달라지는 경향이 있습니다.

워크플로 엔진은 기존 앱에서 점진적으로 채택할 수 있다는 점에서 특히 강력합니다. 최소한의 설치 공간으로 특정 작업 흐름에 단편적으로 적용할 수 있습니다. 즉, 워크플로 엔진의 두 가지 가장 큰 단점은 데이터베이스로 확장되지 않는다는 사실에서 비롯됩니다. 결과적으로 애플리케이션 상태 및 비즈니스 데이터에 걸쳐 쿼리 가능한 단일 진실 소스가 없습니다. 또한 트랜잭션 시맨틱은 일반적으로 데이터베이스 시맨틱과 다르기 때문에 애플리케이션 개발자가 에지 조건을 처리해야 합니다. 

오늘날 표준은 아니지만 많은 경우에 워크플로를 영구 데이터 저장소로 사용할 수 있는 방법에 대한 개념적 아키텍처를 설명하고자 합니다.

워크플로 전용 아키텍처의 예

최신 트랜잭션 스택 PlatoBlockchain 데이터 인텔리전스. 수직 검색. 일체 포함.

워크플로 전용 아키텍처: JavaScript 앱

최신 트랜잭션 스택 PlatoBlockchain 데이터 인텔리전스. 수직 검색. 일체 포함.

워크플로 전용 아키텍처: 마이크로서비스를 사용하는 앱

데이터베이스 중심 접근 방식 세부 정보 

데이터베이스 중심 접근 방식은 데이터베이스에서 시작하지만 임의 코드 실행을 지원하도록 확장하여 데이터 관리와 함께 워크플로우를 허용합니다. 그들은 기본적으로 OLTP 시맨틱을 직접 노출함으로써 일반 코드 블록에 대한 변형, 트랜잭션 및 멱등성에 대한 명시적인 결정을 내릴 수 있도록 프로그래머에게 제어권을 부여함으로써 이를 수행합니다. 프로그래머는 비즈니스 로직과 비즈니스 데이터를 애플리케이션 상태와 분리하여 유지하는 책임이 있습니다. 

실제로 순수한 데이터베이스 관점은 애플리케이션 상태가 항상 비즈니스 데이터에서 파생될 수 있다는 것입니다. 이것은 일반적으로 데이터베이스에서 비즈니스 데이터를 수정하는 일련의 트랜잭션으로 응용 프로그램 상태를 저장하여 수행됩니다. 위에서 설명한 작업 흐름 시스템과 동일한 강력한 보장을 통해 코드 블록을 실행할 수 있는 데이터베이스로 생각하는 것이 가장 쉽습니다. 

내부적으로는 이것을 애플리케이션 논리 트랜잭션 플랫폼(ALTP) 궁극적으로 OLTP 트랜잭션을 애플리케이션으로 확장하기 때문입니다. 그러나 ALTP의 진정한 특징은 그린필드 앱의 경우 앱 개발자가 백엔드 인프라를 직접 관리할 필요성을 완전히 제거할 수 있다는 것입니다.  

ALTP 렌즈에서 가장 일반적으로 사용되는 접근 방식은 Firebase에서 시작되었습니다. 풀 서비스 "백엔드 경험" 인증, 데이터 저장소, 데이터베이스 등을 포함합니다. Firebase와 Supabase와 같은 최근 참가자는 그린필드 프로젝트에서 매우 인기 있는 플랫폼으로 남아 있습니다. 그리고 그들은 OLTP 루트에 충실한 경향이 있어 트랜잭션 백엔드 기능에 대한 임의 코드 실행을 지원하지 않지만 Supabase는 이미 워크플로에 대한 지원을 추가하기 시작했습니다.

그러나, 차세대 ALTP 오퍼링 Convex와 마찬가지로 데이터베이스와 함께 트랜잭션으로 임의의 코드를 실행할 수 있습니다. 이러한 제품을 사용하면 단일 코드 블록이 데이터(애플리케이션 상태 및 비즈니스 데이터)를 읽고 쓰고 변경할 수 있는 일반 언어(예: Javascript/Typescript)로 완전히 트랜잭션 호환 코드를 작성할 수 있습니다. 어떤 의미에서 이는 개발자에게 쿼리 가능한 단일 진실 소스를 제공하고 구독과 같은 워크플로 프리미티브를 제공합니다. 

ALTP는 워크플로 엔진이 데이터베이스에서 분리되는 문제를 해결하지만 결과적으로 사용자가 이점을 얻으려면 표준 OLTP가 아닌 데이터베이스 제품에 의존해야 합니다. 결과적으로 우리는 팀이 기존의 복잡한 백엔드에 통합하는 대신 그린필드 앱에 ALTP를 채택하는 것을 주로 봅니다.

최신 트랜잭션 스택 PlatoBlockchain 데이터 인텔리전스. 수직 검색. 일체 포함.

위의 다이어그램은 우리가 이야기한 많은 오퍼레이터를 합친 것입니다. 일부는 워크플로 엔진만 사용합니다. 일부는 데이터베이스 중심 접근 방식을 사용합니다. 그러나 많은 사람들이 두 가지를 모두 사용할 것입니다. 특히 워크플로를 이제 막 도입하기 시작한 경우에는 더욱 그렇습니다. 오늘날 워크플로 엔진 사용자는 대규모의 복잡한 애플리케이션을 처리하는 백엔드 팀인 경향이 있지만 이를 채택하는 풀스택 팀도 많이 보았습니다. Back-end-as-a-Service 솔루션은 애플리케이션 개발자에게 더 친숙한 경향이 있으며 앱이 기술 선택을 유도할 때 더 일반적으로 사용됩니다. 

수렴

워크플로 중심 접근 방식과 데이터베이스 중심 접근 방식이 충돌 과정에 있음이 분명해지고 있습니다. 이에 대한 주된 이유는 애플리케이션 상태와 데이터베이스 상태가 논리적으로 구별되지만 서로 의존적이며 두 가지를 모두 포함하지 않는 시스템은 올바르게 설정하고 디버그하기가 복잡하기 때문입니다.  

예를 들어 사용자의 체크아웃 프로세스에 대한 상태 시스템을 추적하는 데 사용되는 워크플로우 엔진을 고려하고 해당 사용자는 카트에 항목을 추가합니다. 일반적으로 워크플로 엔진은 오류가 발생한 경우에도 코드 단계가 실행되도록 합니다. 그러나 단계가 완전히 완료되었는지 완전히 확신할 수 없기 때문에 오류가 발생한 동안 엔진이 지정된 단계를 다시 실행해야 하는 인스턴스가 있을 수 있습니다. 해당 단계에서 비즈니스 데이터를 기존 데이터베이스(이 경우 장바구니에 있는 항목)에 쓰는 작업이 포함되고 데이터베이스가 중복 재시도를 인식하지 못하는 경우 중복 항목이 생성됩니다. 

이를 처리하는 방법에는 두 가지가 있습니다. 한 가지 방법은 응용 프로그램 개발자에게 문제를 전달하는 것입니다. 그러면 응용 프로그램 개발자는 워크플로 시스템에서 제공하는 nonce를 사용하여 하나의 항목만 작성되도록 합니다. 그러나 그것은 개발자가 멱등성을 이해하고 있다고 가정합니다. 멱등성은 제대로 하기가 매우 까다롭기로 악명이 높으며 워크플로우 시스템을 갖는 많은 마법을 제거합니다. 다른 방법은 워크플로 트랜잭션 의미 체계를 인식하는 데이터베이스에 워크플로 엔진을 연결하는 것입니다. 이것은 아직 일어나지 않았지만 그렇게 될 것이라고 믿는 것은 어렵지 않습니다. 

반면에 데이터베이스 중심 접근 방식은 일반 워크플로가 애플리케이션 개발자에게 정말 유용하다는 것을 알고 있습니다. 그래서 우리는 쿼리, 변이, 인덱스 등과 같은 전통적인 데이터베이스 기능을 지원하는 Convex와 같은 데이터베이스가 스케줄링 및 구독과 같은 기능을 구현하는 것을 보기 시작했습니다. 이를 통해 워크플로 엔진으로 사용할 수 있습니다. 즉, 강력한 보장을 통해 임의의 코드 블록을 실행할 수 있습니다. 

Ian Livingstone(이 글에 대한 피드백을 제공한 사람)은 이렇게 말했습니다.고전적인 '애플리케이션 로직을 데이터베이스로 가져오나요, 아니면 데이터베이스를 애플리케이션 로직으로 가져오나요?'입니다. 다시 재생... 이번에는 모놀리스를 깨뜨림으로써 시작되었습니다.” 수십 년 동안 그 이분법을 가지고 있었기 때문에 두 모델 모두 단기적으로는 지속될 것이 분명합니다. 장기적으로 그렇게 될지는 훨씬 덜 명확합니다. 

Charly Poly(Defer), Dan Farrelly(Inngest), David Khourshid(Stately), Ian Livingstone(Cape Security), Enes Akar(Upstash), James Cowling(Convex), Jamie Turner(Convex), Paul Copplestone(Supabase)에게 특별히 감사드립니다. ), 이 게시물을 검토하고 피드백을 제공한 Sam Lambert(PlanetScale), Tony Holdstock-Brown(Inngest), Matt Aitken(Trigger). 추가로 Benjamin Hindman(Reboot), Fredrik Björk(Grafbase), Glauber Costa(Chiselstrike), Guillaume Salles(Liveblocks), Maxim Fateev(Temporal), Steven Fabre(Liveblocks), Viren Baraiya(Orkes)에게 감사드립니다. 연구.

* * *

여기에 표현된 견해는 인용된 개별 AH Capital Management, LLC("a16z") 직원의 견해이며 16z 또는 그 계열사의 견해가 아닙니다. 여기에 포함된 특정 정보는 16z가 관리하는 펀드의 포트폴리오 회사를 포함하여 제16자 출처에서 얻은 것입니다. 신뢰할 수 있다고 여겨지는 출처에서 가져왔지만 16z는 그러한 정보를 독립적으로 검증하지 않았으며 정보의 지속적인 정확성이나 주어진 상황에 대한 적절성에 대해 어떠한 진술도 하지 않습니다. 또한 이 콘텐츠에는 타사 광고가 포함될 수 있습니다. XNUMXz는 그러한 광고를 검토하지 않았으며 여기에 포함된 광고 콘텐츠를 보증하지 않습니다.

이 콘텐츠는 정보 제공의 목적으로만 제공되며 법률, 비즈니스, 투자 또는 세금 관련 조언에 의존해서는 안 됩니다. 그러한 문제에 관해서는 자신의 고문과 상의해야 합니다. 증권 또는 디지털 자산에 대한 언급은 설명을 위한 것일 뿐이며 투자 추천이나 투자 자문 서비스 제공을 의미하지 않습니다. 또한, 이 콘텐츠는 투자자 또는 예비 투자자를 대상으로 하거나 사용하도록 의도되지 않았으며, 어떤 상황에서도 a16z가 관리하는 펀드에 투자하기로 결정할 때 의존할 수 없습니다. (16z 펀드에 대한 투자 제안은 사모 투자 각서, 청약 계약서 및 해당 펀드의 기타 관련 문서에 의해서만 이루어지며 전체 내용을 읽어야 합니다.) 언급되거나 언급된 모든 투자 또는 포트폴리오 회사 설명된 내용은 16z가 관리하는 차량에 대한 모든 투자를 대표하는 것은 아니며 투자가 수익성이 있거나 미래에 수행되는 다른 투자가 유사한 특성 또는 결과를 가질 것이라는 보장이 없습니다. Andreessen Horowitz가 관리하는 펀드의 투자 목록(발행자가 16z가 공개적으로 공개하도록 허가하지 않은 투자 및 공개적으로 거래되는 디지털 자산에 대한 미고지 투자 제외)은 https://a16z.com/investments에서 볼 수 있습니다. /.

내부에 제공된 차트와 그래프는 정보 제공의 목적으로만 사용되며 투자 결정을 내릴 때 의존해서는 안 됩니다. 과거의 성과는 미래의 결과를 나타내지 않습니다. 내용은 표시된 날짜 현재만 말합니다. 이 자료에 표현된 모든 예측, 추정, 예측, 목표, 전망 및/또는 의견은 예고 없이 변경될 수 있으며 다른 사람이 표현한 의견과 다르거나 반대될 수 있습니다. 추가 중요 정보는 https://a16z.com/disclosures를 참조하십시오.

타임 스탬프 :

더보기 안드레 센 호로비츠