천리 길도 한 걸음부터 시작하는 MLOps
ZFS는 “Zettabyte File System”의 약자로, 썬 마이크로시스템즈(Sun Microsystems)에서 개발한 파일 시스템이다.
ZFS는 데이터의 안정성, 성능, 스냅샷 및 복제 등의 기능을 제공하며, 오늘날 대부분의 운영 체제에서 사용 가능하다.
사실 리눅스 등에서 기본으로 채택하는 EXT4 파일 시스템에서도 스냅샷을 사용하는 것이 가능하다.
그러나 EXT4에서는 스냅샷 기능이 많이 제한되는 부분이 존재한다.
예를 들어, ext4 스냅샷은 읽기 전용이며, 스냅샷을 생성할 때마다 추가적인 디스크 공간이 필요하다.
또한, 스냅샷이 생성된 후 스냅샷과 원본 파일 시스템 간에 데이터 불일치가 발생할 수 있는 부분 때문에 EXT4를 기본 파일 시스템으로 사용하면서 단 한 번도 스냅샷 사용에 대한 내용을 못 본 것 같다.
그래서 엔터프라이즈 스토리지 쪽에서 ZFS를 차세대 파일시스템으로 보고 있는 것 같고 이 ZFS의 큰 장점 중 하나는 데이터 보호 기능인 것 같다.
데이터 무결성 검사와 복구를 위한 체크섬 기능을 갖추고 있어서, 파일 시스템에서 발생한 데이터 손실을 방지할 수 있다.
QNAP, PureStorage, NetAPP 등에서 최근 출시되는 모든 스토리지에 전부 ZFS를 사용하고 있는 것 보면, 이미 상용화 단계에서 이러한 ZFS의 장점이 충분히 부각되고 있다고 본다.
또한, EXT4와 다르게 안정적인 스냅샷 및 복제 기능을 제공하여, 중요한 데이터의 백업을 손쉽게 수행할 수 있다.
최근에 회사에서 Hot Storage 개념으로 사용하기 위해 QNAP 에서 고가의 NAS를 한 대 구매했다.
이 NAS에서는 기본적으로 65,000장 정도의 스냅샷을 제공하고 있고, 시간에 따라 관리가 되는 것으로 보인다.
약간 여담이지만 QNAP NAS 장비는 PoC를 한 달 정도 해봤는데 ZFS & EXT4 파일 시스템 모두 테스트 해보면서 성능은 EXT4가 더 높게 나오는 것을 확인했다.
그러나 정말 간혹 유저의 실수로 데이터를 날려 먹는 경우가 있어 (DB 데이터를 날리거나, 파일을 잘못 삭제하는 등…) 스냅샷은 필수고, 데이터를 복원시켜주는 일이 반드시 필요하다.
데이터에 관한 사항에 대해서는 무척 보수적으로 접근해야한다.
ZFS는 확장성도 높은데 용량이 늘어날수록 성능이 유지되기 때문에 대규모 스토리지 시스템에서도 잘 작동한다.
또한, 일반적으로 RAID와 같은 복잡한 구성을 필요로 하지 않는다.
영어로 된 블로그에서 작성된 한 글에서는 ZFS의 등장에 따라 RAID의 종말이라는 표현을 쓰는 것도 봤다.
(하지만 RAID 기능은 ZFS에서도 소프트웨어 레벨에서 제공하고 있고, 여전히 RAID controller 칩셋을 사용해 펌웨어 레벨에서 사용하는 것도 활발히 이뤄지고 있다)
따라서, ZFS는 대규모 스토리지 시스템을 구축하는 데 이상적인 파일 시스템이고 다양한 운영 체제에서 사용할 수 있다.
FreeBSD, Linux, macOS, Solaris 등에서 사용 가능하며, 우분투와 같은 리눅스 운영체제에서는 Open ZFS에서 배포하는 버전의 일부 사항을 내장하여 제공하고 있는데, 나를 포함해 많은 유저들이 ZFS를 기본 파일시스템으로 바꿔 사용하지는 않을 것 같다.
개인적으로 ZFS의 가장 큰 장점이자 단점은 메모리를 많이 사용하는 것이다.
ZFS의 메모리 사용 layer는 3개이며, L2ARC, ZIL, Memory cache다.
일단 L2ARC의 ARC는 Adaptive Replacement Cache의 약자로 SSD에서 제공하는 캐싱 레이어로 파일이 ARC에서 퇴출될 때마다 발생하고, 로그에 가중치를 부여하며, 이전에 퇴출되었으나 다시 캐시에 있는 파일은 우선 순위가 낮아 퇴출하는 방식으로 동작한다.
대부분의 엔터프라이즈 스토리지가 M.2 & NVML을 채택하고 있는 올플래시 인 것을 감안하면 SSD 디스크 중 최소 하나는 캐싱 디스크로 사용할 가능성이 높다. (최근엔 U.2로 적용 중인데, QNAP 쪽에 물어보니 차세대 디스크 타입이라 아직 관련 지원이 많이 없는 것 같다.)
그리고 ZIL은 ZFS Intent Log의 약자로, ZFS에서 트랜잭션 로그를 유지하는 데 사용되는 기능이다.
ZFS는 일반적으로 쓰기 작업을 수행할 때 데이터를 일시적으로 캐시하고, 일정 기간 이내에 디스크에 쓰기 작업을 수행한다.
그런데 이렇게 하면 쓰기 작업의 성능이 향상되지만, 시스템이 중단될 경우 데이터 무결성에 문제가 발생할 수 있을 가능성이 다분하다.
이러한 문제를 방지하기 위해, ZFS는 쓰기 작업을 수행하는 동안 트랜잭션 로그를 ZIL에 저장한다.
ZIL은 비휘발성 메모리(우리의 경우 SSD)에 저장된다.
쓰기 작업이 완료되면, ZFS는 데이터를 디스크에 쓰기 전에 먼저 ZIL에 쓴 후, 메인 스토리지에 쓰기 작업을 수행한다.
이렇게 함으로써, 시스템이 중단되더라도 ZIL에 저장된 데이터를 사용하여 데이터의 무결성을 유지할 수 있다.
ZIL은 ZFS에서 쓰기 작업의 성능을 향상시키는 데 중요한 역할을 한다.
ZFS에서는 ZIL의 성능을 높이기 위해 여러 가지 방법을 제공한다.
예를 들어, ZIL을 디스크에 쓰기 전에 메모리에서 유지하는 SLOG라는 캐시 기능을 사용할 수 있다.
또한, 여러 개의 디스크를 병렬로 사용하여 ZIL의 성능을 향상시킬 수도 있다.
하지만, ZIL을 사용하는 것은 무조건적으로 좋은 것은 아니다.
예를 들어, 매우 작은 쓰기 작업이 많은 환경에서는 ZIL이 유용하지 않을 수 있고, 데이터 웨어하우스와 같이 정제된 데이터를 읽기만하는 케이스가 해당될 수 있을 것으로 보인다. (보통 한 번 DW에 들어간 데이터를 수정하거나 지울 일은 거의 없기 때문에)
기본적으로 ZFS은 데이터에 관한 보수적 접근도 접근이지만, 워낙 메모리를 많이 사용하는 시스템으로 알려져 있어 메모리 관리를 잘 해주는 것이 중요하다.
이와 관련해서 메모리 사용량 중 캐싱 비중을 20 ~ 25% 정도만 사용하라는 글을 읽어봤었는데, 이건 추후에 ZFS 튜닝을 해보고 추가 포스팅을 해봐야겠다.
ZFS를 사용할 때, 데이터베이스에는 8K 블록사이즈 적용을 권고하고, 스토리지에는 128K 기본 값을 사용하는 것을 권장한다.
그러나 이건 데이터 타입에 따라 다를 것으로 보이고, PureStorage의 Flashblade & NetApp의 스토리지에서는 튜닝을 지원하고 있지 않아서 구매 전에 충분히 자료 조사를 하고 가는 것이 좋다.
이제 회사 데이터와 코드를 기반으로 실전 튜닝을 해볼 차례다.
Ryan