스토리지 (StableDB)
Stable v1.8.0은 이전 LevelDB 기반 상태 저장소 대신 MemIAVL을 사용합니다. MemIAVL은 하나의 상태 스냅샷을 메모리 맵 파일에 유지하고 각 새 블록의 변경 사항을 순차적 쓰기 우선 로그에 기록합니다.
디스크 I/O가 병목 현상인 이유
모든 블록은 애플리케이션 상태를 변경합니다. 노드는 두 가지 관련 작업을 완료해야 합니다.
- 상태 커밋: 새 상태에 대한 루트 해시를 계산하고 커밋합니다.
- 상태 지속성: 변경된 데이터를 스토리지에 기록하여 노드가 나중에 복구할 수 있도록 합니다.
이전 LevelDB 기반 저장소는 이러한 작업을 결합했습니다. 또한 배경 압축 중에 데이터를 다시 작성하여 나중에 효율적으로 읽을 수 있도록 저장된 레코드를 재구성했습니다.
하나의 논리적 상태 업데이트는 10-50배의 물리적 디스크 쓰기를 유발할 수 있습니다. 이를 **쓰기 증폭(write amplification)**이라고 합니다. 그런 다음 실행은 무작위 쓰기 및 압축이 지배하는 스토리지 경로를 기다려야 했습니다.
MemIAVL이 저장소를 변경하는 방법
메모리 맵 파일, 즉 mmap을 사용하면 운영 체제가 메모리 주소를 통해 파일 내용을 노출할 수 있습니다. 노드는 포인터를 따라 상태를 읽을 수 있으며, 운영 체제는 필요한 페이지를 페이지 캐시에 로드합니다.
MemIAVL은 두 가지 구조를 결합합니다.
- 스냅샷: 지속된 상태 트리의 단일 메모리 맵 표현.
- 쓰기 우선 로그 (WAL): 스냅샷 이후에 변경된 원시 변경 사항의 추가 전용 기록.
쓰기 경로
각 블록은 변경 세트를 WAL에 순서대로 추가합니다. MemIAVL은 LevelDB를 통해 업데이트를 라우팅하거나 압축을 트리거하지 않습니다. 따라서 쓰기 증폭은 10-50배에서 약 1회 쓰기로 감소합니다.
MemIAVL은 또한 트리 노드를 두 가지 범주로 나눕니다.
PersistedNode는 스냅샷에 이미 저장된 변경되지 않은 서브트리를 나타냅니다.MemNode는 현재 업데이트에 의해 메모리에서 변경된 서브트리를 나타냅니다.
MemIAVL이 다음 루트 해시를 계산할 때 변경되지 않은 PersistedNode 서브트리에서 중지됩니다. 새 MemNode 데이터를 포함하는 경로만 해싱합니다.
읽기 경로
현재 상태 읽기는 메모리 맵 스냅샷의 포인터를 따릅니다. 자주 액세스되는 페이지는 운영 체제의 페이지 캐시에 남아 있으므로 노드는 각 트리 노드에 대한 별도의 데이터베이스 조회를 피할 수 있습니다.
기록 상태 및 VersionDB
MemIAVL은 현재 상태와 노드가 유지하는 스냅샷을 제공합니다. 동반 VersionDB는 RocksDB 사이드카에 기록 버전을 저장합니다.
노드가 가장 이른 MemIAVL 스냅샷보다 오래된 기록 상태 쿼리에 응답해야 할 때 VersionDB가 필요합니다. 이는 아카이브 노드 및 장기 쿼리를 노출하는 RPC 서비스에 특히 중요합니다.
업그레이드 고려 사항
Stable 메인넷은 블록 36,976,000에서 v1.8.0을 활성화했습니다. 문서화된 업그레이드는 상태 내보내기 또는 스냅샷 재설정 없이 바이너리와 두 구성 파일을 교체했습니다.
v1.8.0 구성 파일은 새 스토리지 및 제안 경로에서 사용되는 설정을 추가합니다. config.toml과 app.toml을 백업하고, v1.8.0 템플릿을 설치한 다음, 모든 노드별 설정을 복원하세요.
아카이브 노드 운영자는 이전 가지치기 설정을 복원해야 합니다. 배포된 app.toml 템플릿은 기본 가지치기를 사용하며, 가지치기된 기록은 로컬 노드에서 복구할 수 없습니다.
추가 자료
더 자세한 기술 심층 분석 및 구현 세부 정보는 다음을 참조하십시오.
다음 단계
- 고성능 RPC: RPC 계층이 쓰기와 충돌하지 않고 상태 읽기를 노출하는 방법을 확인하십시오.
- 실행: 실행이 여기에서 다루는 스토리지 계층에 기록하는 방법을 이해하십시오.
- 노드 업그레이드: 백업을 준비하고 조정된 업그레이드 후 노드를 확인하십시오.
- 네트워크 업그레이드: v1.8.0 범위 및 활성화 세부 정보를 검토하십시오.

