Knowledge Graph

우분투 환경에서 Virtuoso에 named graph로 대용량 데이터 업로드하기

2023. 12. 05. by 박하람

우분투 서버에 Virtuoso 7을 설치하고, 대용량 데이터를 업로드 해야할 일이 생겼다. 우분투에서 Virtuoso 7을 설치하는 것은 솜솜 블로그의 [Virtuoso] Virtuoso 7 버전 설치하기를 참고하면 된다. 이 포스팅은 무사히 버투소를 설치한 다음, 대용량의 데이터를 named graph 형태로 버투소에 업로드하는 방법을 설명한다.

준비 (1): 설정 변경하기

대용량 데이터를 업로드하려면, 여러 우여곡절을 통해 conf 파일을 변경해야 한다는 것을 알았다..! virtuoso.ini 파일은 /var/lib/virtuoso-opensource-7/db/virtuoso.ini에 있다. virtuoso.ini 파일에서 아래의 코드를 수정하면 된다.

  • DirsAllowed: 데이터가 존재하는 디렉토리의 경로를 허용해줘야 데이터 경로가 인식된다. 추가로 데이터가 있는 경로를 작성하면 된다.
  • NumberOfBuffersNumberOfBuffers: 머신의 RAM 성능에 따라 지정해주면 된다. 버투소가 RAM 용량에 따라 지정한 버퍼 사이즈는 여기에서 확인할 수 있다.
  • MaxCheckpointRemap: 데이터를 마구 업로드하다가 checkpoint로 데이터 저장이 잘 되지 않아서 마구 넣었던 데이터가 날라간 적이 있다. 최대 checkpoint로 얼마 정도의 페이지를 넣을지 지정한다.
  • TransactionAfterImageLimit: 벌크 데이터를 업로드 할 때 transaction 상에서 롤백 에러가 생길 때가 있다. 이렇게 리밋 사이즈를 늘려주면 롤백 에러가 작동하지 않는다. 관련 에러에 대한 버투소의 공식 문서는 다음과 같은 설명을 제공한다.
DirsAllowed = ., /usr/share/virtuoso-opensource-7/vad, /usr/share/proj, {원하는 경로 추가}
NumberOfBuffers          = 5450000
NumberOfBuffers          = 4000000
MaxCheckpointRemap              = 1360000
TransactionAfterImageLimit = 2147483000

virtuoso.ini 파일이 변경되면, 버투소를 재실행해야 한다. 다음의 경로로 접속해서 버투소를 다시 실행한다.

cd /var/lib/virtuoso-opensource-7/db
virtuoso-t -f &

버투소 서버가 정상 작동한다면, localhost:8890/conductor/에서 conductor 화면이 보인다. 간혹 버투소 서버의 ini 파일를 변경했는데, 브라우저 상에서 conductor가 보이지 않을 때가 있다. 그럴 떄 버투소 포트로 방화벽이 잘 열려있는지 확인하자.

ufw allow 8890

준비 (2): global.graph 파일 생성하기

아주 귀찮게도 버투소에 named graph로 데이터를 넣으려면, 데이터가 있는 폴더에 global.graph 파일을 생성해야 한다. 버투소는 여러 방법을 안내하고 있지만, global.graph 파일을 생성하는 것이 가장 쉽다1. 버투소의 설명에 따르면, global.graph 파일은 Contains Graph IRI name into which RDF data from any files that do not have a specific graph name file will be loaded 일 때 사용한다. 즉, global.graph 파일은 어떤 파일이든 관계 없이 global.graph 파일이 있는 경로에 동일한 그래프 IRI로 named graph를 생성하고 싶을 때 사용한다.

http://data.test.com/graph/cow/

vim으로 global.graph 파일을 만들고 위와 같이 named graph로 생성할 IRI를 넣어주면 된다. 단, 폴더 경로를 구성할 때 동일한 폴더에 동일한 named graph로 넣고 싶은 파일만 있어야 동일한 named graph로 생성된다.

대용량 데이터 업로드하기

버투소는 sql 구문으로 데이터를 업로드할 수 있는 편리한 기능을 제공한다. isql은 버투소가 제공하는 sql 기반의 쿼리 환경인데, isql을 통해 버투소의 설정을 변경할 수도 있다. isql은 경로에 상관 없이 다음의 코드를 작성하면 된다.

isql 1111 dba {비밀번호}

isql은 포트 1111에서 열리고, 접속할 때 conductor의 계정을 입력해야 한다. 비밀번호를 바꾸지 않았으면, 아이디와 비밀번호는 모두 dba이다. 본인은 비밀번호를 바꾸었기 때문에, 바뀐 비밀번호를 입력한다.

특정 경로에 있는 모든 파일을 업로드하기

데이터가 home/ubuntu/data/cow 경로에 있고, ttl 파일로 저장되었다면 다음의 코드를 입력하면 된다. 단, global.graph 파일에 http://data.test.com/graph/cow/와 동일한 그래프 IRI가 작성되어 있어야 한다. ld_dir 구문은 버투소에 업로드할 데이터를 DB.DBA.load_list에 올리는 작업이다. ld_dir에 실행 후 DB.DBA.load_list에 해당 경로에 있는 ttl 파일이 모두 올라갔는지 확인한다. rdf_loader_run()은 버투소에 RDF 데이터를 밀어넣는 함수다. ll_state가 0이라면 rdf_loader_run()으로 데이터가 업로드되고, ll_state가 2라면 데이터가 버투소로 업로드된 항목이다. 마지막으로 checkpoint()를 해줘야 RDF 데이터 업로드가 무사히 된다.

-- 데이터 경로, 파일명, 그래프 IRI 순으로 작성
SQL> ld_dir('/home/ubuntu/data/cow', '*.ttl', 'http://data.test.com/graph/cow/');
SQL> select * from DB.DBA.load_list;
SQL> rdf_loader_run();
SQL> checkpoint();

하나의 폴더에 여러 개의 폴더 구조가 있는 데이터 업로드하기

car라는 폴더에 bmw라는 폴더와 hyundai라는 폴더가 있고, 각 폴더에 업로드하고 싶은 ttl 파일이 있다면 ld_dir_all을 사용하면 된다. 물론 DB.DBA.load_list가 해당 목록에 업로드되었는지 확인하고, rdf_loader_run()checkpoint()를 실행해줘야 한다.

SQL> ld_dir_all('/home/ubuntu/data/car', '*.ttl', 'http://data.test.com/graph/cow/');

특정 문자열이 포함된 파일만 업로드하기

isqlsql로 할 수 있는 기능을 지원하고 있기 때문에, %과 같은 와일드 카드 문자의 사용이 가능하다. 파일 목록에 '서울'이 들어간 rdf 파일만 업로드하고 싶다면, 다음의 코드를 작성하면 된다.

SQL> ld_dir('/home/ubuntu/data/cow', '%서울%.rdf', 'http://data.test.com/graph/cow/');

추가: DB.DBA.load_list에 목록이 있어도 데이터가 업로드 되지 않는 경우

DB.DBA.load_list가 원하는 데이터 항목이 업로드되어 있는데, 실제로 rdf_loader_run()을 했을 때 데이터가 업로드되지 않을 때가 있다. ll_state가 2인 경우는 ld_dir 또는 ld_dir_all로 데이터 목록을 업로드해도 rdf_loader_run()이 작동하지 않는다. 그럴 때는 DB.DBA.load_list 목록에서 해당 데이터 목록을 삭제해줘야 한다. 해당 데이터 목록을 삭제하는 방법은 sql 구문과 동일하다. 지우려고 하는 데이터의 Graph IRI가 http://data.test.com/graph/cow/라면 where 구문으로 조건을 걸어서 해당 행을 삭제해주면 된다.

SQL> delete from DB.DBA.load_list where ll_graph='http://data.test.com/graph/cow/';

추가: named graph 삭제하기

conductor에서 직접 네임드 그래프를 삭제하는 데에 시간이 꽤 오래 걸린다. isql은 코드 기반으로 네임드 그래프를 삭제할 수 있는 기능을 제공한다. log_enable에 대한 함수는 정확히 이해하지 못했지만, 자동 커밋 또는 수동 커밋을 설정하는 코드 같다2. 그 다음은 지우고 싶은 graph IRI를 입력하면 버투소에서 해당 네임드 그래프가 삭제된다.

SQL> log_enable(3,1);
SQL> SPARQL CLEAR GRAPH <http://data.test.com/graph/cow/>;
Tags:
#virtuoso
#bulk data
#named graph