주요 컨텐츠로 이동
의료 및 생명 공학

Funke 소개: Databricks 기반 네이티브 HL7v2 파싱

FHIR 변환이나 서드파티 평탄화 없이 원시 HL7v2 메시지를 쿼리 가능한 Spark 네이티브 데이터로 변환해 주는 오픈소스 액셀러레이터입니다.

작성자: Sean Fischer, Chris Mantz , Andy Launchbury

  • Funke는 원본 메시지의 전체 세그먼트, 필드, 컴포넌트 및 하위 컴포넌트 계층 구조를 보존하면서 HL7v2 전자의무기록 메시지를 Databricks Lakehouse의 네이티브 Spark 유형으로 직접 파싱합니다.
  • 이는 2021년 Scala 라이브러리인 Smolder의 후속 버전으로, Unity Catalog, Declarative Automation Bundles 및 Spark Declarative Pipelines를 중심으로 Python 및 PySpark로 재구축되었습니다.
  • Funke는 오픈소스이며 실행 가능한 데모가 함께 제공되어 몇 분 만에 엔드투엔드 HL7 수집 파이프라인을 구축하고 파싱된 임상 데이터를 탐색할 수 있습니다.

레이크하우스에서의 HL7v2 문제

HL7v2는 헬스케어 분야를 뒷받침하는 메시징 표준입니다. 임상 시스템이 환자 입원, 검사 처방, 결과 반환 등의 정보를 서로 주고받는 방식입니다. 도입된 지 수십 년이 지난 지금도 업계에서 가장 널리 배포된 통합 표준으로 남아 있으며, 대부분의 의료 기관이 일상적인 운영 데이터 흐름을 위해 이에 의존하고 있습니다.

하지만 다루기 까다롭기도 합니다. HL7v2 메시지는 중첩된 구분자 인코딩 구조로, 필드로 구성된 세그먼트, 구성 요소 및 반복으로 구성된 필드, 하위 구성 요소로 구성된 구성 요소가 모두 메시지 헤더에 선언된 몇 개의 특수 문자로 구분됩니다. 명세의 유연성으로 인해 실제 메시지는 전송하는 시스템마다 다릅니다.

팀에서 해당 데이터를 현대적인 형식으로 변환하려 할 때 보통 두 가지 우회 방법 중 하나를 선택합니다. 먼저 모든 데이터를 FHIR로 변환하는 것인데, 이 경우 번역 레이어가 추가되고 깔끔한 FHIR 대응 항목이 없는 세부 정보가 누락될 수 있습니다. 아니면 메시지를 서드파티 엔진에 전달하여 계층 구조를 와이드 테이블(wide tables)로 평탄화하는데, 이는 다른 벤더에 비용을 지불하고, 플랫폼 외부로 데이터를 이동하며, 하위의 세부 구조에 직접 접근할 수 없게 됨을 의미합니다. 두 방법 모두 비용과 지연 시간을 늘리고, 자체 임상 데이터와의 거리를 멀어지게 합니다.

Smolder에서 Funke로

2021년에 당사는 파서를 직접 코딩하지 않고도 헬스케어 팀이 실시간 EHR 피드에서 분석을 실행할 수 있도록 HL7v2 메시지를 DataFrame으로 로드하는 Spark 라이브러리인 Smolder를 오픈 소스로 공개했습니다. Smolder는 메시지 파싱이 도입의 주요 장애물이었던 시기에 레이크하우스에서 HL7 데이터를 활용할 수 있게 해주었습니다.

그 이후 플랫폼은 크게 발전했습니다. Unity Catalog가 데이터, 볼륨 및 모델을 거버넌스합니다. Declarative Automation Bundles는 프로젝트를 코드 형태로 패키징하고 배포합니다. Spark Declarative Pipelines는 선언적으로 스트리밍 수집을 처리합니다. 하지만 Smolder는 이 모든 기술보다 먼저 출시되었으며 최신 Databricks 플랫폼에 깔끔하게 맞물리도록 설계되지 않았습니다.

Funke는 현재의 플랫폼에 맞게 재구축된 후속작입니다. 이름은 그 계보를 살짝 반영한 것입니다. 독일어로 Funke는 불꽃(spark)을 의미합니다. Smolder가 Scala 데이터 소스였던 반면, Funke는 Python 및 PySpark 라이브러리와 바로 배포 가능한 파이프라인의 결합체입니다. 메시지를 네이티브 Spark 유형으로 파싱하고, DAB로 배포하며, Declarative Pipeline을 통해 수집하고, 모든 항목을 Unity Catalog에 저장합니다. 사용자는 몇 분 만에 아무것도 없는 상태에서 확장 가능한 스트리밍 HL7 파이프라인을 구축할 수 있습니다.

Smolder가 시작한 아이디어, 즉 HL7을 레이크하우스의 일급(first-class) 데이터로 다룬다는 개념은 동일합니다. 구체적인 구현 방식이 새로워졌을 뿐입니다.

Funke가 특별한 이유

Funke는 HL7v2 메시지를 네이티브 Spark 유형으로 직접 파싱하고 전체 계층 구조를 온전히 유지합니다. 파싱 과정은 무손실로 설계되었으며, 파이프라인 끝까지 원본 구조를 가능한 한 많이 유지하는 것을 목표로 합니다.

파싱된 메시지는 세그먼트 이름부터 해당 세그먼트의 반복까지의 맵으로 모델링됩니다. 각 필드 자체도 맵 형태로, 필드 번호, 반복, 구성 요소, 하위 구성 요소 순으로 참조할 수 있습니다. Spark 용어로 표현하면 다음과 같습니다.

파싱된 메시지는 일반적인 Spark 컬럼이므로 표준 DataFrame 또는 SQL 표현식으로 모든 요소에 접근할 수 있으며, 파서가 HL7 인코딩 규칙을 대신 처리합니다. 즉 MSH 헤더에 선언된 필드, 구성 요소, 반복, 하위 구성 요소 구분자와 표준 이스케이프 시퀀스까지 자동으로 다룹니다. Funke는 모든 HL7 메시지 유형과 버전을 지원하므로 동일한 파이프라인으로 의료 시스템에서 수신되는 다양한 버전의 메시지를 처리할 수 있습니다.

그 결과, 원본 임상 데이터가 Unity Catalog의 거버넌스를 받으며 완벽한 신뢰성을 유지한 채 레이크하우스에 적재되어 즉시 쿼리할 수 있는 상태가 됩니다. 변환기나 벤더가 정의한 형태를 그대로 받아들이는 대신 특정 유즈 케이스에 필요한 필드를 직접 결정할 수 있습니다.

작동 방식: 수집 파이프라인

Funke는 메달리온 아키텍처 패턴을 따르는 Declarative Pipeline으로 배포됩니다. 두 개의 테이블을 정의하며, 사용자는 그 위에 자체 유즈 케이스에 맞는 골드(gold) 테이블을 구축합니다.

그림 1: Databricks 레이크하우스에서의 Funke 데이터 흐름

image1.png

랜딩에서 브론즈 단계로. 새로운 HL7 파일이 Unity Catalog 볼륨에 도착합니다. Auto Loader가 이를 가져와 콘텐츠를 디코딩하고, 파이프라인 전체에서 메시지를 추적하기 위한 MD5 해시, 삽입 타임스탬프, 메시지 ID를 포함한 수집 메타데이터와 함께 raw_messages 테이블에 작성합니다.

브론즈에서 실버 단계로. parsed_messages 테이블은 원시 스트림을 읽고 Funke 파서를 적용하여 위에서 언급한 네이티브 유형의 단일 hl7 컬럼을 추가합니다. 이 단계에서 비구조화된 메시지 텍스트가 구조화되어 쿼리 가능한 데이터로 변환됩니다.

원시 메시지에서 골드 테이블로

hl7 컬럼은 네이티브 Spark 데이터이므로 세그먼트, 필드, 반복, 구성 요소, 하위 구성 요소별로 모든 요소를 직접 참조할 수 있습니다.

동일한 추출 방식이 Spark SQL에서도 작동하므로 Python을 사용하지 않는 분석가도 골드 테이블과 뷰를 직접 구축할 수 있습니다.

위치 인덱스 체인은 정밀하지만 개발 후 몇 달이 지나면 파악하기 어려울 수 있습니다. 이러한 이유로 Funke는 개발자가 콘텐츠를 깔끔하게 추출할 수 있도록 돕는 액세서(accessor) 헬퍼를 제공합니다. get_value는 세그먼트, 세그먼트 반복, 필드, 필드 반복, 구성 요소, 하위 구성 요소를 받아 값을 컬럼으로 반환합니다.

또한 get_segment, get_field, get_component, get_subcomponent 및 MSH 헤더에서 버전을 직접 읽어오는 parse_hl7_version 헬퍼를 포함한 상위 수준의 헬퍼도 제공됩니다. 쿼리에 맞는 추상화 수준을 직접 선택하면 됩니다.

엔드투엔드 실행 확인하기

Funke에는 데모가 함께 제공되어 실제 EHR 피드를 연결하지 않고도 전체 흐름을 살펴볼 수 있습니다. 여러 시설에서의 입원, 전원, 퇴원을 시뮬레이션하는 합성 ADT 이벤트 생성기와, 데이터 스트림의 시작/중지를 제어하고 원시 텍스트에서 파싱된 구조를 거쳐 골드 단계까지 메시지를 추적하는 Databricks Apps 기반 종합 관리 애플리케이션이 포함되어 있습니다.

image2.gif

데모의 골드 레이어는 그 자체로 작동하는 훌륭한 예시입니다. 파싱된 ADT 스트림을 adt_events 이력 테이블로 변환한 다음, 방문 번호를 키로 사용하는 변경 데이터 캡처(CDC)를 통해 실시간 current_census 테이블을 유지함으로써 퇴원 이벤트 발생 시 재원 환자 명단에서 환자를 제거하고 병상을 비웁니다. bed_utilization 테이블은 이러한 실시간 재원 환자 명단과 시설 수용 능력을 결합하여 병동별 사용 중인 병상과 이용 가능한 병상을 대시보드에 시각화합니다.이는 원시 HL7 메시지에서 병원에서 실제 모니터링하는 운영 지표로 전환되는 과정을 보여주는 구체적인 사례입니다.

시작하기

Funke는 Asset Bundle로 배포되는 Databricks Industry Solutions 액셀러레이터입니다.

  1. 리포지토리를 Databricks 워크스페이스로 클론합니다.
  2. DAB 에디터에서 디렉터리를 열고 Deploy를 클릭합니다. 배포 시 funke 라이브러리가 빌드되고 파이프라인, Unity Catalog 스키마, 랜딩 볼륨이 자동으로 프로비저닝됩니다.
  3. 생성된 landing 볼륨에 HL7 메시지를 업로드합니다.
  4. HL7 수집 파이프라인에서 Run을 클릭합니다.

명령줄 인터페이스를 선호하는 경우 Databricks CLI를 사용해 동일하게 배포를 실행할 수 있습니다.

Funke의 역할 및 한계

Funke는 파서이자 수집 액셀러레이터입니다. HL7v2 메시지를 거버넌스가 적용되고 쿼리 가능한 네이티브 레이크하우스 데이터로 제공하며, 사용 사례에 필요한 골드 테이블로 변환하는 깔끔한 패턴을 제공합니다. 인터페이스 엔진이 아니며, 메시지를 정확하게 해석하는 데 필요한 임상 및 HL7 전문 지식을 대체하지 않습니다. 세그먼트 및 필드를 비즈니스 개념으로 매핑하는 작업은 자체적인 도메인 지식을 바탕으로 결정해야 합니다. Funke의 역할은 이러한 결정을 내릴 때 필요한 데이터가 완벽하고 액세스하기 쉬운 상태로 준비되어 있도록 보장하는 것입니다.

시도해 보기

Funke는 Databricks 라이선스 하에 제공되는 오픈 소스입니다. 코드를 탐색하고 데모를 실행한 후 의견이나 아이디어가 있다면 이슈를 작성해 주세요.

https://github.com/databricks-industry-solutions/funke-hl7v2

데모에 사용된 테스트 메시지는 HL7 v2-to-FHIR 프로젝트에서 가져온 것입니다.

(이 글은 AI의 도움을 받아 번역되었습니다. 원문이 궁금하시다면 여기를 클릭해 주세요)

최신 게시물을 이메일로 받아보세요

블로그를 구독하고 최신 게시물을 이메일로 받아보세요.