EOS Snapshot 기능 소개
안녕하세요, 기술력이 강한 블록 프로듀서 후보 이오서울(EOSeoul)입니다.
지난 달 배포되었던 EOSIO v1.4.0 업데이트를 통해 많은 개발자분들이 기다리셨던 스냅샷 기능이 추가되었습니다. 오늘은 새로 업데이트 된 스냅샷 기능이 어떤 의미를 가지는지 커뮤니티에 소개해드리려 합니다.
Snapshot이 왜 필요할까요?
EOS 노드를 운영하는 블록 프로듀서에게 안정적인 nodeos운영은 항상 큰 고민을 가져다주었습니다.
EOS node를 운영하다보면 불가피한 상황들로 인해 강제 종료되는 상황이 발생하곤 합니다. 예를 들자면 Cloud 환경에서의 Host machine의 유지관리로 인해 강제 종료가 발생한다거나, memory 부족으로 또는 관리자의 실수로 인해 노드를 강제적으로 중지 시키는 등 예상치 못한 상황은 언제나 다양하게 발생할 수 있습니다.
특히 EOS node는 강제 종료가 되는 시점에서 정상적으로 state db를 저장하지 못하였기 때문에 Dirty Flag 에러가 발생하게 되며, 여러가지 방법을 통해 복구할 수 있지만 대표적으로 chain replay를 통해 잘못된 블럭 인덱스와 state db의 정보를 다시 동기화합니다.
“복구가 된다면 문제가 없는 것 아닌가?” 라고 생각하실 수도 있지만, EOS는 2018년 11월 1일인 현재 2450만개의 블럭이 생성 되어있고 이 모든 블럭을 replay하여 동기화를 하게 되면 (서버 스펙이나 상황에 따라 다르지만) 적게는 5시간에서 길게는 10시간 가량 복구해야 노드가 정상적으로 동작할 수 있게 됩니다.
EOS node의 운영이 중요해진 상황에서 EOS BP들과 여러 오픈소스 개발자, 시스템 엔지니어들은 다양한 방법으로 복구방법에 대해 연구 해왔고, 대표적으로 사용되었던 방법은 다음과 같았습니다.
- Block Data 디렉토리를 전체 압축하여 보관
- Filesystem의 Snapshot 기능을 이용하여 데이터를 백업
- EOS Canada에서 만든 Pitroes와 같이 블럭 데이터를 snapshot하여 백업
각 백업 방법들은 데이터를 안전하게 보관할 수 있었지만, 백업하는 동안 시간이 오래 걸리거나, EOS node를 중단해야하는 번거로움이 있었습니다. 이러한 고충을 해소하기 위해 이번 eosio v1.4.0에는 EOS node에 맞춘 snapshot 방식을 업데이트하여 배포하게 되었습니다.
Snapshot 생성하기
EOS node의 snapshot 생성은 eosio-v1.4.0 버전부터 지원되기 시작한 기능이며, producer_api_plugin이 활성화 되어 있어야 사용이 가능합니다. 따라서 eosio-v.1.4.0 이하 버전을 사용하고 있다면 1.4.0 이상의 버전으로 업데이트 하셔야 합니다.
아래는 예시를 위해 구성한 node로 eos mainnet에 연결된 fullnode 입니다.
1)snapshot RPC를 사용하기 위해 아래와 같이 producer_api_plugin을 활성화하고, snapshot 데이터를 저장할 경로(Default : --snapshots-dir="snapshots") 를 별도로 지정할 경우 아래와 같이 추가 설정을 진행합니다.
2)이때 주의해야 할 사항은 producer_api_plugin의 경우 nodeos의 동작을 중지시키거나 snapshot을 임의 생성하게하여 Data 저장소를 모두 소비할 수 있으므로 외부에서 엑세스가 불가능하게끔 앞단에 nginx와 같은 frontend를 두고 Access Control을 해주는 것이 좋습니다.
3)snapshot에 대한 설정이 완료 되었다면 nodeos를 재시작하여 설정을 적용 한 후 아래와 같이 RPC 명령을 실행합니다.
4)실행 결과로는 해당 snapshot이 생성될때의 head_block_id값과 Snapshot의 위치와 파일명이 출력 됩니다. Head block id에 해당하는 Block Number는 cleos get block BLOCK_ID 명령어로 확인 가능합니다.
Snapshot 데이터는 생성된 시점의 Head Block이 Confirm된 이후부터 유효하며, 복구를 위해 필요한 blocks.log 파일에 head block이 irreversible block으로 확정된 이후여야 정상적인 snapshot 데이터 효과를 발휘할 수 있습니다.
Snapshot 데이터로 복구하기
Snapshot 데이터로 복구하기 위해서는 Snapshot 파일과 blocks.log 파일이 존재하면 됩니다. blocks.log는 snapshot을 작성하는 시점의 Block ID가 확정블럭(Irreversible Block)이 된 이후의 로그 데이터를 가지고 있어야 하며, 확정 블럭 이전의 log 파일로 복구 시 복구가 되지 않습니다.
우리가 앞서 생성한 스냅샷의 head_block_id는 017783a726525b84f85dbcf492ae9c09b7a73b3475be9392746468724b20cfa0 이었고, 해당 block number는 24609703임을 확인하였습니다.
Snapshot의 데이터 복구 테스트를 위해 현재 정상 동작중인 노드를 강제 종료하여 Dirty Flag를 발생 시킨 후 복구를 진행하겠습니다.
nodeos가 강제종료로 인해 dirty flag를 출력하였고 동기화가 중단되었으므로, snapshot 데이터로 복구를 진행해보겠습니다.
snapshot 데이터로 복구할 때에는 nodeos의 block 디렉토리의 데이터 중 blocks.log 파일을 제외한 나머지 파일과 디렉토리 모두를 삭제해야 합니다. state 디렉토리 또한 삭제해야 합니다. 이는 snapshot 데이터를 바탕으로 blocks.index와 state 디렉토리의 shared_memory.bin,meta 파일을 재생성 하기 때문이며, 해당 파일이 남아있을 경우 정상적인 복구가 되지 않습니다.
이제 snapshot을 활용하여 recovery를 진행 합니다.
Recovery는 nodeos 시작을 할때 --snapshot [snapshot file] [blocks.log 파일] 의 옵션을 추가한 후 실행하시면 됩니다.
여기에서는 Docker로 nodeos를 실행하므로 run.sh 파일을 수정하여 아래 그림과 같이 적용 하였습니다. 그리고 Docker를 실행하면 Snapshot 파일과 Blocks.log파일을 이용하여 Index를 생성하기 시작하며, 일정 시간이 지나면 남은 블럭에 대해 동기화를 진행합니다.
index 생성이 완료되고 snapshot 되었던 시점과 log 파일의 최종 블럭 내용을 바탕으로 남은 블럭들(24609703 이후 블럭)에 대한 Replay를 추가로 진행 합니다. 최종적으로 log 이후의 블럭내용에 대해 p2p 동기화를 진행하면, 아래 그림과 같이 최종 완료됨을 확인할 수 있습니다.
Snapshot 후기
기존 백업들의 경우 data를 압축하여 백업하거나, lvm, brtfs, zfs와 같은 파일시스템의 snapshot을 활용할 경우 백업 데이터를 저장하기 위한 저장소, 저장하는 시간 동안의 EOS 노드 중단, 파일시스템 스냅샷에 대한 관리 및 타 서버로의 이전 불가 등의 여러가지 제약사항들이 있었고, 실제 복구하는데에도 상당한 수준의 시간이 소요되었습니다. 그만큼 이번에 업데이트 된 Snapshot 기능은 효율적인 nodeos를 운영을 가능하도록 하였습니다.
위의 snapshot 복구 과정에서 Last head block 동기화까지 총 걸린시간을 비교해보면 06:40 부터 06:51까지 총 11분이 걸렸고 nodeos를 정상화 할 수 있었습니다.
Snapshot 기능은 block.log 와 snapshot 데이터만 있다면 약 수십분의 시간안에 fullnode의 정상화를 기대할 수 있을 것이며, BP 및 개발자들의 여러 환경 구성에 상당한 도움이 될 것 입니다.
EOSeoul은 EOS 메인넷 런칭 이전부터 기술에 관한 컨텐츠들을 커뮤니티에 나누고, 런칭 이후 지금까지 다양한 기술밋업에 참가하고 있습니다. 앞으로도 여러가지 콘텐츠들을 통해 이오스 생태계에 기여하겠습니다. EOSeoul텔레그램에 가입하시면 EOS와 관련된 기술적인 토의를 나누실 수 있습니다.
감사합니다.
EOSeoul 팀 드림.
EOSeoul Contact
Telegram
Facebook
Youtube
Medium
Steemit
Github
Twitter
Bihu