Rust로 RML 엔진 만들기 ep2
목차
English version: Building an RML Engine in Rust, Ep. 2
요약
- RML-Core 공식 테스트 76/76 통과 (JSON 소스, 매핑 파서, 엔진, N-Quads 출력)
- 스트리밍 실행과 128비트 해시값으로 중복을 지워 100만 행 메모리 3,747MB → 275MB
- Python 휠과 WebAssembly 패키지
- SQL 소스: PostgreSQL, MySQL, SQL Server
- RML-IO: 논리 타깃, 압축(gzip·zip·tar.gz·tar.xz), XML(XPath)
- KROWN 실행 프레임워크로 Morph-KGC와 비교 측정
- 공식 테스트 365개 중 89개 → 214개 통과
작업 내역
공식 테스트는 KG-Construct가 공개한 테스트 케이스를 고치지 않고 그대로 돌린다.
결과는 공식 구현 보고서와 같은 형식으로 남기고, 전에 통과하던 테스트가 하나라도 실패하면 CI가 커밋을 막는다.
특이사항 - 1
첫 측정에서 Morph-KGC보다 메모리를 3배 넘게 썼다
CSV 100만 행(출력 600만 개)을 Morph-KGC와 나란히 돌렸더니, 시간은 비슷했지만 메모리를 3배 넘게 썼다.
소스 전체를 메모리에 올리고, 중복 문장을 지우려고 출력 600만 개를 모두 들고 있었기 때문이다.
해시값은 문장 하나를 일정한 길이(여기서는 128비트, 16바이트)의 숫자로 줄인 값이다. 문장 대신 이 값만 저장해 두고, 같은 값이 다시 나오면 이미 쓴 문장으로 보고 건너뛴다.
| 100만 행 | 시간 | 최대 메모리 |
|---|---|---|
| RMLrs AS-IS | 10.98초 | 3,747MB |
| Morph-KGC 2.10.0 | 9.53초 | 1,165MB |
| RMLrs TO-BE (스트리밍 + 출력 서식 최적화) | 5.70초 | 275MB |
맥북(Apple M4, 16GB)에서 직접 돌린 3회 중앙값이다.
특이사항 - 2
빠른 해시로 바꿨다가 출력 10만 개를 잃을 뻔했다
프로파일러를 보니 해시값 계산(SipHash)이 눈에 띄어서, 직접 짠 더 빠른 해시로 바꿨다.
5.0초로 빨라졌는데 출력 파일의 해시값이 이전과 달랐다.
Morph-KGC 출력과 맞대 보니 한 자리만 다른 IRI들이 같은 해시값을 받아, 약 99,000개가 중복으로 잘못 버려져 있었다.
검증된 SipHash로 되돌리고, 한 자리만 다른 IRI 30만 개를 넣는 테스트를 만들었다.
그 테스트가 문제의 해시로는 실제로 실패하는 것(30만 개 중 28만 개만 남음)까지 확인했다.
시간과 메모리만 봤다면 그대로 커밋했을 것이다.
KROWN 실행 프레임워크로 재기
KROWN의 실행 프레임워크(exectool)에 RMLrs를 붙여 Morph-KGC와 같은 조건으로 쟀다.
이 프레임워크는 엔진을 Docker 안에서 돌리며 시간·CPU·RAM을 기록한다.
테스트 기기의 메모리가 8GB로 작아서, Morph-KGC는 프로세스 수를 1개와 4개로 줄여서 쟀다.
| 행 수 | 엔진·설정 | 시간 | CPU 시간 | RAM 증가 |
|---|---|---|---|---|
| 10만 | RMLrs | 2.44초 | 2.3초 | 3~20MB |
| 10만 | Morph-KGC 프로세스 1 | 7.23초 | 7.3초 | 184~328MB |
| 10만 | Morph-KGC 프로세스 4 | 5.41초 | 9.8초 | 474~586MB |
| 100만 | RMLrs | 19.88초 | 17.4초 | 358MB |
| 100만 | Morph-KGC 프로세스 1 | 59.74초 | 55.6초 | 1,412MB |
| 100만 | Morph-KGC 프로세스 4 | 40.29초 | 109.3초 | 2,956MB |
100만 행에서 RMLrs는 Morph-KGC보다 2~3배 빨랐고, RAM 증가분은 4분의 1에서 8분의 1 수준이었다.
모든 실행에서 두 엔진의 출력은 정렬 후 같았다.
측정은 맥의 Docker VM(10 CPU, 8GB)에서 3회 중앙값으로 했다.
시간에는 컨테이너 시작이 들어 있고, RAM은 VM 전체 사용량의 증가분이다.
사양을 높인 환경에서 다시 잴 예정이다.
정리
공식 테스트 365개 중 214개를 통과했다.
스트리밍과 해시값 중복 제거로 100만 행 메모리를 3.7GB에서 275MB로 줄였고, 해시나 키를 바꾼 뒤에는 출력이 같은지와 벤치를 다시 본다.
다음 작업
- KROWN의 나머지 시나리오(조인, DB)와 다른 엔진(CARML, SDM-RDFizer) 비교
- 확장 모듈: FNML, CC, LV, star
- 메모리: 출력이 아주 많을 때의 해시값 집합, 문서 크기에 비례하는 XML
참고
- KG-Construct RML 테스트 케이스 https://github.com/kg-construct
- RML 구현 보고서 https://w3id.org/kg-construct/rml-implementation-report
- RML-IO 명세 https://w3id.org/rml/io/spec
- KROWN https://github.com/kg-construct/KROWN
- Morph-KGC https://github.com/morph-kgc/morph-kgc