EOS开发者研讨会
(感谢eospark分享)
节点的搭建
编译
- 切换到对应的 tag 然后再编译,不能直接编译 master
- 设置 -s 资源符号
./eosio_build.sh -s EOS
- 后续的编译进⼊ build ⽬录进⾏增量编译,如果再次运⾏ eosio_build.sh 会导致全量编译
- 使⽤不同操作系统的备份⽂件(blocks、state)的话,在编译时需要修改下⾯的代码来绕过检测:
//vim libraries/chainbase/src/chainbase.cpp +72
if( !env.first || !( *env.first == host_env ) ) {
改成
if( false ) {
编译⾃定义插件时,需要指定环境变量:
LOCAL_CMAKE_FLAGS="-
DEOSIO_ADDITIONAL_PLUGINS=${HOME}/eos/plugins/eos_zmq_plugin"
./eosio_build.sh -s EOS
-
绕过 mongo 插件的编译。我在 MAC 上编译遇到下⾯的问题:
修改 eosio_build.sh 第 284 ⾏(tag:v1.7.0):
将 -DBUILD_MONGO_DB_PLUGIN 改为 false
- 有些低配置的机器(4c8g)编译源码时会出错,⼀般都是因为 eosio_build.sh 编译的时候都是并⾏编译,CPU 吃紧后就会导致编译失败。这个时候 cd 进 build ⽬录,然后执⾏ make -j1 可以编译成功。
配置
- 节点配置我⼀般 这⾥ 取 (https://validate.eosnation.io/mainnet/reports//endpoints.txt)
- 为了加快追主⽹区块的速度,可以在配置⾥加上 trusted-producer 项,可以跳过⼀些交易的合法性验证,加快同步速度(这个配置对加快区块重放同样⽣效)。
- chain-state-db-size-mb 设置⼤⼀点,我⼀般设置成 8192
- 如果不接受交易推送,即不⽀持 push_transaction,可以设置 read-mode = read-only
- 启动 快照节点备份 需要先删除本地的 blocks 和 state ⽂件夹,然后执⾏:
# 本命令启动完成后,⽴即 cleos get info 是不会返回任何东⻄的,⼀般要等个⼤约 3分钟才会正常返回
./start.sh --snapshot snapshots/snapshot0202490f9adbf613b2f5b426c813bc4ff582f9cd38995b93896ef108e78c8b96.bin
节点的维护
搭过 EOS 节点的同学应该都知道其中的痛苦:
- 追不上区块⾼度
- 数据极其脆弱,容易 replay
- 节点不稳定,经常卡死
- 节点各个版本接⼝的增删改
追不上区块⾼度
原因⽐较复杂,⽹络状况、节点版本、节点配置⽂件等因素都会影响到同步速度。节点对⽹速上限要求不⾼,只要稳定就⾏。
解决⽅案:
- 定期更新配置⽂件的 endpoint 信息,剔除经常报错重连的节点
- 更新最新的 nodeos 版本
节点不稳定
节点从 0 点开始,每隔 4 个⼩时就会卡顿⼏分钟,最近观察是没隔⼀个⼩时就会卡顿。或者就是莫名其妙出现节点卡顿现象。这种问题基本⽆解,有些是插件内存泄漏或者节点本身有 bug,只能等官⽅慢慢修复。
解决⽅案:
- 部署多个节点,做负载均衡
- 重启⼤法。就 EOSPark ⽬前观察的经验,⼀般节点⻓时间运⾏⼤约⼀周左右就会出现很多莫名其妙的诡异问题,⼀般都是重启下就正常了。
节点版本的接⼝变动
节点很多版本之间接⼝是不兼容的,⽐如在 1.4.x 之前的版本创建新账户的命令字叫 newaccount ,之前⾥⾯新账户的参数名叫 name ,但是在 1.4.x 变成了 newact ,然⽽在 1.5.x 之后这个参数名⼜改回name 了。
还⽐如就是查询 global 表时,返回的字段⾥有⼀个叫 last_pervote_bucket_fill 字段,之前这个字段是⼀个纯时间戳数字的字符串,但是在最近的⼀次系统合约的部署后,这个字段变成 UTC 格式的时间了。
还有很多字段本来是返回的数字,后来估计是考虑到溢出问题,换成字符串了。
再举⼀个接⼝变动的例⼦,之前有⼀个叫 get_code 的接⼝,但是后来这个接⼝被弃⽤了,⽽官⽅的版本更新⽇志上却没有提到这⼀点。
解决⽅案:
- 关注代码更新记录,升级新版本前阅读更新说明
- 灰度升级
节点微分叉
除去⽹络因素不管,当相邻两个出块节点的物理位置相隔太远时会有⼤概率出现区块回滚现象,⽐如阿根廷的节点和北京的节点。即便两个出块机器直连⼀根⽹线,互相 ping 对⽅也要花 130+ms 的时间。
⽽ EOS 必须在 500ms 内出⼀个块……
解决⽅案:节点之间做 heartbeat,按最近延迟的节点顺序出块
节点 replay
现在的节点确实很容易就 replay,⼀个全节点数据⼀旦 replay,照⽬前的量预计⾄少两周,如果选择从头同步数据则需要⼀个⽉,⾮常的痛苦。依照我现在的经验,⼀般造成脏数据导致 replay 的有以下原因:
- 磁盘满了
- kill -9
- 没有正常暂停节点的情况下重启机器
- 没有正常暂停节点的情况下运⾏ eosio_build.sh 升级节点,会⼤概率导致脏数据
- 其他业务抢占 cpu 迫使节点服务停掉
解决⽅案:定时做节点数据的全量备份(blocks 和 state ⽂件)
全量备份和快照备份
全量备份(带 state)可以直接就地启动,⽆需重放,拎包⼊住。就⽬前来看,blocks ⽂件夹有220G,state ⽂件夹有 20~60G。缺点是备份和恢复复杂。
快照备份⼀般都 200~300M,备份恢复⾮常简单⽅便。缺点是获取不到历史的区块数据。假如你的快照数据是从区块⾼度为 100 的时候做的,那么⽤ cleos get block 99 就会返回错误。所以快照备份就⾮常适合不关⼼历史数据的业务场景。