etcd 의 WAL 이 무엇인가요?

etcd 의 WAL(Write Ahead Log)이 무엇인지 알아봅니다. 세그먼트 파일 구조와 이름 규칙, Raft 상태 저장 방식, 데이터 무결성을 보장하는 원리를 정리했습니다.

etcd 의 WAL 이 무엇인가요?
etcd
💡
WAL (Write Ahead Log)는 etcd 가 데이터베이스에 적용되기 전에 모든 변경 사항을 기록하는 곳으로, 미리 쓰기 라는 측면에서 반영될 작업이 미리 기록되어 데이터 무결성과 시스템 일관성을 보장한다는것을 의미합니다.
etcd 데이터 디렉터리에서 WAL 파일을 조회한 터미널 출력
etcd 데이터 디렉터리에서 wal 파일을 조회한 모습

각 파일은 WAL 의 세그먼트를 의미하고, 이 파일은 etcd 클러스터의 트랜잭션 스냅샷을 캡처해서, 필요한 경우 etcd 상태를 재 구축하는데 사용 할 수 있는 변경 내역을 보존합니다. 각 파일 내부에는 Raft 의 상태와 데이터가 저장되어있습니다.

WAL 파일은 WAL 레코드의 스트림이고, $seq-$index.wal 형태로 저장됩니다. WAL 파일은 64MB 크기를 초과하면 wal 파일을 잘라내고 새로운 내부 시퀀스 번호와 함께 새로운 파일이 생성됩니다. 뒤쪽의 index 는 마지막 저장된 Raft 인덱스의 증분만큼 늘어난 값으로 저장됩니다.

0000000000000001-0000000000000021.wal 처음 파일이 이런 형태였고 이후 0x10 인덱스만큼 Raft 파일 인덱스가 늘어난 상태에서 파일을 잘라내면 새로운 파일은 0000000000000002-0000000000000031.wal 이 됩니다.

0.tmp , 1.tmp 는 번갈아가면서 나타나고 wal 파일을 저장하기 위한 임시 파일로써 쓰입니다.

 

etcd 의 과거 문서(v2.3) 에서는 (Administration )

wal 파일을 저장할 전용 디스크를 사용하면 처리량을 개선하고 클러스터를 안정화 할 수 있다고 설명합니다.

etcd 의 나름 최근 문서 (v3.4) 에서는 (Configuration options )

--wal-dir 을 지정해서 etcd data directory 가 아닌곳에 저장하고, 전용 디스크를 사용하면서 로깅과 다른 I/O 작업과의 경쟁을 피할 수 있다고 설명합니다.

wal 파일 전용 디스크를 생성하고, 해당 디스크가 마운트된 경로에 wal 파일을 저장하도록 설정하는 것입니다. 이 설정은 현재에도 있으며 인자로 전달할 때 --wal-dir , 환경 변수로는 ETCD_WAL_DIR 형태로 전달 해줄 수 있는 값입니다.

 

etcd 의 최근 문서 (v3.5 , v3.6) 에서는 관련된 내용은 없고 이러한 설정값이 있다고만 설명하고 있습니다.

또한 이와 별도로 --max-wals , ETCD_MAX_WALS 형태로 wal 파일의 개수를 지정 할 수 있는데, 디폴트 값은 5 이며 윈도우 사용자는 0 으로 설정되는데, 0 은 해당 파일 개수를 제한을 두지 않겠다는 설정입니다. (Configuration options)

그래서 실제로 생기고 동작하나요?

wal 파일은 etcd 에 쓰기 작업을 요청할때, 그리고 그 크기가 64MB 가 넘어 갈 때 마다 잘라서 생성됩니다. 그래서 etcd 쓰기작업을 시뮬레이션 하는 겸, etcd 성능 테스트를 할 수 있는 $ etcdctl check perf --load="s" 같은 명령어로 테스트 해봅니다. --loads, m , l 이렇게 있고, 각각의 수준의 load 별로 etcdI/O 성능이 적절한지 테스트하는것이라고 보면 됩니다.

 

현재 192.168.100.2 , 192.168.100.2 , 192.168.100.3 총 3개의 머신에 etcd 가 설치되어있다고 가정하고 아래와 같은 명령어로 테스트를 시작해봅니다.

export ETCDCTL_API=3
HOST_1=192.168.100.2
HOST_2=192.168.100.3
HOST_3=192.168.100.4
ENDPOINTS=$HOST_1:2379,$HOST_2:2379,$HOST_3:2379

/usr/local/bin/etcdctl --endpoints=$ENDPOINTS \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-node1.pem \
  --key=/etc/ssl/etcd/ssl/admin-node1-key.pem \
  check perf --load="l"

이후 /var/lib/etcd/member/wal 디렉터리를 관찰해보면

etcd 부하 테스트 시작 시 WAL 파일과 1.tmp 임시 파일을 확인하는 터미널 출력
최초 테스트 시작시 wal 파일들. 1.tmp 파일도 확인 가능
WAL 파일이 하나 더 생성되고 임시 파일이 0.tmp 로 바뀐 터미널 출력
최초 시작 이후 1개의 wal 파일이 더 생긴 장면. 0.tmp 로 임시파일이 변경
WAL 파일이 추가로 생성되고 임시 파일이 다시 1.tmp 로 바뀐 터미널 출력
이후 추가적인 wal 이 하나 더 생긴 장면. 1.tmp 로 다시 임시파일 변경

이런식으로 wal 파일이 새로운 시퀀스 번호를 부여 받아서 생성되면서 + tmp 파일은 0,1,0 번갈아 나타납니다.

왜 WAL 이 필요하죠?

etcd 에 데이터를 쓰기 직전에 wal 파일을 생성함으로써 쓰기작업이 진행 중일 때 장애/충돌이 발생 했을 때 쓰고있었던 데이터가 손실 되지 않도록 하는데 목적이 있습니다. 다만 실제로 우리가 사용할 때 이 파일을 통해 복구하거나 처리할 일은 따로 없습니다. 다만 etcd 의 fault tolerance 기능 강화 목적으로 필요한 파일들입니다.