GFS: Evolution on Fast-forward by Marshall Kirk McKusick, Sean Quinlan
FreeBSD의 McKusick이 GFS tech leader 였던 Sean Quinlan을 인터뷰한 acmqueue 기사.(McKusick은 ‘The Design and Implementation of the 4.4 BSD Operating System’의 저자로 FreeBSD 계의 인물이고, Sean Quinlan은 Sawzall 페이퍼에 이름이 올라가있다.)
GFS 페이퍼가 발표된 지 이미 6년이 다 되었는데, 그 동안 GFS에 어떤 변화가 있었는지, 구글의 엔지니어링 방식은 어떠한 지를 부분적으로나마 엿볼 수 있는 글이다.
이 인터뷰에서 GFS가 진화해나가고 있는 모습을 보는 것도 의미가 있겠지만, 일반적인 엔지니어링의 양상을 보여주는 것도 시사하는 바가 있다고 생각한다.
- 초기 시스템 설계에서는 설계의 단순함이나 짧은 개발기간을 위해 설계의 완결성을 일부 희생할 수 있다.
- 설계의 결함으로 인한 시스템 문제는 시스템이 실제로 적용되면서, 스케일이 커지면서, 여러 가지 용도가 생겨나면서 드러난다.
- 시스템 문제를 해결하는 방법은 여러 가지가 있다. 단기간의 튜닝을 해서 시스템의 수명을 연장할 수도 있고, 시스템의 배치 등을 조정함으로써 해결할 수도 있고, 시간과 비용을 들여 설계의 결함을 해소하는 새로운 시스템을 설계할 수도 있다.
- 시스템이 더욱 넓은 범위에서 사용되면서, 설계의 초점은 처음의 것과 전혀 다른 것 (심지어는 완전히 반대의 것)으로 변화할 수 있다.
- 초기 시스템 설계에서 유용하다고 생각했던 기능들이 오히려 부작용을 낳거나 쓸모가 없는 경우가 있다.
어떤 시스템의 엔지니어링에 있어서, 변화하는 요구사항에 얼마나 적극적이고 효율적으로 대응해나가느냐가 성공의 관건이 아닌가 싶다.
간단히 이 인터뷰 내용을 한번 정리해본다. (정리하다 보니, GFS 페이퍼를 읽은 지 너무 오래되어 GFS에 관한 세부사항이 잘못될 수 있으리라고 생각된다.)
single-master 디자인
이 인터뷰에서는 주로 single-master 디자인의 문제를 중점으로 다루고 있다. GFS 페이퍼를 읽었든지, GFS 클론을 프로덕션 환경에서 사용해봤다면, single-master 디자인이 어떠한 문제들을 가지게 될 지 쉽게 상상할 수 있을 것이다.
일단 초기 GFS에서 single-master 디자인을 선택한 것에 대해서는, 분산 파일시스템이라는 커다란 시스템을 설계하는 입장에서 초기에 디자인 문제들을 단순화하는 것, 그리고 개발기간을 단축하여 단시간 안에 많은 사용자들이 사용할 수 있었던 것으로부터 이득을 볼 수 있었다고 이야기하고 있다.
bottleneck on single-master
single-master 디자인은 초기에 예측한 사용 시나리오나 규모에서 크게 문제가 되지 않을 것으로 생각했으나, 곧 master에서 유지해야 하는 메타데이터가 증가하면서, 메타데이터 operation이 bottleneck이 되기 시작했다고 한다.
구글에서는 하나의 바이너리가 충분히 잘 동작하기만 한다면, scale 하도록 만드는 일에 좀 더 치중을 하지만, GFS의 메타데이터 문제의 경우, 예외적으로 master의 튜닝에 많은 노력을 들였다고 한다. 물론, 약간의 노력으로 이를 상회하는 효과를 얻을 것이란 느낌으로 튜닝을 진행하였으며, 일정 범위 내의 로드에서, single master가 bottleneck이 되는 현상을 줄여 single-master GFS의 수명을 연장할 수 있었다고 한다.
file-count problem (a.k.a. small-file problem)
GFS는 원래 크롤과 인덱싱과 같은 대용량 파일의 저장을 위해 만들어진 시스템이다 보니, 원래의 페이퍼에서도 chunk의 크기는 64MB다. GFS가 성공한 시스템이 되고, 여러 사용자들이 여러 용도로 사용하게 되면서, 많은 수의 작은 파일들을 저장하는 경우들도 생겨나기 시작했다고 한다. 자연스레 master가 메타데이터를 유지해야 하는 파일의 수가 증가하다 보니, master의 메모리가 차버리는 문제가 발생했다.
이 문제를 해결하기 위해 메타데이터를 여러 master에 분산할 수 있는, distributed master 시스템이 기존의 single-master와 완전히 별도의 시스템으로 개발되었고, distributed master는 여러 종류의 용도에 대응하기 위해, 평균 1MB의 파일들에 맞추어 디자인되었다고 한다.
BigTable
BigTable은 현재 크롤과 인덱싱 용도에 점점 많이 사용되고 있으며, 프론트엔드 애플리케이션에도 많이 사용되고 있다고 한다. 특히, 많은 수의 작은 데이터를 가지고 있는 애플리케이션은 BigTable을 사용하는 경향이 있다고 한다. BigTable이 file-count 문제를 해결하는 용도로도 사용될 수 있는 듯 하다.
latency-sensitive applications
batch efficiency에 초점을 맞추어 디자인 된 GFS는 latency의 면에서 여러 가지 약점을 가지고 있다. Quinlan은 대표적인 사례로 pullchunk (chunk의 replication)에 따른 latency나 master의 failover 시간에 따른 downtime, 수천 개의 operation을 queue에 한꺼번에 넣고 나서 처리를 시작하는 (아마도 MapReduce) 메커니즘 등을 들고 있다.
이러한 문제들을 해결한 사례로는 BigTable을 들고 있다. BigTable의 transaction log의 write가 지연 또는 실패할 경우 latency가 발생하는데, 항상 2개의 로그에 쓸 수 있도록 준비하고, 나중에 replay가 필요할 경우 이를 merge한다는 것이다. BigTable과 같은 GFS 애플리케이션들을 설계할 때, 이와 같이 기본적으로 latency를 숨기는 방식으로 동작하도록 설계하는 경향이 있다고 한다.
consistency
GFS의 모델에서는 client가 write가 성공할 때까지 push하는 방식이므로, operation 중 client의 crash가 일어나면 indeterminate state가 될 수 있다고 한다. 처음에는 이런 현상은 크게 문제가 아닌 것으로 봤으나, 파일 길이 등이 서로 다르게 보이는 문제 등 혼란의 여지가 많았기 때문에, 점차로 inconsistent한 상태를 허용하는 time window를 줄여갔다고 한다.
여러 client가 동시에 로그를 append할 수 있도록 하는 RecordAppend 기능과 같은 경우, loose한 consistency 모델 하에서는 서로 다른 순서의 데이터나 중복 write된 데이터 등이 발생해, 혼란을 줄 수 있는 여지가 많아지면서, RecordAppend 기능이 처음에 의도된 이득보다는 오히려 손실이 많았다고 한다.
snapshot
GFS의 recovery 메커니즘은 client가 write를 할 수 없도록 chunk를 lock하고 snapshot을 복제하는 방식으로 동작한다. 이러한 방식은 latency의 원인이 될 수 있다.
GFS의 일반적인 snapshot 기능은 초기의 다른 설계와는 달리 제대로 구현되어 있는 영역인 것으로 보이고, 구현에 있어서 많은 비용이 들어간 듯하나, 그리 자주 사용되지는 않는 듯하다.