NoSQL/Cassandra DB

카산드라(cassandra), Commit Log, Memtable, SSTable

어휘 창고 지기 2021. 8. 11. 11:00
반응형

카산드라는 테이블의 데이터를 넣는 저장소를 SSTable(Sorted String Table)이라 합니다. SSTable은 파일이기 때문에 데이터가 입력되는 시점에 항상 SSTable로 저장한다면 저장하는 데 많은 시간이 소요될 것입니다. 저장뿐만 아니라 데이터를 읽기 위해 항상 SSTable에서 읽어와야 한다면 읽는 시간도 오래 걸릴 겁니다. 그래서 SSTable에 저장하기 전에 메모리에 먼저 기록합니다. 이 메모리를 Memtable 이라 합니다. 그러나 Memtable의 이름에서 알 수 있듯이 Memtable은 메모리이므로 휘발성입니다. 서버가 다운되면 메모리에 기록된 데이터는 모두 지워집니다. 그러므로 메모리에 기록하기 전에 디스크 파일로 저장할 필요가 생깁니다. 이를 커밋로그(Commit Log)라 합니다. 아래의 그림은 이를 도식화한 것입니다.

그림 1. 데이터 입력 과정 도식화

위의 그림의 가로선은 메모리 영역과 디스크 영역의 구분 선입니다. 저장되는 순서를 나열하면 다음과 같습니다.

① 저장할 데이터가 입력되면 커밋 로그(Commit log)에 해당 내용을 기록합니다. 커밋 로그에 입력된 후에는 해당 노드가 다운되거나 재시동하더라도 커밋 로그에 데이터가 존재하는 한 해당 내용을 복원할 수 있습니다.

② 영구적으로 디스크에 저장하기 전에 입력 데이터는 먼저 Memtable에 기록합니다. Memtable은 일반적으로 테이블당 한 개가 할당됩니다. 메모리는 쓰기/읽기 속도가 디스크와는 비교할 수 없을 만큼 빠르기 때문에 클라이언트에서 데이터 조회 시 가장 먼저 찾는 위치가 바로 Memtable입니다. (카산드라 버전 2.1 이후로 JVM heap에서 Memtable를 관리하지 않아 Java Garbage Collection으로 인한 성능 저하가 개선되었습니다.)

③ 메모리나 커밋 로그가 가득 차게 되면 비로소 Memtable의 내용을 SSTable에 기록하게 됩니다.

SSTable은테이블의 내용을 아래와 같이 Key:Value 형식의 스트링을 파일로 저장합니다.

 

{
   "partition" : {
     "key" : [ "1000" ],
     "position" : 420
   },
   "rows" : [
     {
       "type" : "row",
       "position" : 619,
       "clustering" : [ 10 ],
       "cells" : [
         { "name" : "b", "value" : 100 },
         { "name" : "address", "deletion_info"},
         { "name" : "address", "path", "value" : "서울" },
         { "name" : "address", "path", "value" : "부산" },
         { "name" : "address", "path", "value" : "광주" },
         { "name" : "books", "deletion_info"},
         { "name" : "books", "path" : [ "cassandra" ], "value" : "2020-02-01" },
         { "name" : "books", "path" : [ "mongodb" ], "value" : "2020-02-20" },
         { "name" : "contact", "deletion_info"},
         { "name" : "contact", "path" : [ "a123@hotmail.com" ], "value" : "" },
         { "name" : "contact", "path" : [ "b456@gmail.com" ], "value" : "" }
       ]
     },
     {
       "type" : "row",
       "position" : 619,
       "clustering" : [ 11 ],
       "cells" : [
         { "name" : "b", "value" : 300 },
         { "name" : "address", "deletion_info"},
         { "name" : "address", "path", "value" : "서울" },
         { "name" : "address", "path", "value" : "부산" },
         { "name" : "address", "path", "value" : "광주" },
         { "name" : "books", "deletion_info"},
         { "name" : "books", "path" : [ "cassandra201" ], "value" : "2020-02-01" },
         { "name" : "books", "path" : [ "mongodb201" ], "value" : "2020-02-20" },
         { "name" : "contact", "deletion_info"},
         { "name" : "contact", "path" : [ "a123@hotmail.com" ], "value" : "" },
         { "name" : "contact", "path" : [ "b456@gmail.com" ], "value" : "" }
       ]
     }
}

반응형