-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Paged File, I/O System Implementation #6
Open
seokmyungham
wants to merge
23
commits into
woowacourse-study-2024:jazzloki
Choose a base branch
from
seokmyungham:step1/feat-paged-file
base: jazzloki
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Paged File, I/O System Implementation #6
seokmyungham
wants to merge
23
commits into
woowacourse-study-2024:jazzloki
from
seokmyungham:step1/feat-paged-file
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
페이지 메타데이터를 정의하고 스토리지 엔진 버퍼 풀을 설계하였습니다.
더 빨리 PR을 올리고 싶었는데 독감 이슈와 더불어 학습할 내용이 점점 늘어나더니 시간이 길어져 볼륨을 조절하지 못했네요 😅
주요 구현 내용은 다음과 같습니다.
1. Page Structure
페이지 구조는 MySQL InnoDB 스토리지 엔진의 내용을 참고하였습니다.
이전에 같이 MySQL을 학습하기도 했고 오픈 소스 기술이다보니 학술적으로 참고할 수 있는 문서가 많았습니다.
일반적인 16KB 크기의 페이지를 설계하였고 페이지 메타데이터 중 아직 필요성을 느끼지 못한 몇몇 필드들은 제외하였습니다. (Page Directory, Fil Trailer)
2. ByteBuffer를 이용한 직렬화
Page 객체를 읽고 쓰기 위해 바이트로 변환하는 과정에서
java.nio
패키지의ByteBuffer
를 사용하였습니다.자바 직렬화 방법에는
java.io
가 제공하는Serializable
마커 인터페이스를 구현하는 방법이 대표적이지만 객체를 바이트 스트림으로 변환하는 과정에서 추가적으로 발생하는 여러 시스템 비용들을 확인하게 되었습니다. 그 과정에서 데이터베이스 특성에 맞는 더 저수준의 API를 사용할 필요성을 느끼게 되었습니다.ByteBuffer
할당 방식에는allocate()
를 통한힙 버퍼
,allocateDirect()
를 통한다이렉트 버퍼
가 존재합니다.힙 버퍼
는 JVM 힙 메모리 공간을 할당하여 일반적인 객체처럼 GC의 관리를 받는 방식이고,다이렉트 버퍼
는 JVM 힙 외부의 네이티브 메모리에 공간을 할당하는 방식입니다.JVM은 OS 커널 버퍼에 직접 접근하지 못하므로 일반적인 Java I/O 방식에서는 커널 버퍼에 있는 내용을 JVM 내부 버퍼로 데이터를 복사하는 과정이 필요합니다. 이를 위해 CPU가 개입하게 되고 그동안 I/O 작업을 수행하던 Thread는 Blocking 상태에 빠지게 됩니다. CPU 자원 소모, Blocking과 더불어 복사 과정에 사용한 메모리를 정리해야 하므로 GC도 수행되니 속도가 느릴 수 밖에 없는 것입니다.
반면에
다이렉트 버퍼
는 JVM 외부에 있기 때문에 커널 버퍼를 직접 핸들링할 수 있고 빠른 입출력 작업이 가능합니다. 그렇지만 네이티브 메모리를 사용한다는 것은 GC의 대상이 아니라는 뜻이고 관리를 잘하지 못하면 잦은 OOM 문제가 발생할 수 있습니다. javadoc에서는 이러한 내용을 경고하고 있습니다. 그리고 생명 주기가 길고 큰 버퍼에만 다이렉트 버퍼를 사용할 것을 권장합니다.따라서 우선적으로 현재 프로젝트에는
힙 버퍼
를 사용하는 것을 선택했고 메모리를 한정할 수 있도록ByteBufferPool
을 구현하였습니다. 추후 기능이 완성되면 벤치마크를 진행하여힙 버퍼
와다이렉트 버퍼
의 차이를 비교해서 성능을 개선할 수 있을 것 같습니다.3. Page 교체 전략
처음에는 일반적인 LRU 방식을 구현하였습니다. LRU는 시간적 지역성을 활용하여 캐시 히트율을 높일 수 있지만, 다량의 페이지를 순차 스캔할 시 기존 캐시에 존재하는 핫 페이지들이 제거되는 문제를 가지고 있습니다. 실제로 InnoDB 스토리지 엔진은 버퍼 풀의
스캔 저항성
을 확보하고자 LRU와 MRU가 결합된 방식을 사용하는데 이를 자바 코드로 구현해봤습니다.