조희대의 개인 사이트
개인적이지만 유용한

라즈베리 파이 4로 이더리움 풀 노드 돌리기

데스크탑 서버에서 이더리움 풀 노드를 돌리니까 서버가 느려졌다. 그래서 라즈베리 파이 4로 옮겨 볼까 한다. 이 프로젝트를 위해 우선 라즈베리 파이 4에 슬랙웨어 설치하기를 마쳤다.

1   Go 1.13 이상 버전 설치하기

go-ethereum을 컴파일하기 위해서는 Go 1.13 이상 버전이 필요하다. 슬랙웨어 ARM current의 기본 패키지에는 GCC Go 버전 1.12.2가 포함되어 있다. 그래서 sbopkg를 이용해서 google-go-lang 1.13.10을 컴파일해 봤다. 다음과 같은 오류와 함께 실패했다.

Building Go cmd/dist using /usr.
Building Go toolchain1 using /usr.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
runtime: failed mSpanList.remove span.npages=7 span=0xb6ea2ce8 prev=0x0 span.list=0xb6e8b570 list=0xb6e8b578
fatal error: mSpanList.remove

이미 비슷한 문제가 보고되어 있었다. 컴파일에 성공한 사람에 의하면 스왑이 작아서 그렇다는데 메모리 8GB에 스왑이 5GiB이면 총 메모리는 충분하다고 생각한다. Go의 공식 배포본을 다시 패키징하는 방법도 있지만 SARPi 프로젝트에서 슬랙웨어 ARM current를 위해 몇몇 패키지들을 이미 만들어 놨다. 어차피 SARPi에서 제공하는 부트 이미지를 쓰고 있으니 같은 팀에서 만든 Go 패키지를 설치하는 것도 좋은 생각이다.

su - # root로 로그인한다.

cd /tmp
wget https://sarpi.fatdog.eu/files/pkg/google-go-lang-1.14-armv7-1_slackcurrent_sp1.txz # Go 패키지를 내려받는다.
installpkg google-go-lang-1.14-armv7-1_slackcurrent_sp1.txz # Go 1.14를 설치한다.

# 파이에서 빠져 나간 다음 다시 일반 사용자로 로그인한다.
go version # 버전이 1.14인지 확인한다.

2   Go Ethereum 컴파일하기

Go Ethereum을 컴파일하자.

echo 'export GOPATH="$HOME/usr/local/lib/go"' >> ~/.bash_profile
. ~/.bash_profile

mkdir -p ~/usr/local/src
cd ~/usr/local/src

git clone https://github.com/ethereum/go-ethereum.git

make

cat<<'EOT'>> ~/.bash_profile
# Go Ethereum
export PATH="$PATH:$HOME/usr/local/src/go-ethereum/build/bin"
EOT

3   SSD 마운트하기

이제 SSD를 ~/.ethereum 디렉토리로 마운트한다.

su - # root로 로그인한다.

mkdir /home/sda1 # /dev/sda1에 있는 SSD를 마운트할 디렉토리를 생성한다.

mkdir /home/user/.ethereum # 일반 사용자 HOME 디렉토리에 이더리움 디렉토리를 생성한다.
chown user.users /home/user/.ethereum
chmod og-rx /home/user/.ethereum

cat<<'EOT'>> /etc/fstab # 마운트를 설정한다.
/dev/sda1             /home/sda1            ext4  defaults  1  2
/home/sda1/.ethereum  /home/user/.ethereum  none  bind      0  0
EOT

reboot # 재부팅한다.

4   Go Ethereum 실행하기

이제 geth를 실행한다.

screen -UDR # screen 안에서 geth를 실행하면 나중에 상태를 언제든지 확인할 수 있다.

geth # 일반 사용자로 geth를 실행한다. 기본적으로 fast 동기화 모드로 실행된다.
     # Ctrl-A d로 screen에서 분리한다.

5   블럭체인을 동기화하는 동안 콘솔 사용하기

다른 터미널에서 키스토어를 $HOME/.ethereum/keystore 디렉토리로 복사한 다음 geth를 실행한다.

cd ~/.ethereum/keystore
scp user@remote:.ethereum/keystore/* .

geth attach

6   메모리 문제 해결하기

위와 같이 하면 잘 될 줄 알았다. 그런데 한참을 동기화하던 geth가 다음과 같은 메모리 오류를 일으키며 죽어 버린다.

runtime: out of memory: cannot allocate 92274688-byte block (2401239040 in use)
fatal error: out of memory

92274688 바이트면 겨우 88MiB이고 왠지 모르게 훨씬 큰 괄호 안의 숫자는 2.2GiB인데 메모리를 할당할 수없단다. 8GB 기본 메모리에 5GiB 스왑까지 있는데 말이다. 여기를 보면 4GB 파이 4에서도 같은 문제가 있는 것 같다. 문득 내가 설치한 슬랙웨어 current가 64 비트가 아닐 거란 생각에 검색을 해 보니 SARPi64라는 프로젝트가 따로 있었다. 즉, 슬랙웨어 ARM current는 32 비트 버전밖에 없고 64 비트 커널과 모듈 위에 32 비트 OS를 돌릴 수는 있다는 뜻이다. 라즈베리 파이 4에 슬랙웨어를 설치할 때 64 비트 커널과 모듈을 설치해야 된다.

결국 SARPi64 프로젝트에서 64 비트 이미지를 내려받아서 새 SD 카드에 슬랙웨어 ARM current를 다시 설치했다. 테스트 결과 약 8 시간 정도는 무리없이 돌아갔다. 더 테스트를 해 봐야 된다.

참고문헌

이 칸을 비워 두세요.