Skip to content
isdnetworks
Go back

처리율 저하가 스톨은 아니다

(수정됨)

지갑 노드의 재스캔을 블록 구간 열셋으로 나눠 순차로 돌리고 있었다. 마지막 구간에서 처리율이 급락했다.

Table of contents

Open Table of contents

증상 — 처리율이 급락했다

블록 수를 비교하니 차이가 컸다.

앞선 구간들   30분당 수천 블록
이 구간       30분당 수백 블록

30분당 수백 블록 이라는 숫자가 스톨로 보여서 bitcoind 를 죽이려 했다.

kill 하기 전에 확인부터 하기로 했다. 먼저 프로세스가 살아 있는지 봤다.

pgrep -f 'bitcoind.*-datadir=/data/btc'
# 있음

pgrep -f 에 잡히니 죽은 것은 아니었다.

그런데 떠 있다는 것이 일하고 있다는 뜻은 아니다. 디스크 응답을 기다리며 멈춰 있어도 pgrep 에는 그대로 보이므로 생존 여부만으로는 갈리지 않았다.

판단 기준 — 갱신 시각과 처리 중 블록 높이

생존 말고 진행을 보는 데는 두 가지 방법이 있었는데, 로그 파일의 갱신 시각과 처리 중 블록 높이다. 먼저 갱신 시각을 봤다.

stat -c '%Y' /data/btc/debug.log

debug.log 의 mtime 이 몇 초 전이라 계속 쓰고 있다는 뜻이었다.

지금 무엇을 하고 있는지도 봤다.

tail -20 /data/btc/debug.log

tail 에 Still rescanning. At block 54xxxx. Progress=0.9x 가 찍히고 있었다. Bitcoin Core 0.17 지갑 코드는 이 줄을 60초마다 남기고, 0.17.0 릴리스 노트에는 rescanblockchain 의 진행률 보고를 고친 항목도 실려 있다.

잠시 뒤에 다시 tail 하니 그 블록 높이가 더 큰 값으로 바뀌어 있었다. 갱신 시각과 처리 중 블록 높이 둘이 함께 살아 있으면 그 작업은 돌고 있는 것이다.

원인 — 블록이 만든 단가 차이

왜 느린지는 구간별 블록의 성격에 있었다.

앞선 구간들  →  블록당 트랜잭션 몇 개에서 몇백 개
이 구간      →  블록당 트랜잭션 수천 개 (최근 1년)

재스캔은 블록의 모든 트랜잭션을 지갑 키와 대조하므로 블록당 비용이 트랜잭션 수에 비례한다.

Progress 값이 블록 수가 아니라 트랜잭션 양을 기준으로 오르는 것도 그래서다. 느려진 것이 아니라 이 구간의 정상 처리율이 원래 그것이었다.

주의 — 성급한 종료의 비용

내가 스톨의 근거로 삼은 신호가 무엇이었는지 정리했다.

[내가 본 신호]  블록 높이 증가폭
[실제 의미]     블록당 트랜잭션이 많으면 낮아진다

블록 높이 증가폭 이 스톨을 뜻하지 않고 구간이 다르면 정상 처리율 자체가 다르다.

죽이고 재시작했으면 이렇게 됐을 것이다.

재스캔 중단 (Rescan interrupted by shutdown request)
    ↓
재시작 → 그 구간을 처음부터 다시
    ↓
같은 속도로 다시 감  (원래 그 속도니까)
    ↓
또 느리다고 판단
    ↓
반복

원래 그 속도이므로 재시작해도 같은 판단이 반복된다.

거기에 중단된 구간의 진행분이 날아간다. 판별에 몇 초면 되는데 그것을 안 하고 죽이면 진행분을 날리고 같은 자리로 돌아온다. 확인 없이 죽이는 것 대신 tail 두 번을 골랐다. 이유는 두 번의 블록 높이 차이가 곧 판정이라서다.

재발 방지 — 구간별 단가로 추정

구간별 완주 시간 추정도 함께 고쳤다.

초기 구간  →  블록당 x초
최근 구간  →  블록당 y초  (x 의 몇십 배)

같은 블록 수여도 초기 구간 과 최근 구간 에 따라 걸리는 시간이 다르다.

전체를 하나의 속도로 추정하면 같은 오해가 매번 반복된다. 단가를 알아야 총량이 나오고 느려 보인다는 인상이 조급함이 만든 신호인지도 그때 갈린다.

정리


Share this post on:

Previous Post
자료가 없어져서 코드에서 되살렸다
Next Post
제한기가 워커 수만큼 곱해진다