搭建混合式全节点的一点记录与心得

in STEEM CN/中文6 years ago (edited)

首先感谢@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/ 目录下执行

    1. 停止并卸载容器和网络
docker-compose down
    1. 查看相关运行容器
docker-compose ps
    1. 查看log
      查看log,并且截取最后100行,且持续输出。容器名不填就是全部容器
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.

Sort:  

分擔全節點負荷,一大創舉,讚👍🏽

支持鱼哥👍5⃣👏

你好程序員

这个特别详细,收藏学习下!

Coin Marketplace

STEEM 0.04
TRX 0.32
JST 0.088
BTC 61185.27
ETH 1644.21
USDT 1.00
SBD 0.38