搭建混合式全节点的一点记录与心得
首先感谢@ety001对本文的大力支持与帮助,欢迎大家踊跃投他的见证人票。
大家都知道,steem的全节点非常耗资源,随便就几百G的内存,让大多数人望而却步。
然而我们有办法可以搭建一个轻量化的全节点,通过jussi让部分插件转移到别的节点运行。这样可以大大减少服务器硬件需求,并且也可以有效的为目前仅有的几个全节点分担负载。
比如Account History Api这个插件,需要非常大的硬盘空间,我们可以选择不加载这个。或者建全节点的朋友,可以把这个丢去备机运行。
步骤一
首先我们要建设一个见证人节点。教程可以看我之前的文章:https://steem.buzz/hive-180932/@maiyude/3m5gje
如果是从头开始建设的朋友,在修改config.ini这步,在打开插件的目录修改成这样:
plugin = webserver witness condenser_api network_broadcast_api account_by_key database_api
plugin = block_api rc_api account_by_key_api json_rpc market_history_api follow_api
当然你也可以根据自己的情况,少打开一些插件,让别的节点来帮忙分流。
如果已经建设好了普通的节点的朋友,可以直接修改修改config.ini,也改成这样。
plugin = webserver witness condenser_api network_broadcast_api account_by_key database_api
plugin = block_api rc_api account_by_key_api json_rpc market_history_api follow_api
这步骤打开了block_api,rc_api,account_by_key_api, json_rpc ,market_history_api follow_api等插件。这些插件经过不严谨的测试,打开不需要重新replay。
打开后./run.sh restart重启节点即可。如果报错,试试减少几个插件后重试。
步骤二
修改run.sh
找到这行 : ${PORTS="2001"}
修改为
: ${PORTS="2001,8090,8091"}
这步骤是添加了监听8090,8091两个端口,两个端口分别是webserver-ws和webserver-http的端口。
步骤三:搭建jussi
参考文档:https://developers.steem.io/services/jussi
https://github.com/steemit/jussi
jussi 是全节点的最前端的缓存层,负责用 JSON 把后端数据源数据格式统一,且提供缓存功能,提高吞吐量。
这步骤是重头戏,混合式全节点的关键就是让部分服务通过jussi转移到别的节点运行。
- 1.安装docker-compose
pip install docker-compose
- 2.下载jussi目录
git clone https://github.com/steemit/jussi.git
- 3.pull镜像或者build
建议直接pull镜像,想要自己build请看上面的官方参考文档
docker pull steemit/jussi:latest
- 4.创建 docker-compose.yml
在 jussi/ 目录下创建 docker-compose.yml,内容如下
version: "3.3"
services:
jussi:
restart: "always"
image: "steemit/jussi:latest"
ports:
- "8080:8080"
environment:
JUSSI_UPSTREAM_CONFIG_FILE: /app/config.json
JUSSI_REDIS_URL: redis://redis1:6379
volumes:
- ./config.json:/app/config.json
redis1:
restart: "always"
image: "redis:latest"
volumes:
- ./redis1:/data
注意: 确认下你目前机器是否有程序占用 8080 端口,如果有占用,自行修改端口号
- 5.创建配置文件
在 jussi/ 目录下,新建 config.json 文件。然后进行配置,此步骤让你决定什么插件本地节点运行,什么插件让别的节点运行。
首先我们来看看有什么插件,我们参考官方的api文档:
https://developers.steem.io/apidefinitions/
可以看见有N大类和N小类,我们来看看具体有些啥。
Condenser Api
broadcast_block broadcast_transaction broadcast_transaction_synchronous find_proposals get_account_bandwidth get_account_count get_account_history get_account_references get_account_reputations get_account_votes get_accounts get_active_votes get_active_witnesses get_block get_block_header get_blog get_blog_authors get_blog_entries get_chain_properties get_comment_discussions_by_payout get_config get_content get_content_replies get_conversion_requests get_current_median_history_price get_discussions_by_active get_discussions_by_author_before_date get_discussions_by_blog get_discussions_by_cashout get_discussions_by_children get_discussions_by_comments get_discussions_by_created get_discussions_by_feed get_discussions_by_hot get_discussions_by_promoted get_discussions_by_trending get_discussions_by_votes get_dynamic_global_properties get_escrow get_expiring_vesting_delegations get_feed get_feed_entries get_feed_history get_follow_count get_followers get_following get_hardfork_version get_key_references get_market_history get_market_history_buckets get_next_scheduled_hardfork get_open_orders get_ops_in_block get_order_book get_owner_history get_post_discussions_by_payout get_potential_signatures get_reblogged_by get_recent_trades get_recovery_request get_replies_by_last_update get_required_signatures get_reward_fund get_savings_withdraw_from get_savings_withdraw_to get_state get_tags_used_by_author get_ticker get_trade_history get_transaction get_transaction_hex get_trending_tags get_version get_vesting_delegations get_volume get_withdraw_routes get_witness_by_account get_witness_count get_witness_schedule get_witnesses get_witnesses_by_vote list_proposal_votes list_proposals lookup_account_names lookup_accounts lookup_witness_accounts verify_account_authority verify_authority
Bridge
account_notifications get_community get_ranked_posts list_all_subscriptions list_community_roles
Account By Key Api
get_key_references
Account History Api
enum_virtual_ops get_account_history get_ops_in_block get_transaction
Block Api
get_block get_block_header
Database Api
find_account_recovery_requests find_accounts find_change_recovery_account_requests find_comments find_decline_voting_rights_requests find_escrows find_limit_orders find_owner_histories find_proposals find_savings_withdrawals find_sbd_conversion_requests find_smt_contributions find_smt_token_emissions find_smt_tokens find_vesting_delegation_expirations find_vesting_delegations find_votes find_withdraw_vesting_routes find_witnesses get_active_witnesses get_config get_current_price_feed get_dynamic_global_properties get_feed_history get_hardfork_properties get_nai_pool get_order_book get_potential_signatures get_required_signatures get_reward_funds get_transaction_hex get_version get_witness_schedule list_account_recovery_requests list_accounts list_change_recovery_account_requests list_comments list_decline_voting_rights_requests list_escrows list_limit_orders list_owner_histories list_proposal_votes list_proposals list_savings_withdrawals list_sbd_conversion_requests list_smt_contributions list_smt_token_emissions list_smt_tokens list_vesting_delegation_expirations list_vesting_delegations list_votes list_withdraw_vesting_routes list_witness_votes list_witnesses verify_account_authority verify_authority verify_signatures
Debug Node Api
debug_generate_blocks debug_generate_blocks_until debug_get_hardfork_property_object debug_get_json_schema debug_get_witness_schedule debug_has_hardfork debug_pop_block debug_push_blocks debug_set_hardfork
Follow Api
get_account_reputations get_blog get_blog_authors get_blog_entries get_feed get_feed_entries get_follow_count get_followers get_following get_reblogged_by
Jsonrpc
get_methods get_signature
Market History Api
get_market_history get_market_history_buckets get_order_book get_recent_trades get_ticker get_trade_history get_volume
Network Broadcast Api
broadcast_block broadcast_transaction
Rc Api
find_rc_accounts get_resource_params get_resource_pool
Reputation Api
get_account_reputations
Rewards Api
simulate_curve_payouts
Tags Api
get_active_votes get_comment_discussions_by_payout get_content_replies get_discussion get_discussions_by_active get_discussions_by_author_before_date get_discussions_by_blog get_discussions_by_cashout get_discussions_by_children get_discussions_by_comments get_discussions_by_created get_discussions_by_feed get_discussions_by_hot get_discussions_by_promoted get_discussions_by_trending get_discussions_by_votes get_post_discussions_by_payout get_replies_by_last_update get_tags_used_by_author get_trending_tags
Transaction Status Api
find_transaction
Witness Api
get_account_bandwidth get_reserve_ratio
密密麻麻有好几百项目,这每一个大类,以每一个细分子类,都可以分别设定由不同的节点运行。
首先是全局设置
比如我要让Account History Api这个大类让api.steemit.com运行,我可以这样设置
{
"urls":[
["appbase", "http://127.0.0.1:8091"]#这个是全局设置,如果没有指定的,全部由这个url执行
[""appbase.account_history_api","https://api.steemit.com"]
]
}
我们也可以细分一下,比如condenser_api这个大类我大部分想要本机运行,其中的小细分子项目get_account_history我想要让api.steemit.com运行,我可以这样设置(http://127.0.0.1:8091是我本机IP)
{
"urls":[
["appbase.condenser_api", "http://127.0.0.1:8091"],
["appbase.condenser_api.get_account_history", "https://api.steemit.com"]
]
}
大体就是这样,有好几百项,自己考虑什么想要自己运行,什么分流给别人,下面放上我的设置。
其中http://127.0.0.1:8091是本地容器内的IP,请自己找自己steemd容器内的IP是什么,找不到也可以直接打公网IP:
{
"limits": {
"blacklist_accounts": [
"non-steemit"
]
},
"upstreams": [
{
"name": "steemd",
"translate_to_appbase": true,
"urls": [
[
"steemd",
"http://127.0.0.1:8091"
]
],
"ttls": [
[
"steemd",
3
],
[
"steemd.login_api",
-1
],
[
"steemd.network_broadcast_api",
-1
],
[
"steemd.follow_api",
10
],
[
"steemd.market_history_api",
1
],
[
"steemd.database_api",
3
],
[
"steemd.database_api.get_block",
-2
],
[
"steemd.database_api.get_block_header",
-2
],
[
"steemd.database_api.get_content",
1
],
[
"steemd.database_api.get_state",
1
],
[
"steemd.database_api.get_state.params=['/trending']",
30
],
[
"steemd.database_api.get_state.params=['trending']",
30
],
[
"steemd.database_api.get_state.params=['/hot']",
30
],
[
"steemd.database_api.get_state.params=['/welcome']",
30
],
[
"steemd.database_api.get_state.params=['/promoted']",
30
],
[
"steemd.database_api.get_state.params=['/created']",
10
],
[
"steemd.database_api.get_dynamic_global_properties",
1
]
],
"timeouts": [
[
"steemd",
5
],
[
"steemd.network_broadcast_api",
0
]
]
},
{
"name": "appbase",
"urls": [
["appbase", "http://127.0.0.1:8091"],
["appbase.condenser_api", "http://127.0.0.1:8091"],
["appbase.account_history_api", "https://api.steemit.com"],
["appbase.condenser_api.get_account_history", "https://api.steemit.com"],
["appbase.condenser_api.get_ops_in_block", "https://api.steemit.com"],
["appbase.transaction_status_api", "https://api.steemit.com"],
["appbase.rewards_api,", "https://api.steemit.com"],
["appbase.witness_api,", "https://api.steemit.com"],
["appbase.reputation_api", "https://api.steemit.com"],
["appbase.follow_api", "http://127.0.0.1:8091"],
["appbase.tags_api", "https://api.steemit.com"]
],
"ttls": [
[
"appbase",
-2
],
[
"appbase.block_api",
-2
],
[
"appbase.database_api",
1
]
],
"timeouts": [
[
"appbase",
3
],
[
"appbase.chain_api.push_block",
0
],
[
"appbase.chain_api.push_transaction",
0
],
[
"appbase.network_broadcast_api",
0
],
[
"appbase.condenser_api.broadcast_block",
0
],
[
"appbase.condenser_api.broadcast_transaction",
0
],
[
"appbase.condenser_api.broadcast_transaction_synchronous",
0
],
[
"appbase.condenser_api.get_ops_in_block.params=[2889020,false]",
20
],
[
"appbase.account_history_api.get_ops_in_block.params={\"block_num\":2889020,\"only_virtual\":false}",
20
]
]
}
]
}
我的设置是condenser_api,follow_api大部分本机运行,其中子项目get_account_history和get_ops_in_block交给api.steemit.com。
account_history_api,transaction_status_api,rewards_api,witness_api,reputation_api,tags_api这些插件我的节点没打开,全部交给api.steemit.com。
上面那段太长,单独抽出这部分设置帮助理解:
[
["appbase", "http://127.0.0.1:8091"],
["appbase.condenser_api", "http://127.0.0.1:8091"],
["appbase.account_history_api", "https://api.steemit.com"],
["appbase.condenser_api.get_account_history", "https://api.steemit.com"],
["appbase.condenser_api.get_ops_in_block", "https://api.steemit.com"],
["appbase.transaction_status_api", "https://api.steemit.com"],
["appbase.rewards_api,", "https://api.steemit.com"],
["appbase.witness_api,", "https://api.steemit.com"],
["appbase.reputation_api", "https://api.steemit.com"],
["appbase.follow_api", "http://127.0.0.1:8091"],
["appbase.tags_api", "https://api.steemit.com"]
]
步骤四,启动测试
进入 jussi/ 目录后,执行
docker-compose up -d
即可启动。启动后,8080 端口即为 jussi 的服务端口。后续可配合 nginx 进行反向代理加上证书等等。
然后大家可以使用你的公网IP:8080测试一下。
比如我的:http://62.125.25.20:8080
浏览器打开显示这样的信息就是配置成功了,可以使用各种api测试测试。
其他参考命令
以下命令需要在 jussi/ 目录下执行
- 停止并卸载容器和网络
docker-compose down
- 查看相关运行容器
docker-compose ps
- 查看log
查看log,并且截取最后100行,且持续输出。容器名不填就是全部容器
- 查看log
docker-compose logs -f --tail 100 [容器名]
通过以上步骤,一个普通的见证人节点就升级为混合式全节点了。
我用来测试的机器配置是10G内存,700G硬盘,成功运行。
运行后内存占用大约2G,硬盘空间330G,仅供各位参考。
感谢你的阅读,steems.top是@maiyude开发的网页钱包,我是中文区见证人之一,欢迎通过 SteemConnect 来给我投票,或者打开 https://steemitwallet.com/~witnesses 页面,输入 maiyude 进行投票。
中文区的见证人目前有:
支持一下他们(按字母顺序),一人可以有30票:
Thank you for reading. I'm a witness. I would really appreciate your witness vote! You can vote by SteemConnect. Or open https://steemitwallet.com/~witnesses page, input maiyude to vote.
分擔全節點負荷,一大創舉,讚👍🏽
支持鱼哥👍5⃣👏
你好程序員
这个特别详细,收藏学习下!