2025년 10월 11일 토요일

팔란티어 온톨로지 플랫폼 아키텍처 기술 해부 및 구현 방법

이 글은 세계적으로 주목받고 있는 팔란티어(Palantir)의 온톨로지 플랫폼 아키텍처를 소프트웨어 공학 관점에서 분석하고, 오픈소스 기술을 활용한 구현 방법을 정리한다. 팔란티어의 핵심은 기존 시스템을 대체하는 것이 아니라, 통합하고 확장하는 개방성에 있다. 이 글은 팔란티어가 어떻게 검증된 오픈소스 기술 기반 위에 독자적인 온톨로지(Ontology)라는 의미론적 추상화 계층을 구축했는지, 그리고 그 구조를 파헤쳐 본다.

팔란티어 아키텍처의 핵심 철학 - 개방과 통합
팔란티어 아키텍처의 근간에는 '대체가 아닌 통합'이라는 철학이 있다. 이는 기업이 이미 막대한 투자를 한 데이터 레이크, ERP, CRM과 같은 기존 IT 환경을 교체하는 대신, 이들을 하나로 묶고 그 가치를 증대시키는 플랫폼 역할을 하는 것이다.

이러한 철학은 아키텍처의 명확한 관심사 분리로 이어진다. 배포, 오케스트레이션, 데이터 처리와 같은 하위 계층은 의도적으로 쿠버네티스(Kubernetes), 스파크(Spark), 플링크(Flink) 등 보편적인 오픈소스 표준 위에 구축된다. 이를 통해 고객의 기존 기술 스택 및 엔지니어링 역량과 마찰 없이 통합된다. 반면, 온톨로지, AI 플랫폼(AIP)과 같은 상위 계층에는 팔란티어의 독자적인 지적 재산이 집중된다. 이 구조는 고객이 새로운 데이터베이스나 컴퓨팅 엔진이 아닌, 기존 자산과 상호 작용하는 새로운 패러다임을 구매하게 만들어 비지니스 가치를 제안한다.

플랫폼의 안정성과 확장성은 두 가지 핵심 기술, 즉 자율 배포 시스템인 아폴로(Apollo)와 쿠버네티스 기반의 컨테이너 오케스트레이션 기판인 루빅스(Rubix)에 의해 뒷받침된다. 이 기반 위에서 데이터 통합 및 분석 플랫폼인 파운드리(Foundry), 국방 및 정보 분석에 특화된 고담(Gotham), 그리고 AI 모델을 온톨로지와 연결하는 AIP(Artificial Intelligence Platform)가 운영된다.
팔란티어 아키텍처 구조 개념도

데이터 처리 워크플로우 - 비정형 데이터에서 지식으로 변환
팔란티어의 워크플로우는 이기종의 파편화된 데이터 소스를 연결하고, 이를 구조화된 지식으로 변환하여 온톨로지를 '활성화(Hydration)'하는 과정이다.

데이터 수집 및 파싱
PDF, 문서, 이미지와 같은 비정형 데이터는 먼저 '미디어 셋(media sets)'이라는 파일 모음으로 수집된다. 데이터를 파싱하는 과정은 블랙박스가 아니다. 개발자는 파이썬(Python)이나 자바(Java) 변환과 저수준 파일 시스템 API를 사용하여 직접 파이프라인을 구축한다. 이는 결정론적이고, 테스트 가능하며, 버전 관리가 가능한 파이프라인을 통해 신뢰성과 거버넌스를 확보하는 엔지니어링 중심의 접근 방식이다.

더 나아가 AIP는 AI 기반 파싱 기능을 제공한다. 이는 사전 훈련되거나 맞춤화된 AI 모델(예: NLP 모델)을 파이프라인 내에 통합하여 개체명 인식, 요약과 같은 정교한 작업을 수행하는 방식이다. 이 구조는 엔지니어가 견고한 데이터 파이프라인을 구축하고, AI 엔지니어가 그 안에 두뇌 역할을 하는 모델을 배포하는 효율적인 이중 계층 시스템을 만든다.

기반 처리 기술
이러한 데이터 변환 및 통합 로직은 독점 엔진에 종속되지 않는다. 모든 데이터는 아파치 파케이(Apache Parquet), 아브로(Avro)와 같은 표준 형식으로 저장되며, 대규모 배치 처리를 위한 아파치 스파크, 실시간 스트림 처리를 위한 아파치 플링크와 같은 오픈소스 런타임을 사용한다.

온톨로지 메타모델
온톨로지는 팔란티어의 핵심 차별화 요소로, 기업의 모든 데이터, 모델, 프로세스를 현실 세계의 대응물(공장, 고객, 제품 등)과 연결하는 의미론적, 동역학적 계층이다. 이는 기업의 '디지털 트윈(digital twin)' 역할을 한다.

온톨로지의 개념은 객체 지향 프로그래밍(OOP)과 매우 유사하다.
  • 객체(Object)는 클래스(Class)에 해당한다. 온톨로지의 '항공기' 객체 유형은 OOP의 Aircraft 클래스와 같다.
  • 속성(Property)은 속성(Attribute)에 해당한다. '항공기' 객체의 '꼬리 번호' 속성은 Aircraft 클래스의 tailNumber 속성과 같다.
  • 연결(Link)은 객체 간의 관계(Association)에 해당한다. '조종사'가 '항공기'에 탑승한다는 연결은 Pilot 객체와 Aircraft 객체 간의 관계를 정의한다.
다음은 이를 역공학해본 온톨로지 메타모델 구조이다. 
팔란티어 온톨로지 메타모델(UML)

본질적으로 온톨로지는 기업의 비즈니스 개념을 객체 지향 방식으로 모델링한 추상화 계층이다.
온톨로지 작업 UI 메뉴

플랫폼 아키텍처적 고려 - 디커플링(Decoupling)
온톨로지의 가장 중요한 기능은 소스 데이터 시스템과 운영 애플리케이션 사이에 안정적인 추상화 계층을 제공하여 애플리케이션 계층을 데이터 계층과 분리(decouple)하는 것이다.

일반적으로 애플리케이션은 ERP나 CRM 같은 소스 데이터베이스에 직접 연결된다. 만약 소스 시스템의 스키마가 변경되면 모든 종속 애플리케이션이 손상되어 막대한 기술 부채를 유발한다. 온톨로지는 중간 계층 역할을 한다. 애플리케이션은 원시 데이터 테이블이 아닌, 온톨로지의 안정적인 비즈니스 객체(예: '고객' 객체)를 기준으로 구축된다. 소스 시스템이 변경되더라도 '활성화' 파이프라인만 수정하면 되므로, 온톨로지 위에 구축된 수백 개의 운영 애플리케이션은 영향을 받지 않는다. 이는 사실상 온톨로지가 기업 전체 데이터에 대한 안정적인 API 역할을 수행하게 하여, 기업의 민첩성을 극적으로 높이고 유지보수 비용을 절감한다.
클라이언트 앱 프로젝트 생성 UI 메뉴 
 
온톨로지 메타모델 구현 방법
팔란티어의 온톨로지는 마법이 아닌, 소프트웨어 공학적으로 설계된 데이터 모델링과 아키텍처 원칙의 조합이다. 이는 오픈소스 기술 스택으로 충분히 구현 가능한 구조이다.

온톨로지의 요구사항은 특정 객체를 빠르게 조회하고, 객체 간의 복잡한 관계를 탐색하며, 대규모 데이터셋을 검색하는 것이다. 이를 만족시키기 위한 가장 가능성 높은 아키텍처는 단일 데이터베이스가 아닌, 여러 기술을 조합한 복합 아키텍처(Composite Architecture)이다.
  • 객체 저장소: 객체 데이터 자체는 카산드라(Cassandra)와 같은 수평적으로 확장 가능한 Key-Value 저장소에 저장될 수 있다. 각 객체는 고유 ID를 키(Key)로, 모든 속성을 담은 JSON 문서를 값(Value)으로 저장하는 방식이다.
  • 검색 및 그래프 인덱스: 빠른 검색, 집계, 그래프 탐색 기능을 위해서는 엘라스틱서치(Elasticsearch)나 루씬(Lucene) 기반의 검색 인덱스가 필수적이다. Key-Value 저장소에 저장된 객체 데이터는 검색 엔진으로 인덱싱되어 풍부한 쿼리 기능을 제공한다.
이 구조에서 온톨로지는 기술적으로 레이블이 있는 속성 그래프(Labeled Property Graph, LPG) 모델로 구현된다. 객체는 '노드(Node)'가 되고, 연결은 '간선(Edge)'이 되며, 이는 확장성이 뛰어난 Key-Value 저장소와 검색 인덱스의 조합 위에 효율적으로 구축될 수 있다.

온톨로지는 고객의 기존 MongoDB나 PostgreSQL을 대체하지 않는다. 대신 JDBC, ODBC와 같은 표준 커넥터를 통해 이들 시스템에 연결하고, 데이터를 가져와 온톨로지 모델로 '활성화'한다. 예를 들어, PostgreSQL의 여러 테이블을 조인하여 하나의 '제품' 객체를 생성하거나, MongoDB의 'customers' 컬렉션을 '고객' 객체로 매핑할 수 있다.
SQL 질의문 예시

온톨로지의 활용 - AI 에이전트와 애플리케이션
완전히 활성화된 온톨로지는 AI 에이전트와 인간 운영자가 상호작용하는 기반이 된다(인간-AI 팀 개념 구현). AI 에이전트는 온톨로지라는 잘 구조화된 지식 그래프를 탐색하며 복잡한 추론을 수행한다. 예를 들어, "배송 지연 위험이 있는 제품은 무엇인가?"라는 질문에, 에이전트는 '제품'에서 '공급업체', '위험 점수'로 그래프 관계를 탐색하며 다각적인 답변을 생성할 수 있다.
팔란티어의 인간-AI 팀 개념도

개발자는 파이썬 OSDK(Ontology SDK) 등을 사용하여 온톨로지와 상호작용하는 애플리케이션을 구축한다. client.ontology.objects.Shipment.where(status="Delayed").all()과 같은 코드는 SQL 쿼리보다 훨씬 직관적이며, 비즈니스 용어로 로직을 작성할 수 있게 해준다. 또한, 온톨로지에 정의된 '액션(Action)'을 호출하는 것은 단순한 데이터베이스 업데이트가 아니라, 플랫폼의 모든 거버넌스, 보안, 감사 추적이 적용되는 통제된 트랜잭션을 실행하는 것이다.
팔란티어 앱 개발 방법 예시

팔란티어 플랫폼 기반 앱 개발 예시
개발자가 Palantir Foundry의 온톨로지 SDK(OSDK)를 사용하여 실제 운영 애플리케이션을 어떻게 구축하는지 살펴보는 것은 플랫폼의 가치를 이해하는 데 중요하다. 이 섹션에서는 가상의 물류 애플리케이션 시나리오를 통해 Python OSDK의 실제 코딩 예시를 제시한다.

물류 회사는 매일 수천 건의 화물을 처리한다. '화물(Shipment)'과 '운송 차량(Vehicle)'이라는 두 가지 핵심 객체 유형이 온톨로지에 정의되어 있다고 가정하자. 물론, 이 온톨로지 객체 인스턴스들은 파서 파이프라인을 통해 데이터베이스에 구축된 상태이다. 팔란티어는 고객 데이터베이스에 온톨로지를 구축하기 위해 개발 컨설팅을 서비스한다. 

이 예제에서는 이 과정이 끝나고, 온톨로지 모델을 통해 접근할 수 있는 '화물' 객체에는 shipmentId, status (예: '운송 중', '지연', '배송 완료'), destination과 같은 속성이 있다. '운송 차량' 객체에는 vehicleId, currentLocation 속성이 있으며, 각 '화물'은 특정 '운송 차량'에 할당되어 온톨로지 상에서 연결(Link)되어 있다. 온톨로지를 여기서는 데이터베이스가 아닌 추상 레이어(미들웨어)라 가정해야 한다. 다음은 팔란티어 온톨로지 기반으로 정의된 사용자 모델이다.
사용자 온톨로지 모델 구조(UML)

우리의 목표는 '지연' 상태인 모든 화물을 식별하고, 운영자가 상태를 '조사 중'으로 변경할 수 있는 간단한 스크립트를 작성하는 것이다.

Foundry 플랫폼은 개발자가 온톨로지와 직접 상호작용할 수 있는 언어별 SDK를 제공한다.37 Python OSDK는 객체, 속성, 액션을 마치 일반적인 Python 클래스와 메서드처럼 다룰 수 있게 해준다.

import os
from <YOUR_PACKAGE_NAME> import FoundryClient
from <YOUR_PACKAGE_NAME>.core.api import UserTokenAuth

# 1. Foundry 클라이언트 초기화
try:
    auth = UserTokenAuth(
        hostname=os.environ,
        token=os.environ
    )
    client = FoundryClient(auth=auth, hostname=os.environ)
except KeyError:
    print("오류: FOUNDRY_HOSTNAME 및 FOUNDRY_TOKEN 환경 변수를 설정.")
    exit()

# 2. 온톨로지 객체 쿼리: 지연된 화물 검색
#    OSDK는 온톨로지의 각 객체 유형(예: Shipment)에 대한 접근자를 제공
#    'where' 절을 사용하여 특정 속성 값(status == "Delayed")을 기준으로 객체를 필터링
print("\n'지연' 상태인 화물을 검색...")
delayed_shipments = client.ontology.objects.Shipment.where(status="Delayed").all()

if not delayed_shipments:
    print("지연된 화물이 없음.")
else:
    print(f"총 {len(delayed_shipments)}개의 지연된 화물을 찾음")

    # 3. 객체 속성 접근 및 연결된 객체 탐색
    #    검색된 각 화물 객체에 대해 속성(shipmentId, destination 등)에 직접 접근
    #    온톨로지 연결을 통해 'assignedVehicle'과 같은 연결된 객체를 로드
    for shipment in delayed_shipments:
        print(f"\n- 화물 ID: {shipment.shipmentId}")
        print(f"  목적지: {shipment.destination}")
        print(f"  현재 상태: {shipment.status}")

        # 연결된 운송 차량 정보 로드
        try:
            vehicle = shipment.assignedVehicle.get()
            print(f"  할당된 차량 ID: {vehicle.vehicleId}")
            print(f"  차량 현재 위치: {vehicle.currentLocation}")
        except Exception as e:
            print(f"  할당된 차량 정보를 가져오는 데 실패: {e}")


    # 4. 온톨로지 액션(Action) 실행
    #    온톨로지의 동역학적 계층은 'update_shipment_status'와 같은 액션을 정의
    target_shipment = delayed_shipments
    print(f"\n화물 {target_shipment.shipmentId}의 상태를 '조사 중'으로 업데이트...")

    try:
        # 'update_shipment_status'는 온톨로지에 미리 정의된 액션의 API 이름이라고 가정
        target_shipment.update_shipment_status(new_status="Investigation")
        print("상태 업데이트 액션이 성공적으로 실행.")

        # 변경 사항 확인
        updated_shipment = client.ontology.objects.Shipment.get(target_shipment.shipmentId)
        print(f"화물 {updated_shipment.shipmentId}의 새로운 상태: {updated_shipment.status}")

    except Exception as e:
        print(f"액션 실행 중 오류가 발생: {e}")


위 코드는 Palantir 플랫폼의 핵심 철학을 보여준다. 개발자는 기본 데이터베이스의 스키마나 조인(join) 로직에 대해 알 필요가 없다. 대신, 비즈니스 용어(Shipment, Vehicle, status)로 정의된 잘 구조화된 온톨로지 API와 상호작용한다. 


client.ontology.objects.Shipment.where(...)와 같은 코드는 SQL 쿼리보다 훨씬 직관적이며, 애플리케이션 로직과 기본 데이터 저장소를 분리(decouple)시킨다. 액션(Action)을 호출하는 것은 단순한 UPDATE 문이 아니라, 플랫폼의 거버넌스와 보안 모델을 통과하는 감사 가능한 트랜잭션을 실행하는 것이다. 이러한 접근 방식은 개발 속도를 크게 향상시키고 유지보수 비용을 절감하며, 복잡한 기업 환경에서도 일관성 있고 안전한 데이터 조작을 보장한다.


결론
팔란티어 플랫폼 아키텍처를 해부한 결과, 강력함은 독점적인 데이터베이스 기술이 아닌 추상화에 있다. 팔란티어는 쿠버네티스, 스파크와 같은 검증된 오픈소스 기술을 기반으로, 고객이 이미 보유한 다양한 데이터베이스 위에 '온톨로지'라는 일관되고 의미 있는 비즈니스 언어 계층을 구축한다.
팔란티어의 개방형 데이터셋 연결 구조 예시

이 아키텍처는 기업이 기존 데이터 투자의 가치를 극대화하고, 데이터와 운영 애플리케이션을 분리하여 미래 변화에 민첩하게 대응할 수 있도록 만든다. 

레퍼런스
부록: 카산드라(Cassandra)의 아키텍처적 장점 및 온톨로지 모델 구현
1. 개요
이 글은 카산드라의 쿼리 언어(CQL)와 전통적인 SQL의 관계를 설명한다. 이어서, 개발자들이 특정 시나리오에서 관계형 데이터베이스 대신 카산드라를 선택하는 핵심적인 아키텍처적 장점인 수평적 확장성, 고가용성, 쓰기 성능을 설명한다.
참고로, 엘라스틱서치(Elasticsearch)는 루씬(Lucene)이라는 검색 라이브러리를 기반으로 만든 오픈소스 검색 및 분석 엔진이다. 엘라스틱서치는 저장된 데이터를 찾고 분석하는 데 특화되어 있다.

2. 카산드라와 SQL의 관계
카산드라가 "그냥 SQL이 지원되는 데이터베이스"라는 인식은 반은 맞고 반은 틀린 이야기이다.

카산드라는 CQL (Cassandra Query Language)을 사용한다. SELECT, INSERT, UPDATE, CREATE TABLE 등 그 문법이 SQL과 매우 유사하여, 기존 관계형 데이터베이스(RDBMS)에 익숙한 개발자가 쉽게 배울 수 있다는 장점이 있다. 이는 의도적으로 설계된 부분이다.

겉모습은 비슷하지만, 내부 동작 원리와 데이터 모델링 철학은 완전히 다르다. 카산드라는 관계형 데이터베이스가 아니다. 가장 큰 차이점은 다음과 같다.
  • 카산드라는 여러 테이블을 연결하는 JOIN 연산을 지원하지 않는다. 이는 분산 환경에서 JOIN이 유발하는 막대한 성능 저하를 원천적으로 차단하기 위함이다.
  • 외래 키(Foreign Key)와 같은 관계 무결성을 데이터베이스 차원에서 보장하지 않는다.
  • RDBMS가 데이터의 관계를 정규화하여 모델링하는 반면, 카산드라는 애플리케이션이 사용할 쿼리(조회 방식)를 먼저 설계하고 그에 맞춰 테이블을 비정규화(denormalization)하여 구성한다.
결론적으로, CQL은 SQL의 편리한 문법을 차용한, 분산 Key-Value 데이터 저장소에 최적화된 전혀 다른 언어이다.

3. 개발자가 카산드라를 선택하는 이유
개발자들은 RDBMS가 해결하기 어려운 특정 문제들을 풀기 위해 카산드라를 선택한다.

가. 분산 아키텍처와 수평적 확장성 (Horizontal Scalability)
이것이 카산드라를 사용하는 가장 큰 이유이다. 카산드라는 여러 서버(노드)를 묶어 하나의 거대한 데이터베이스처럼 사용하는 'Shared-Nothing' 분산 아키텍처를 기반으로 한다.
  • 수평적 확장: 데이터가 늘어나거나 트래픽이 증가할 때, 고가의 단일 서버 성능을 높이는 '수직적 확장'이 아니라, 저렴한 일반 서버를 클러스터에 계속 추가하는 '수평적 확장'이 가능하다. 이론적으로 서버를 추가하는 만큼 성능과 용량이 선형적으로 증가한다.
  • 대규모 데이터 처리: 수십억, 수백억 개의 행을 가진 페타바이트(PB)급 데이터를 처리하는 데 최적화되어 있다.
나. 고가용성 및 장애 허용 (High Availability & Fault Tolerance)
카산드라 클러스터에는 마스터(Master) 노드처럼 특별한 역할을 하는 노드가 없어 단일 장애점(SPOF, Single Point of Failure)이 존재하지 않는다.
  • 데이터 복제: 데이터는 클러스터 내 여러 노드에 자동으로 복제되어 저장된다.
  • 무중단 서비스: 특정 노드에 장애가 발생하더라도, 복제된 데이터를 가진 다른 노드가 즉시 요청을 처리하여 서비스 중단 없이 운영이 가능하다. 이는 24시간 365일 무중단이 필수적인 서비스에 결정적인 장점이다.
다. 압도적인 쓰기 성능 (Optimized for Write Performance)
카산드라는 LSM-Tree (Log-Structured Merge-Tree) 라는 자료 구조를 사용하여 데이터를 저장한다. 이는 디스크에 데이터를 순차적으로 추가(Append-Only)하는 방식으로, 기존 RDBMS의 B-Tree 방식보다 쓰기 작업에 훨씬 유리하다.
  • 활용 사례: 사물 인터넷(IoT) 센서 데이터, 서비스 로그, 메시징 데이터처럼 끊임없이 대량으로 쏟아지는 데이터를 지연 없이 저장해야 하는 시스템에 최적이다.
4. 실제 구현 사례: 온톨로지 모델의 객체 저장소
앞서 구현한 온톨로지 모델은 카산드라의 장점을 활용한 전형적인 데이터 아키텍처로 적용 가능하다.

가. 아키텍처 설계 복기
이 시스템은 두 가지 데이터베이스를 조합하여 각자의 장점을 극대화한다.
  • 객체 저장소 (카산드라): 모든 객체의 원본 데이터를 저장하는 'Source of Truth' 역할을 한다.
  • 검색 인덱스 (엘라스틱서치): 카산드라에 저장된 데이터를 복사하여, 복잡한 검색 및 집계 기능을 제공한다.
나. 이 아키텍처에서 카산드라의 역할
온톨로지 모델의 객체 저장소로 카산드라를 선택한 이유는 다음과 같다.
  • Key-Value 최적화: 온톨로지 객체는 고유 ID를 Key로, 속성 데이터를 Value로 갖는다. 이는 object_id를 파티션 키로 사용하는 카산드라의 데이터 모델과 완벽하게 부합하며, ID 기반 조회 시 최고의 성능을 보장한다.
  • 확장성: 수억, 수십억 개의 온톨로지 객체가 생성되더라도, 단순히 카산드라 클러스터에 노드를 추가하는 것만으로 시스템을 수평적으로 확장할 수 있다.
  • 가용성: 온톨로지 데이터는 기업의 핵심 자산이다. 카산드라의 무중단 특성은 일부 노드에 장애가 발생해도 객체 데이터의 유실 없이 안정적으로 서비스를 유지할 수 있도록 보장한다.
다. 구현 코드
다음은 카산드라와 엘라스틱서치를 사용하여 온톨로지 모델을 구현한 파이썬 코드이다. 이 코드는 위에서 설명한 아키텍처 원리를 추측해 구현해 본 것이다.

import uuid
import json
import time
from cassandra.cluster import Cluster
from cassandra.query import SimpleStatement
from elasticsearch import Elasticsearch

# 1. 데이터베이스 연결 설정
def setup_cassandra(contact_points=['127.0.0.1'], port=9042):
    cluster = Cluster(contact_points, port=port)
    session = cluster.connect()
   
    # 키스페이스 생성
    session.execute("""
    CREATE KEYSPACE IF NOT EXISTS ontology
    WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '1' }
    """)
    session.set_keyspace('ontology')

    # 객체 저장을 위한 테이블 생성 (JSON 문자열로 속성 저장)
    session.execute("""
    CREATE TABLE IF NOT EXISTS objects (
        object_id TEXT PRIMARY KEY,
        properties TEXT
    )
    """)
    print("카산드라 설정 완료: 'ontology' 키스페이스 및 'objects' 테이블 준비됨.")
    return cluster, session

def setup_elasticsearch(hosts=[{'host': 'localhost', 'port': 9200, 'scheme': 'http'}]):
    es_client = Elasticsearch(hosts=hosts)
    if not es_client.ping():
        raise ValueError("엘라스틱서치 연결에 실패.")
    print("엘라스틱서치 연결 성공.")
    return es_client

# 2. 온톨로지 클래스 구현
class Ontology:
    def __init__(self, cassandra_session, es_client, es_index_name='ontology_index'):
        self.session = cassandra_session
        self.es = es_client
        self.es_index = es_index_name
       
        if not self.es.indices.exists(index=self.es_index):
            self.es.indices.create(index=self.es_index)
            print(f"엘라스틱서치 인덱스 '{self.es_index}' 생성됨.")

    def add_object(self, object_type, properties):
        object_id = f"{object_type}-{uuid.uuid4().hex[:8]}"
        full_properties = {"object_type": object_type, properties}
       
        query = SimpleStatement("INSERT INTO objects (object_id, properties) VALUES (%s, %s)")
        self.session.execute(query, (object_id, json.dumps(full_properties)))
       
        self.es.index(index=self.es_index, id=object_id, document=full_properties)
       
        print(f"객체 추가됨: {object_id} (카산드라 저장, ES 인덱싱 완료)")
        return object_id

    def get_object(self, object_id):
        query = "SELECT properties FROM objects WHERE object_id = %s"
        row = self.session.execute(query, (object_id,)).one()
        if row:
            return json.loads(row.properties)
        return None

    def search(self, property_key, property_value):
        query = { "match": { f"{property_key}.keyword" if isinstance(property_value, str) else property_key: property_value } }
        response = self.es.search(index=self.es_index, query=query)
        hits = response['hits']['hits']
        print(f"\nES 검색 실행 ('{property_key}:{property_value}')... {len(hits)}개 결과 찾음.")
        return [hit['_source'] for hit in hits]

    def add_link(self, source_object_id, link_type, target_object_id):
        source_object = self.get_object(source_object_id)
        if not source_object: return

        if "_links" not in source_object: source_object["_links"] = {}
        if link_type not in source_object["_links"]: source_object["_links"][link_type] = []
        source_object["_links"][link_type].append(target_object_id)
       
        query = SimpleStatement("INSERT INTO objects (object_id, properties) VALUES (%s, %s)")
        self.session.execute(query, (source_object_id, json.dumps(source_object)))
        self.es.index(index=self.es_index, id=source_object_id, document=source_object)

        print(f"링크 추가 및 업데이트됨: {source_object_id} --({link_type})--> {target_object_id}")

5. 결론
카산드라는 SQL과 유사한 CQL을 제공하여 개발자 친화적이지만, 그 본질은 대규모 분산 환경을 위해 태어난 NoSQL 데이터베이스이다. JOIN이나 참조 무결성을 포기하는 대신 수평적 확장성, 고가용성, 뛰어난 쓰기 성능이라는 명확한 장점을 얻었다.

참고로, 오픈소스인 칸산드라 개발자는 아비나쉬 라크쉬만 (Avinash Lakshman), 프라샨트 말릭 (Prashant Malik)이다. 페이스북의 '받은 편지함 검색(Inbox Search)' 기능의 대규모 데이터 처리 요구사항을 충족시키기 위해 내부적으로 개발되었다. 아마존(Amazon)의 DynamoDB와 구글(Google)의 Bigtable 아키텍처에서 영감을 받아 설계되었다. 2008년 오픈소스로 공개된 후, 아파치 재단(ASF)의 최상위 프로젝트로 승격되어 전 세계적으로 널리 사용되는 분산 NoSQL 데이터베이스로 성장했다.


팔란티어는 단일 개발자가 아닌, 각기 다른 전문성을 가진 공동 창업자들의 협업을 통해 탄생했다.

피터 틸 (Peter Thiel)은 페이팔(PayPal)의 사기 방지 시스템 경험을 바탕으로 초기 비전을 제시한 핵심 창업자이다. 스티븐 코언 (Stephen Cohen)은 팔란티어 플랫폼의 초기 프로토타입을 직접 코딩한 핵심 엔지니어이다. 스탠퍼드 대학교 컴퓨터 과학 석사 출신으로, 그의 객체지향 프로그래밍(OOP) 배경이 온톨로지(Ontology) 아키텍처의 근간이 되었다. 네이선 게팅스 (Nathan Gettings)는 초기 엔지니어링 및 알고리즘 개발에 기여한 컴퓨터 과학자이다. 


플랫폼의 핵심인 온톨로지 개념은 창업자 그룹, 특히 스티븐 코언의 깊은 객체지향 프로그래밍(OOP) 이해도에서 비롯되었다. 이는 클래스(Class), 객체(Object), 관계(Link)로 현실을 모델링하는 OOP의 핵심 사상과 정확히 일치한다.


온톨로지 구현 사례에서 보았듯이, 카산드라는 대규모 객체의 원본 데이터를 안정적으로 저장하고, 엘라스틱서치와 같은 검색 엔진과 결합하여 복잡한 조회 요구사항을 충족시키는 'Polyglot Persistence' 아키텍처의 핵심 구성 요소로 사용될 수 있다. 

댓글 없음:

댓글 쓰기