MongoDB의 wiredTiger 스토리지 엔진

 

MongoDB의 wiredTiger 스토리지 엔진

WiredTiger 스토리지 엔진

WiredTiger 스토리지 엔진은 내부적인 Lock 경합 최소화를 위해서 Hazard-Pointer나 Skip-List와 같은 많은 신기술을 채택하고 있으며, 최신 RDBMS들이 가지고 있는 MVCC와 데이터 파일 압축, 암호화 기능등을 갖추고 있습니다.

 

WiredTiger 스토리지 엔진의 가장 자주 쓰는 기본적인 파라미터를 몇 가지 보겠습니다.

  • dbPath: 데이터 파일이 저장되는 경로. MongoDB는 저널로그나 OpLog가 모두 이 디렉토리의 하위에 저장된다. 다른 디스크나 파티션에 저장하고 싶을때는 심볼릭링크를 사용하는 것이 좋음.
  • directoryPerDB: 데이터베이스 단위로 디렉토리를 생성할 지 dbPath에 모두 생성할 지 결정한다. true로 설정하면 데이터베이스 별로 생성한다.
  • journal: 서버의 저널로그(=트랜잭션 로그)를 활성화할 것인지 결정.
    • journal.enabled를 false로 하면 저널로그를 디스크에 기록하지 않음.
    • journal.commitIntervalMs 옵션은 디스크에 동기화 간격을 결정. MongoDB는 트랜잭션 단위로 저널 로그를 디스크에 동기화 하지 않기 때문에 해당 옵션에서 설정한 밀리초 단위로 주기적으로 저널로그를 디스크에 동기화한다.

 

WiredTiger 스토리지 엔진의 저장 방식

WiredTiger 스토리지 엔진은 3가지 타입의 저장소를 가지고 있습니다.

  • 레코드(도큐먼트) 스토어: 일반적인 RDBMS가 사용하는 저장 방식. 테이블의 레코드를 한꺼번에 같이 저장하는 방식. B-Tree 알고리즘 사용
  • 컬럼 스토어: 대용량 분석(OLAP 또는 DW)용도로 주로 사용. 테이블의 레코드와 상관없이 각 컬럼 패밀리로 데이터 파일을 생성하므로 데이터파일의 크기가 작고 속도가 빨라 대용량 분석에 적합
  • LSM(Log Structured Merge Tree) 스토어: HBase나 카산드라와 같은 NoSQL에서 자주 사용하는 저장 방식으로, 데이터 읽기보다는 쓰기에 집중한 저장방식. B-tree로 동작하지 않고 순차 파일형태로 데이터를 저장. 메모리의 저장 가능한 크기의 조각으로 데이터 파일을 관리하는데 메모리의 저장 가능한 한계를 넘어서면 디스크에 저장.

현재 MongoDB에서는 레코드 스토어 방식의 저장 방식만 사용합니다.

 

WiredTiger 스토리지 엔진의 내부 동작 방식

WiredTiger 스토리지 엔진은 다은 DBMS와 동일하게 B-Tree 구조의 데이터 파일과 서버 크래시로부터 데이터를 복구하기 위한 저널로그(WAL, Write Ahead Log)를 가지고 있습니다. Oracle의 Redo처럼 파일 내에서 로테이션 되는 방식이 아니라 새로운 로그파일을 생성하고, 지난 사용하지 않는 파일은 자동으로 삭제하는 방식입니다. 저널로그의 아카이빙이나 크기는 MongoDB의 설정 파일로 제어할 수 없으며, 다음과 같이 WiredTiger의 설정 옵션을 MongoDB에 명시해야 합니다.

storage:
  ...
  engine: wiredTiger
      engineConfig:
          cacheSizeGB: 10
          configString: "log=(archive=true, enabled=ture, file_max=100MB, path=/log/journal)"
      collectionConfig:
          blockCompressor: snappy
  • enabled: 저널로그를 활성화 할 것인지를 설정. true 활성, false 비활성
  • archive: 기본값으로 체크포인트 이전의 저널로그를 자동 삭제하는데, 이 것을 삭제하지 않고 아카이빙하려면 true로 설정
  • file_max: 저널로그의 최대 크기
  • path: 저널로그를 다른 경로에 저장하고자 할 때 설정

사용자가 쿼리를 실행하면 WiredTiger 스토리지 엔진은 블록 매니저를 통해서 필요한 데이터 블록을 디스크에서 읽어 공유 캐시에 적재하여 쿼리를 처리합니다. 만약 사용자가 도큐먼트의 내용을 변경하면 WiredTiger 스토리지 엔진이 트랜잭션을 시작하고 커서를 이용해서 도큐먼트의 내용을 변경합니다. 변경 내용은 공유 캐시에 먼적 적용되며, 변경된 내용을 디스크에 기록되는 것을 기다리지 않고 저널 로그에 기록한다음 처리 결과를 사용자에게 리턴합니다. WriteConcern 옵션에 따라 조금 다를수는 있는데 작업처리 결과를 반환하는 시점은 디스크에 기록한 시점이 아닌 저널로그에 기록이 완료된 시점입니다. 공유 캐시가 쌓이면 wiredTiger 스토리지 엔진은 체크포인트를 발생시켜서 공유 캐시의 더티 페이지를 모아 디스크에 기록합니다. 메모리의 더티 페이지는 디스크에 쓰기 전에 원본 데이터와 변경된 정보를 병합하는데 리컨실리에이션 모듈이 이 작업을 담당합니다.

사용자 요청 쿼리가 실행되면서 블록 매니저는 디스크의 새로운 데이터 페이지들을 계속 공유 캐시로 읽어오는데, 공유 캐시에 더 이상 더티 페이지를 읽어들일 공간이 없으면 이빅션(Eviction)모듈이 공유 캐시의 오래된 데이터 페이지를 제거하는 작업을 수행합니다. 이때 제거해야하는 데이터 페이지가 더티 페이지라면 리컬실리에이션 모듈을 이용해 디스크에 기록하고 공유캐시에서 제거합니다. 이러한 과정중에 어느 한 곳에서라도 문제가 발생하면 처리가 느려지게 됩니다.

WiredTiger 스토리지 엔진의 데이터 블록은 모두 가변 사이즈입니다. Oracle이나 MySQL의 블록 사이즈가 고정된 크기를 가지고 있는데 반해 상한선은 있지만 실제 저장되는 데이터 블록의 크기는 고정적이지 않습니다. 데이터 블럭이 고정적인 경우 압축 기능을 구현하기 어렵습니다. 8KB의 데이터 페이지를 압축한 크기가 데이터 내용에 따라 가변적일수 밖에 없는데, 가변젹인 결과물을 다시 고정된 크기의 블럭에 넣는 것은 압축 효율을 떨어트릴수 있습니다. 가변 크기의 데이터 블록을 사용하는 WiredTiger 스토리지 엔진에서는 압축이 매우 자주 사용되며, 압축된 데이터를 적절한 크기의 빈공간을 찾아 기록하는 것을 블록 매니저가 합니다. 블록 매니저는 변경된 데이터 블록을 기록할때, 프레그멘테이션을 최소화 하면서 기록되는 데이터 블록의 크기에 최적의 위치를 찾아서 저장하는 역할을 합니다.

 

공유 캐시

WiredTiger는 내부에 공유 캐시를 가지고 있습니다. 4.2 버전부터는 OS 페이지 캐시를 사용하던 MMAPv1 스토리지가 완전히 배제되었습니다. WiredTiger 스토리지 엔진은 내부에서 캐시를 사용합니다. 공유 캐시의 최적화는 MongoDB의 처리 성능에 있어 매우 중요합니다. WiredTiger 스토리지 엔진의 처리가 원활하지 못한경우 공유 캐시 사용량 그래프의 변화를 보는 경우가 많습니다.

일반적으로 RAM의 50%, 최소 256MB를 캐시 메모리로 사용합니다. MongoDB가 사용할 캐시 사이즈를 구하는 방법입니다.

Total RAM 4GB, (0.5 x (4GB – 1GB) = 1.5GB
Total Ram 1.25GB, (0.5 x (1.25GB – 1GB)) = 128MB < 256MB

전체 RAM의 사이즈가 1.25GB를 가진 경우 계산식에 의해 나오는 값이 256MB보다 작기 때문에 그냥 256MB를 사용합니다. 디스크의 인덱스나 데이터 파일을 메모리에 캐시하여 빠르게 쿼리를 처리할뿐만 아니라, 데이터의 변경을 모아서 한번에 디스크로 기록하는 쓰기 배치 기능도 가지고 있습니다.

공유 캐시는 MongoDB 서버를 재시작하지 않고도 크기 조정이 가능합니다.

db.adminCommand({"setParameter": 1, 
                 "wiredTigerEngineRuntimeConmfig": "cache_size=25G"})

일반적으로 RDBMS는 데이터 페이지 이미지를 그대로 캐시로 적재하는데, 그래서 캐시에 적재된 B-Tree 노드를 통해 자식 노드를 찾아 갈때도 B-Tree상의 주소를 사용하는데, 공유 캐시에 적재되어도 똑같은 구조를 가지고 있으며, 트리를 찾아가는 과정에서 계속 페이지와 실제 메모리상의 주소로 맵핑(별도의 해시맵)을 참조하게 됩니다. 하지만 WiredTiger 스토리지 엔진은 디스크의 데이터 페이지가 캐시로 공유될때 메모리에 적합한 트리 형태로 재구성하기 때문에 별도의 맵핑 없이 메모리 주소(C/C++ Pointer)를 이용해 바로 검색이 가능하기 때문에 맵핑 테이블의 경합이나 오버헤드가 없습니다.

일반적인 RDBMS에서는 하나의 데이터 페이지 내에 저장된 레코드들의 인덱스를 별도로 관리합니다. 이는 Table Full Scan을 하지 않지않고 필요한 데이터만 빠르게 가져오기 위한 것인데 WiredTiger 스토리지 엔진은 레코드 인덱스를 별도로 관리하지 않고 저장하며, 데이터 페이지를 공유 캐시의 메모리에 적재할 때 레코드 인덱스를 새롭게 생성해서 매모리에 적재합니다. 이런 과정에 의해 디스크에서 메모리로 적재하는 과정은 RDBMS보다 느리게 동작하지만, 캐시에 적재된 후 필요한 레코드를 검색하고 변경하는 작업은 RDBMS보다 빠르게 동작합니다.

 

Hazard Pointer

wiredTiger 스토리지 엔진에서 캐시에 메모리를 올리고, 사용 후 필요없게 되어 캐시에서 제거하는 방식이 이 Hazard Pointer를 이용합니다.

프로그래밍을 할때 Lock-Free 알고리즘을 공부하다 보면 ABA_problem(https://en.wikipedia.org/wiki/ABA_problem)을 마주치게 되는데 그때 ABA_problem을 해결하는 효과적인 방법중에 하나가 Hazard Pointer라는 것 입니다. Hazard Pointer의 알고리즘은 어떤 스레드가 자신이 안전하게 엑세스 하고자 하는 메모리 블럭이 있다면, 그것을 Hazard Pointer 리스트에 등록해두고, 그 메모리 블록을 사용합니다. 사용이 끝나면 그 메모리 블럭을 Hazard Pointer 리스트에서 제거합니다. 그리고 또 어떤 쓰레드가 더 이상 사용되지 않아 해제 해야할 메모리 블럭이 있다면, 이 메모리 블럭을 Hazard Pointer 리스트에서 검색하여 리스트에 없다면 삭제하게 됩니다. 만약 Hazard Pointer 리스트에서 발견된다면, 그것을 자신의 Retire List에 저장만 해두고 실제로 삭제하지는 않습니다. 후에 스레드가 또 메모리를 해제할 기회가 생기면 자신의 Retire List에 등록되어 있는 메모리에 전체에 대해서 Hazard Pointer 리스트 검색을 거쳐서 삭제합니다.

wiredTiger 스토리지 엔진에서 “사용자 쓰레드”는 사용자의 쿼리를 처리하기 위해서 wiredTiger 캐시를 참조하는 쓰레드이며, “이빅션 쓰레드(Eviction Thread)”는 캐시가 다른 데이터 페이지를 읽어 들일 수 있도록 빈 공간을 만드는 역할을 담당합니다. 모든 “사용자 쓰레드”는 wiredTiger 캐시의 데이터 페이지를 참조할 때, 먼저 Hazard Pointer에 자신이 참조하는 페이지를 등록합니다. 쿼리가 처리되는 동안 “이빅션 쓰레드”는 캐시에서 제거해야할 데이터 페이지를 골라 캐시에서 삭제하는 작업을 하게되는데 이때 제거해도 될만한 페이지(자주 사용되지 않는 페이지)를 골라서 먼저 하자드 포인터에 등록되어 있는지 확인하고, 등록되어 있는 페이지는 무시하고, 등록되어 있지 않는 페이지는 캐시에서 삭제합니다.

wiredTiger 스토리지 엔진 사용할 수 있는 Hazard Pointer의 기본값은 1000개이며, configString에 hazard_max 옵션 값을 설정하여 변경이 가능합니다. 최소 15부터 1000개 이상 설정할 수 있습니다.

storage:
  ...
  engine: wiredTiger
    engineConfig:
      cacheSizeGB: 10
      configString: "hazard_max=2000"

 

Skip-List

wiredTiger 스토리지 엔진에서 Lock-Free를 구현하기 위한 또 다른 기술이 스킵 리스트 자료 구조입니다. 또 스킵 리스트는 wiredTiger 엔진에서 RDBMS의 Undo 같은 역할을 합니다. 다른점이 있다면 데이터 페이지의 레코드를 직접 변경하지 않고, 변경된 데이터를 스킵 리스트에 추가합니다. 사용자가 쿼리가 데이터를 읽을 때에는 변경 이력이 저장된 스킵 리스트를 검색해서 원하는 시점의 데이터를 가져갑니다. 이렇게 변경된 내용을 직접 데이터 페이지에 덮어쓰지 않고 별도의 리스트로 관리하는 이유는 쓰기 작업 처리를 빠르게 하기 위함입니다. 변경된 내용을 스킵 리스트에 추가하기만 하면 되는데 스킵 리스트에 추가하는 작업은 매우 빠르고, 사용자의 응답 시간도 빨라집니다. 이런 방식 때문에 wiredTiger 스토리지 엔진은 여러 쓰레드가 하나의 데이터 페이지를 동시에 읽거나 쓸 수가 있어서 동시 처리 성능이 매우 향상되는 것 입니다.

 

캐시 이빅션(Cache Eviction)

wiredTiger 스토리지 엔진의 공유 캐시를 사용하는데 있어, 새로운 디스크 데이터 페이지를 읽어서 공유 캐시에 적재할 수 있도록 빈 공간을 항상 적절히 유지해야 하는데, 이렇게 빈 공간을 유지하기 위해 wiredTiger 스토리지 엔진은 이빅션 모듈을 가지고 있으며, 이를 “이빅션 서버(Eviction Server)”라고도 부릅니다. 이빅션 서버는 백그라운드 쓰레드로 실행되는데 공유 캐시에 적재된 데이터 페이지 중에서 자주 사용되지 않는 데이터 페이지 위주로 공유 캐시에서 제거하는 작업을 합니다. 이 과정에서 공유 캐시 스캔이 빈번히 발생하며 B-Tree의 브랜치 노드는 자주 접근되는 비율에 관계없이 공유 캐시에 유지하려는 경향이 있습니다. 이전에는 SSD를 사용해도 이빅션이 데이터 페이지의 읽기 성능을 따라가지 못해서 캐시가 가득차는 경우가 발생했는데, 이러한 현상은 버전업이 되면서 점차 나아졌고 현재는 MongoDB에서 SSD를 사용하는 것이 최적의 저장매체로 사용을 권장하고 있습니다.

 

Checkpoint

체크포인트는 모든 데이터베이스에 존재하는 개념으로 데이터 파일과 트랜잭션 로그가 동기화 되는 시점을 의미하며, WiredTiger 엔진은 버전 3.6부터 MongoDB는 60초 간격으로 체크포인트를 생성(스냅샷 데이터를 디스크에 기록)합니다. 사용자 데이터에 대해 60초 간격으로 또는 2GB의 저널 데이터가 기록된 경우 중 먼저 발생하는 체크포인트를 생성합니다. 사용자 요청을 빠르게 처리하면서 커밋된 트랜잭션의 영속성을 보장하기 위해서 트랜잭션 로그(WAL, Write Ahead Log = 저널로그)를 먼저 기록하고, 데이터 파일에 기록하는 것은 트랜잭션에 상관없이 뒤로 미뤄 작업을 합니다.

체크포인트는 DBMS가 서버가 크래시되거나 재구동 되었을때, 복구를 시작할 시점을 결정하는 기준이 됩니다. 체크포인트의 간격이 길면 복구 시간이 길어지게 되고, 또 반대로 너무 짧으면 쿼리를 처리하는 성능이 떨어지게 됩니다. Oracle이나 MySQL의 INNODB가 Fuzzy 방식의 체크포인트를 사용하는 것과는 다르게 MongoDB의 wiredTiger 스토리지 엔진은 Sharp 체크포인트 방식을 사용합니다. 평상시에는 디스크 쓰기가 없지만, 체크포인트가 실행되는 시점에 한 번에 모아서 더티 페이지를 기록하는 방식입니다.

wiredTiger의 체크포인트는 절대 기존의 B-Tree 구조를 덮어 쓰지 않습니다. 새로운 leaf 페이지가 추가될때 새로운 공간을 할당 받고, 새로운 브랜치 노드가 구성되면 root 노드를 삭제하지 않고 새로운 브랜치 노드가 기존 leaf부터 새로 생성된 leaf를 바라보는 B-Tree 구조가 생성되며, 만약 사용하지 않는 leaf가 있다면 해당 부분은 처내고 전체적으로 다시 B-Tree 구조를 완성합니다. 새로운 B-Tree구조가 완성되면 기존의 B-Tree를 삭제하고 사용하던 공간을 반납합니다.

 

MVCC

wiredTiger 스토리지 엔진은 REPEATABLE-READ, READ_COMMITTED, SNAPSHOT 세가지의 격리 수준을 제공하는데, SNAPSHOT 수준의 격리 수준을 기본으로 선택하고 있습니다. wiredTiger 스토리지 엔진의 SNAPSHOT 격리 수준은 REPEATABLE-READ와 동일한 수준입니다. 예전 3.x 버전에서는 트랜잭션을 엄격하게 유지하지는 않았지만, 4버전 부터는 RDBMS 수준의 트랜잭션을 지원한다고 합니다.

 

데이터 블록(페이지)

wiredTiger 스토리지 엔진은 고정된 크기의 블록을 사용하지 않습니다. 하지만 하나의 페이지가 너무 커지는 것을 방지하기 위해 최대 크기에 대해서는 제한을 두고 있습니다. B-Tree의 브랜치 노드와 leaf노드의 페이지 크기를 다르게 설정할 수 있으며, 또 컬렉션 별로, 인덱스 별로 다르게 설정할 수도 있습니다. 하지만 컬렉션 별로 미세하게 설정을 변경하게 되면 관리의 어려움이 생기고 운영 비용을 높이는 결과를 가져올 수도 있습니다. 분석이나 대량의 Insert 작업이 많다면 페이지를 크게, 소규모의 데이터에 Random access가 잦고 빈번하게 Update가 발생한다면 가능한 페이지 크기를 작게 설정하는 것이 좋습니다.

 

운영체제 캐시(페이지 캐시)

wiredTiger 스토리지 엔진은 Cached IO를 기본 옵션으로 사용하고 있습니다. wiredTiger 스토리지 엔진이 참조하고자 하는 데이터 페이지는 리눅스 페이지 캐시에 있는 데이터를 다시 자신의 공유 캐시에 복사하는 것입니다. OS의 페이지 캐시에도 있고, wiredTiger 스토리지 엔진에도 같은 데이터가 있는데 이것을 더블 버퍼링이라고 하며, RDBMS에서는 이러한 더블 버퍼링 문제를 해결하기 위해 Direct IO 방식을 주로 사용합니다. Cached IO를 사용하는 경우 리눅스 서버가 디스크 데이터 쓰기를 전담해서 처리합니다. 이때 페이지 캐시 처리에서 가끔식 문제를 발생하기도 하지만, 성능적인 부분에서는 Cached IO가 Direct IO보다 빠른 속도를 보여줍니다.

 

압축

wiredTiger 스토리지 엔진의 가장 큰 장점 중 하나는 압축 기능입니다. RDBMS와 비교 했을때 크게 3가지 장점이 있습니다.

  • 가변 사이즈의 페이지 사용: 페이지가 가변 사이즈이기 때문에 압축 결과를 그대로 디스크에 기록하기때문에 RDBMS들처럼 페이지를 스플릿하여 여러번 압축하는 과정을 가질 필요가 없습니다.
  • 데이터 입출력 레이어에서의 압축지원: wiredTiger의 블록 매니저가 디스크 데이터 페이지를 읽어오면서 공유 캐시에 적재할 때 압축을 해지한 상태에서 적재하고, 공유 캐시에서 디스크로 기록되는 페이지에 대해서만 압축을 실행해서 저장합니다.
  • 다양한 압축 알고리즘 지원: 4.2버전부터 Zstd를 지원하지 시작했으며, zlib과 Snappy를 지원하고 있습니다. 압축률이 높을수록 공간 절약이 되지만 압축하고 해제할 때 속도는 성능에 영향을 미칩니다.
압축률 압축속도 (MB/sec) 압축해제 속도 (MB/sec)
zstd 2.9 330 940
zlib 2.7 95 360
Snappy 2.1 480 1600

wiredTiger 스토리지 엔진에서는 압축 알고리즘 뿐만 아니라 컬렉션과 인덱스 그리고 저널로그에 대해서 각각 압축을 적용할 것인지 결정할 수 있습니다. 저널 로그와 데이터 파일은 Snappy로, 인덱스는 Prefix 압축을 적용해서 많이 사용합니다. Prefix 압축이란 인덱스 키에서 왼쪽 부분의 중복영역을 생략하는 압축 방식입니다. 프리픽스 압축은 블록 압축과 다르게 공유 캐시에 적재된 상태에서도 압축상태를 유지합니다. 프리픽스 압축은 데이터를 읽을 때, 항상 완전한 키 값을 얻기 위해서 조립과정을 거치는데, 페이지 첫번째에 있는 인덱스 키부터 재조립 과정을 거치게 되면 효율이 떨어지기도 합니다. 압축률이 좋으면 인덱스를 읽는 속도가 떨어질수도 있고, 인덱스를 역순으로 읽을때는 더 심해집니다.

 

암호화

엔터프라이즈 버전에서만 암호화 기능을 사용할 수 있는데, 커뮤니티 버전의 소스 코드에도 암호화 처리를 위한 인터페이스가 그대로 남아 있기 때문에 간단한게 플러그인 형태의 모듈을 개발한다면 커뮤니티 버전에서도 데이터 암호화 기능을 사용할 수 있습니다.

 

그 밖의 MongoDB의 스토리지 엔진의 종류

  • MMAPv1: 처음 몽고DB가 나왔을때 사용하던 스토리지 엔진으로 3.0부터 WiredTiger 스토리지 엔진이 나온 이후 사용하지 않음
  • In-Memory: WiredTiger의 변형으로 디스크에 기록하지 않고 Memory에만 보관하는 스토리지 엔진. 엔터프라이즈 버전에서만 사용가능하나 서버의 코드를 조금만 커스터마이징하면 커뮤니티 버전에서도 사용 가능.
  • RocksDB: 페이스북에서 LevelDB를 커스터마이징하여 개선한 스토리지 엔진
  • TokuDB: Percona에서 개발중인 스토리지 엔진

스토리지 엔진 혼합 사용

하나의 MongoDB 서버(인스턴스)에서 동시에 여러 스토리지 엔진을 사용할 수는 없습니다. 하지만 레플리카 셋에서 프라이머리 노드는 WiredTiger 엔진을 사용하고, 세컨더리에서는 RocksDB 같은 다른 스토리지 엔진을 사용하는 것은 가능합니다. 샤드 클러스터 역시 마찬가지 입니다. 1번 샤드에서는 WiredTiger를 사용하고, 2번에서는 RocksDB를 사용하는 것이 가능합니다. 프라이머리를 In-Memory 엔진으로 구성할 경구 DB가 내려가면 모든 데이터와 oplog가 사라지기 때문에 레플리카 셋의 세컨더리를 디스크 기반의 WiredTiger로 저장하면 일부 멤버는 데이터를 가지고 있는 환경을 구성할 수 있습니다. 근래에는 SSD의 성능이 매우 좋아져서, SSD기반의 WiredTiger 스토리지 엔진을 사용한 구성을 많이 합니다.

 

참고 자료

도서 : 맛있는 몽고DB

도서: Real MongoDB

도서: 오픈소스 몽고DB

도서: MongoDB in Action

MongoDB Manual: https://docs.mongodb.com/manual/

You may also like...

2 Responses

  1. 도토리 말해보세요:

    잘 읽었습니다. 몇가지 수정할 부분이 있네요.
    아마 참고하신 도서들이 옛날 버젼(3.x)을 기반으로 작성된거라서 현재 주요사용되는 버젼들과는 약간의 차이가 있네요.

    1. hazard_max 는 MognoDB 설정에서 더 이상 지원하지 않습니다. hazard pointer는 내부적으로 initial size를 정해놓고 필요하면 동적으로 늘어나는 구조로 변경되었습니다. 그리고 hazard_max 의 값은 포인터 갯수가 아닌, wiredTiger session 에서 동시에 사용가능한 포인터 입니다.
    2. Skip-List 를 사용하는 이유는 쓰기 작업 처리를 빠르게하기 위함보다는 MVCC를 구현하기 위함이 크다고 봐야 할거 같습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다