글을 작성하게 된 계기
The Google File System 논문을 읽고 학습한 내용을 정리하기 위해 글을 작성하게 되었습니다.
1. 개념 정리
글을 읽기 전, 아래와 같이 알고 있어야 할 개념들이 있는데, 이를 먼저 살펴보겠습니다.
- Metadata
- Chunk
- Chunk Handle
- Operation Log
- Consistency Model
- Chunk Lease
1-1. Metadata
메타데이터는 데이터 자체에 대한 정보를 담고 있는 데이터를 말합니다. 파일 시스템에서 파일 메타데이터는 파일 자체에 대한 정보 를 담고 있는 데이터를 의미하며, 파일의 속성, 구조, 관리에 관한 정보입니다.
각 운영체제마다 다르지만, Mac에서는 mdls stat, xattr 등의 명령어로 메타데이터를 확인할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ mdls data.pdf
kMDItemContentCreationDate = 2024-10-17 18:17:26 +0000
kMDItemContentCreationDate_Ranking = 2024-10-17 00:00:00 +0000
kMDItemContentModificationDate = 2024-10-17 18:17:27 +0000
kMDItemContentType = "com.adobe.pdf"
......
kMDItemPhysicalSize = 77824
kMDItemSecurityMethod = "None"
kMDItemTitle = "미들급 백엔드 개발자 사전과제"
kMDItemUseCount = 3
kMDItemUsedDates = (
"2024-10-17 15:00:00 +0000"
)
kMDItemVersion = "1.4"
kMDItemWhereFroms = (
......
)
이는 다음과 같은 정보들로 구성되는데, 궁금하신 분들은 각 운영체제에서 제공하는 메타데이터의 필드를 한 번 직접 확인해보세요. 😙
| Metadata Key | Description | Metadata Value |
|---|---|---|
| kMDItemContentCreationDate | 파일 생성 날짜/시간 | 2024-10-17 18:17:26 +0000 |
| kMDItemContentCreationDate_Ranking | 파일 생성 날짜에 대한 정렬 우선순위 정보 | 2024-10-17 00:00:00 +0000 |
| kMDItemContentModificationDate | 파일 최종 수정된 날짜/시간 | 2024-10-17 18:17:27 +0000 |
| kMDItemContentType | 파일 유형 메타데이터 | com.adobe.pdf |
| kMDItemContentTypeTree | 파일 유형의 계층 구조 | (“com.adobe.pdf”, “public.data”, “public.item”, “public.composite-content”, “public.content”) |
| kMDItemDateAdded | 파일이 시스템에 추가된 날짜/시간 | 2024-10-17 18:17:26 +0000 |
| kMDItemDisplayName | 파일 표시 이름 | data.pdf |
| kMDItemDocumentIdentifier | 파일 고유 문서 ID | 0 |
| kMDItemEncodingApplications | 파일을 인코딩하는 데 사용된 애플리케이션 | (“Skia/PDF m131 Google Docs Renderer”) |
| kMDItemFSContentChangeDate | 파일 내용이 마지막으로 변경된 날짜/시간 | 2024-10-17 18:17:27 +0000 |
| kMDItemFSCreationDate | 파일이 파일 시스템에 생성된 날짜/시간 | 2024-10-17 18:17:26 +0000 |
| kMDItemFSCreatorCode | 파일을 생성한 응용 프로그램의 코드 | ”” |
| kMDItemFSFinderFlags | Finder에서 사용하는 추가 파일 속성 | 0 |
| kMDItemFSHasCustomIcon | 사용자 정의 아이콘이 있는지 여부 | (null) |
| kMDItemFSInvisible | 파일이 숨겨져 있는지 여부 | 0 |
| kMDItemFSIsExtensionHidden | 파일 확장자가 숨겨져 있는지 여부 | 0 |
| kMDItemFSIsStationery | 파일이 템플릿(정지 문서)으로 설정되었는지 여부 | (null) |
| kMDItemFSLabel | Finder에서 설정된 파일 라벨 | 0 |
| kMDItemFSName | 파일 시스템에서의 이름 | data.pdf |
| kMDItemFSNodeCount | 파일의 하위 노드 수 | (null) |
| kMDItemFSOwnerGroupID | 파일의 소유 그룹 ID | 20 |
| kMDItemFSOwnerUserID | 파일의 소유 사용자 ID | 501 |
| kMDItemFSSize | 파일의 크기 (바이트) | 76939 |
| kMDItemFSTypeCode | 파일 형식 코드 | ”” |
| kMDItemInterestingDate_Ranking | 파일과 관련된 중요한 날짜의 정렬 정보 | 2024-10-17 00:00:00 +0000 |
| kMDItemKind | 파일 종류 | PDF 문서 |
| kMDItemLastUsedDate | 파일이 마지막으로 사용된 날짜/시간 | 2024-10-17 18:17:31 +0000 |
| kMDItemLastUsedDate_Ranking | 마지막 사용 날짜에 대한 정렬 우선순위 정보 | 2024-10-17 00:00:00 +0000 |
| kMDItemLogicalSize | 파일의 논리적 크기 (압축되지 않은 경우) | 76939 |
| kMDItemNumberOfPages | PDF 파일의 총 페이지 수 | 4 |
| kMDItemPageHeight | PDF 파일의 페이지 높이 | 842 |
| kMDItemPageWidth | PDF 파일의 페이지 너비 | 596 |
| kMDItemPhysicalSize | 파일의 실제 물리적 크기 | 77824 |
| kMDItemSecurityMethod | PDF 파일의 보안 방식 | None |
| kMDItemTitle | PDF 문서의 제목 | 미들급 백엔드 개발자 사전과제 |
| kMDItemUseCount | 파일이 사용된 횟수 | 3 |
| kMDItemUsedDates | 파일이 사용된 날짜들 | (“2024-10-17 15:00:00 +0000”) |
| kMDItemVersion | PDF 파일의 버전 | 1.4 |
| kMDItemWhereFroms | 파일의 출처 (다운로드 링크 등) | (“https://mail-attachment.googleusercontent.com/…”) |
GFS는 다음과 같은 메타데이터를 마스터에서 관리합니다.
File and Chunk Namespace: 클라이언트가 파일을 생성하거나 검색할 때, 마스터 서버는 이 네임스페이스를 조회하여 파일과 청크의 위치를 정확히 식별하고, 클라이언트에게 파일 접근 경로를 제공합니다.File-to-Chunk Mapping: 클라이언트가 파일을 읽거나 수정할 때, 마스터 서버는 해당 파일이 어떤 청크들로 분할되어 있는지 이 매핑 정보를 참조하여 파일에 대한 작업을 원활하게 처리할 수 있게 합니다.Chunk Replica Locations: 청크의 복제본이 저장된 서버 위치를 관리하여, 데이터를 읽거나 복구할 때 활용합니다.
메타데이터는 메모리 에 저장되어 마스터 서버에서 작업을 신속하게 처리할 수 있으며, 각 64MB 청크당 약 64byte 이하의 메타데이터를 관리합니다. 즉, 메타데이터를 중앙 집중식 으로 관리하여 마스터 서버가 파일 시스템의 상태를 완전히 파악할 수 있습니다. 마스터 서버는 파일과 청크의 이름, 파일-청크 매핑 정보, 청크 복제본의 위치를 모두 관리함으로써, 데이터의 일관성을 유지하고 동시 접근이 많은 환경에서도 안정적으로 작동할 수 있습니다.
1-2. Chunk
GFS에서는 파일을 64MB 단위의 청크(Chunk)로 나누어 저장합니다. 각 청크는 고유한 Chunk Handle을 가지고 있으며, 이를 통해 분산된 여러 서버에 저장된 청크를 식별합니다. 예를 들어, 200MB 크기의 동영상 파일은 64MB씩 나누어 3개의 64MB Chunk와 1개의 8MB Chunk로 나눠집니다.
GFS에서 파일을 64MB 단위로 Chunk로 나누어 저장하는 이유는 효율성, 부하 분산, 안정성, 확장성, 병렬 처리 때문 입니다.
효율성: 대용량 파일을 작은 단위로 나누어 각 청크만 처리하므로 입출력 성능이 향상됩니다.부하 분산: 여러 서버에 청크를 분산 저장하여 서버 과부하를 방지하고 작업을 나눌 수 있습니다.안정성: 청크의 복제본을 만들어 서버 장애 시에도 데이터 복구가 가능해집니다.확장성: 청크를 통해 시스템을 쉽게 확장할 수 있으며, 새로운 서버 추가도 용이합니다.병렬 처리: 여러 서버에서 동시에 청크를 처리해 데이터 접근 속도가 빨라집니다.
각 Chunk는 최소 3개의 복제본 을 가지고 있어, 데이터의 안정성과 복구를 보장합니다. 이 복제본들은 여러 서버에 분산 저장되어, 부하를 분산시키고 병렬 처리를 통해 성능을 향상시킵니다. 클라이언트가 데이터를 읽거나 쓸 때는 Chunk Handle을 사용하여 가장 효율적인 서버에 접근함으로써 데이터 처리 속도를 극대화할 수 있습니다.
1-3. Chunk Handle
Chunk Handle은 64bit 크기의 값으로 전역적으로 고유한 식별자 입니다. 분산 파일 시스템에서 각 Chunk는 고유한 식별자를 가지기 때문에 충돌이나 중복 없이 관리될 수 있습니다.
ID of a chunk (64 bit, globally unique)
클라이언트가 특정 청크에 데이터를 읽거나 쓰려고 할 때, 마스터 서버는 해당 Chunk Handle을 통해 청크 위치(Chunk Location) 를 식별하고, 클라이언트에게 어느 서버에 청크가 저장되어 있는지 정보를 제공합니다. 클라이언트는 이 정보를 바탕으로 직접 청크 서버에 접근해 데이터를 읽거나 쓸 수 있습니다.
1-4. Operation Log
GFS에서 파일 시스템의 상태를 안전하게 관리/복구하는 핵심 메커니즘은 Operation Log와 CheckPoint 입니다. 클라이언트가 새로운 파일을 추가할 때, 마스터 서버는 해당 작업을 Operation Log에 기록합니다. 예를 들어, example.txt라는 파일이 생성되고, 이 파일의 청크가 서버 A, B, C에 복제되었다는 정보가 로그에 기록되며, 이 기록은 여러 원격 머신에 복사되어 백업됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 파일 생성 - 초기 청크 복제본 생성
[2024-10-17 10:15:30] Operation: CREATE FILE
File: example.txt
Chunk Handle: 1234567890ABCDEF
Initial Chunk Replicas: Server A, Server B, Server C
# 파일에 데이터 추가 - 청크 복제본 업데이트
[2024-10-17 10:15:45] Operation: APPEND CHUNK
File: example.txt
Chunk Handle: 1234567890ABCDEF
Replicas Updated: Server A, Server B, Server C
# 장애로 - 특정 서버에서 청크 삭제
[2024-10-17 10:16:15] Operation: DELETE CHUNK
File: example.txt
Chunk Handle: 1234567890ABCDEF
Deleted From: Server A
Reason: Server Failure
또한, 마스터 서버는 주기적으로 파일 시스템의 상태를 캡처한 Checkpoint를 생성합니다. Checkpoint는 파일 시스템의 현재 상태를 담은 스냅샷으로, 메모리에 바로 로드할 수 있는 Compact B-tree 구조로 저장됩니다. 만약 마스터 서버에 장애가 발생하면, 가장 최근의 Checkpoint를 먼저 로드하여 복구 시간을 단축하고, 이후 Operation Log에 기록된 작업을 재실행(replay)하여 파일 시스템을 완전히 복구합니다.
The master checkpoints its state whenever the log grows beyond a certain size so that it can recover by loading the latest checkpoint from local disk and replaying only the limited number of log records after that. The checkpoint is in a compact B-tree like form that can be directly mapped into memory and used for namespace lookup without extra parsing. This further speeds up recovery and improves availability.
Checkpoint를 만드는 과정은 시간이 걸리기 때문에, 마스터 서버는 새로운 로그 파일로 전환하여 별도의 스레드에서 Checkpoint를 생성합니다. 또한 Checkpoint 생성 중 오류가 발생하더라도, 이는 전체 시스템의 데이터 무결성에 영향을 주지 않습니다. 복구 과정에서 불완전한 Checkpoint는 감지되어 무시되며, 이전 Checkpoint와 그 이후의 로그 기록을 사용해 정상적으로 복구됩니다.
1-5. Consistency Model
GFS는 완화된 일관성 모델(Relaxed Consistency Model) 을 채택하여 파일 시스템을 보다 단순하고 확장성 있게 운영할 수 있도록 설계되었습니다. 전통적인 파일 시스템은 모든 클라이언트가 동일한 데이터를 항상 볼 수 있도록 엄격한 일관성을 요구하지만, GFS는 이를 완화함으로써 복잡성을 줄이고 성능을 높였습니다.
For example, we have relaxed GFS’s consistency model to vastly simplify the file system without imposing an onerous burden on the applications. We have also introduced an atomic append operation so that multiple clients can append concurrently to a file without extra synchronization between them. These will be discussed in more details later in the paper.
GFS에서는 클러스터를 구성하는 수백 대에서 수천 대의 저렴한 상용 하드웨어로 만든 스토리지 머신들이 주기적으로 장애가 발생할 수 있는 것을 전제로 설계되었습니다. 즉, GFS는 장애가 예외적인 상황이 아닌, 일반적인 상황으로 간주합니다.
First, component failures are the norm rather than the exception. The file system consists of hundreds or even thousands of storage machines built from inexpensive commodity parts and is accessed by a comparable number of client machines.
이 과정에서 Atomic Append 기능을 도입하여, 여러 클라이언트가 동시에 파일에 데이터를 추가할 때 별도의 동기화 없이도 안전하게 기록될 수 있도록 보장합니다. 이를 통해 클라이언트는 각자 데이터를 추가하면서도 서로의 작업에 영향을 주지 않으며, 파일 시스템이 클라이언트 간 충돌 없이 데이터를 처리할 수 있게 됩니다.
정상적(Consistent): 모든 클라이언트가 동일한 데이터를 볼 수 있는 상태입니다.일관성 없음(Inconsistent): 클라이언트가 데이터를 쓰는 도중 장애가 발생해 복제본 간 일관성이 맞지 않는 상태입니다.정확성 없음(Append-Only): Atomic Append 연산을 사용할 때, 일부 클라이언트가 추가한 데이터의 순서가 맞지 않을 수 있지만, 데이터가 중복되거나 손실되지 않은 상태입니다.
1-6. Chunk Lease
GFS에서 Chunk의 변조를 안전하게 처리하기 위한 중요한 메커니즘입니다. 마스터는 데이터 조작에 직접 관여하지 않기 때문 에, 복제본 중 하나에게 변조 순서를 결정할 권한을 임대하고, 클라이언트는 이 임대를 받은 복제본과 통신해 데이터를 전송합니다. 이를 통해 데이터 변조가 일관성 있게 관리되며, 네트워크 전송이 효율적으로 이루어져 성능이 최적화됩니다.
Chunk Lease를 사용하는 이유는 여러 클라이언트가 동시에 하나의 청크를 수정하거나 데이터를 추가하려고 할 때, 동기화 문제 가 발생할 수 있기 때문입니다. 예를 들어, 클라이언트 A가 청크에 데이터를 추가하고, 그와 동시에 클라이언트 B도 동일한 청크에 데이터를 추가하려고 한다면, 이 두 작업 중 어느 작업이 먼저 적용되어야 할지 순서가 필요합니다. 이 순서를 정하는 역할을 Primary Chunk가 하며, 변조 순서를 관리해 동기화 문제를 해결합니다.
클라이언트는 데이터를 여러 복제본으로 전송한 후, 마지막에 Primary Chunk에게 변경 작업을 확정해달라는 최종 요청을 보냅니다. Primary Chunk는 순서를 정한 후, 그 순서대로 다른 복제본들에게도 동일하게 적용합니다.
작업 순서가 결정되는 동안은 일시적인 비동기 상태가 존재할 수 있습니다.
2. 아키텍처 및 동작과정
위에서 GFS에 사용된 개념들에 대해 살펴봤는데, 이제 GFS의 아키텍처 및 동작과정에 대해 살펴보겠습니다. GFS 클러스터는 단일 마스터 와 여러 청크 서버 로 구성되어 있으며, 다수의 클라이언트가 접근할 수 있습니다.
2-1. 클라이언트 요청 처리
GFS에서 클라이언트가 파일을 생성하거나 수정하려는 요청을 보내면, 클라이언트는 가장 먼저 마스터 서버에 접근합니다. 이때, 마스터 서버는 파일과 청크의 네임스페이스, 파일-청크 매핑 정보, 청크 복제본 위치 등 모든 관련 메타데이터를 관리하는 역할을 합니다. 이를 통해 클라이언트는 파일을 어디서 찾고 수정할 수 있는지 정보를 얻습니다.
마스터 서버는 작업에 관여하지 않고 메타데이터 관리에 집중합니다. 즉, 파일의 청크가 저장된 서버를 클라이언트에게 알려주면, 클라이언트는 이후 해당 청크 서버와 직접 통신 하여 데이터를 전송하거나 수정 작업을 진행하게 됩니다. 이를 통해 GFS는 마스터 서버와 클라이언트 간의 통신을 최소화하여 마스터의 부하를 줄이고, 클라이언트는 네트워크를 효율적으로 사용해 청크 서버들과 직접 데이터 전송을 처리함으로써 성능을 최적화합니다.
2-2. 청크 서버와 동기화 처리
클라이언트가 동일한 청크를 동시에 수정할 경우 동기화 문제가 발생할 수 있습니다. 이를 방지하기 위해 GFS는 Chunk Lease를 사용합니다. 마스터 서버는 Primary Chunk를 선정해 변조 작업의 순서를 결정할 권한을 부여합니다. 이렇게 지정된 Primary Chunk는 여러 클라이언트가 동시에 데이터를 추가하거나 수정하려고 할 때 그 순서를 결정하고, 이를 다른 복제본에 동일하게 적용하여 데이터의 일관성을 보장합니다.
Primary Chunk에게 변경 작업을 확정하도록 요청하며, Primary는 요청을 받은 뒤 각 청크에 동일한 작업을 수행합니다. 이러한 방식으로 동시 작업 환경에서도 일관성 있게 데이터를 처리할 수 있습니다. 단, 작업이 진행되는 동안은 일관성이 순간적으로 보장되지 않을 수 있습니다.
2-3. Operation Log와 Checkpoint
마스터 서버는 메타데이터 변경 사항을 Operation Log에 기록하고, 주기적으로 Checkpoint를 생성하여 파일 시스템의 상태를 저장합니다. 만약 마스터 서버에 장애가 발생하더라도, Checkpoint와 Operation Log를 통해 빠르게 복구할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 파일 생성 - 초기 청크 복제본 생성
[2024-10-17 10:15:30] Operation: CREATE FILE
File: example.txt
Chunk Handle: 1234567890ABCDEF
Initial Chunk Replicas: Server A, Server B, Server C
# 파일에 데이터 추가 - 청크 복제본 업데이트
[2024-10-17 10:15:45] Operation: APPEND CHUNK
File: example.txt
Chunk Handle: 1234567890ABCDEF
Replicas Updated: Server A, Server B, Server C
# 장애로 - 특정 서버에서 청크 삭제
[2024-10-17 10:16:15] Operation: DELETE CHUNK
File: example.txt
Chunk Handle: 1234567890ABCDEF
Deleted From: Server A
Reason: Server Failure
또한 GFS의 Operation Log와 Checkpoint는 순서 일관성을 유지하는 중요한 역할을 합니다. Operation Log는 모든 메타데이터 변경 사항을 기록하며, 이러한 로그를 통해 마스터 서버는 클라이언트의 모든 작업이 정확한 순서로 처리되었음을 보장할 수 있습니다. 예를 들어, 파일을 생성하거나, 데이터를 추가하고, 청크를 삭제하는 작업이 발생하면, Operation Log에 기록된 순서대로 작업이 처리되었다는 것이 보장됩니다. 만약 장애가 발생하더라도, 로그에 기록된 내용을 바탕으로 복구 시 마지막 Checkpoint 이후의 작업들이 순차적으로 재실행되기 때문에, 데이터 일관성이 유지됩니다.
1
2
3
4
5
6
[2024-10-17 10:16:15] CREATE # 1
[2024-10-17 10:17:20] UPDATE # 2
[2024-10-17 10:17:21] REPLICATION # 3
[2024-10-17 10:17:22] REPLICATION # 4
[2024-10-17 10:17:23] REPLICATION # 5
[2024-10-17 10:17:25] DELETE # 6
3. 배운점
파일 시스템 자체에 대한 학습도 했지만, 데이터 동기화 에 대해 많이 생각해볼 수 있었습니다. 평소 데이터의 일관성을 맞출 때, 데이터 정합성이 중요하지 않다면 락을 사용하지 않고, 중요하다면 RDB 락 이나 레디스의 분산락 을 통해 문제를 해결하려 했습니다.
- GFS 아키텍처
- 데이터 동기화
4. 정리
평소 구글 스프레드시트, 구글 등을 자주 사용하기 때문에 구글의 파일 시스템이 어떻게 구성 돼 있는지, 아키텍처 내부는 어떻게 구현 돼 있는지 정말 궁금했습니다. 실습하는 것을 좋아하기 때문에 직접 만들어 보고 싶었지만, 이번 주 일정이 너무 많아서 시간이 부족했습니다. 이 부분은 추후 보강해보도록 하겠습니다.