5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【未解決】ARM環境でSymbolノードの同期中に「Too many open files」エラーで停止する

Last updated at Posted at 2025-12-02

はじめに

Oracle CloudのARM インスタンス(Ampere A1)でSymbolノードをセットアップしたところ、300万ブロックを超えたあたりでノードがダウンし、同期が進まなくなる問題に遭遇しました。

本記事では、この問題の調査過程と暫定的な対処法を共有します。なお、根本的な解決には至っておらず、現時点では未解決の問題として記録しています。

結論: エラー原因については未解決。でもfast-syncしたらOK

先に結論をお伝えすると、エラーの解決方法はまだわかってないです。
しかし、他の同期済みのノードから以下の2つのディレクトリを持ってくることである程度同期を済ませておくと問題なく動作します。
半年ぐらい回してみましたが、特にx86_64版のサーバーで動かす場合と差異はなく動いています。

回避策: 持ってくるディレクトリ

  • data/ - ブロックデータや状態情報
  • databases/ - MongoDBのデータ

結論はここまでで、以下は調査・試した内容のまとめです。

発生した事象

環境

項目 詳細
サーバー Oracle Ampere A1 Compute(ARM64)
OS Ubuntu Server 24.04
CPU 4 OCPU
RAM 24GB
Storage 250GB Block Storage
Node.js v24.11.1
symbol-bootstrap v1.1.12 linux-arm64
Docker v29.0.1
Docker Compose v2.40.3

エラーログ

同期処理中、320万ブロックあたりまで同期したタイミングで以下のエラーが発生しました:

$ docker compose logs -f node

node  | 2025-11-24 08:38:10.671622 <error> failed when connecting to 'node.example.com': Too many open files (cancelled? false)
node  | 2025-11-24 08:38:10.671671 <warning> unable to resolve and connect to static node node.example.com @ node.example.com:7900
node  | 2025-11-24 08:38:10.672102 <fatal> 
node  | thread: server catapult
node  | unhandled exception while running local node!
node  | Dynamic exception type: boost::wrapexcept<boost::filesystem::filesystem_error>
node  | std::exception::what: Failed to open file for writing: Input/output error [generic:5]: "/symbol-workdir/logs/catapult_server0000.log"
node  |
node  | Shutting down server

重要なのは1行目のここ: Too many open files

ログから読み取れる流れは以下の通りです:

  1. 同期処理中にpeerへの接続が増加
  2. ファイルディスクリプタ(FD)が枯渇
  3. ログファイルへの書き込みすら失敗
  4. ノードがクラッシュ

調査内容

試したこと1: コンテナ内プロセスのFD数を確認

まず、コンテナ内でどれだけのFDが使用されているかを確認しました。

PID=$(docker inspect -f '{{.State.Pid}}' node)

echo "FD Count:"; ls /proc/$PID/fd | wc -l
echo "FD Limit:"; grep FDSize /proc/$PID/status
echo "RSS:"; grep VmRSS /proc/$PID/status

結果:

FD Count: 4  
FDSize:   256  
VmRSS:    約3MB  

FDの上限が256しかありません。これは流石に不足してるかも?

試したこと2: OS全体のFD上限を確認

次に、OS側の制限を確認しました。

$ cat /proc/sys/fs/file-max
9223372036854775807

64bit整数の最大値が設定されており、OS側の制限ではないことがわかりました。

試したこと3: docker-compose.ymlの修正

OS側は問題なかったため、Docker Compose側でFD上限を引き上げることにしました。

target/docker/docker-compose.ymlのrest-gateway外のサービスにulimitsを追加:

# 抜粋
services:
  db:
    ulimits: #追加
      nofile:
        soft: 8192
        hard: 16384
  node:
    ulimits: #追加
      nofile:
        soft: 8192
        hard: 16384
  broker:
    ulimits: #追加
      nofile:
        soft: 8192
        hard: 16384

設定が反映されたか確認:

# node起動後に以下のコマンドをdocker-compose.ymlと同じディレクトリで実行
$ docker exec -it node bash -c "ulimit -n"
8192 # OK

一見すると、8192に上がっており問題なさそうに見えます。

しかし、問題は解決しなかった

FD上限を引き上げたにもかかわらず、同期は依然として途中で停止してしまいました。

調査を進めると、以下の状況が判明しました:

  • ulimit -nでは8192と表示される
  • しかし同期途中(今回は60万block程度)でなぜかblockが0にしまって以後起動しなくなる

どうやら、docker-composeのulimits設定がコンテナ全体に一貫して適用されないという挙動があるようです。これはcgroup v2 + systemd + Dockerの組み合わせで発生する既知の問題のようです。(これはAIによる推測で未確認)

現時点でのまとめ

わかったこと

  • ARMサーバー自体のスペックは十分(4 OCPU、24GB RAM)
  • OSのfile-maxは正常に設定されている
  • 問題はDocker側のFD管理にある
  • docker-composeのulimits指定がサービス単位で整合性が取れない
  • Symbolノードは複数プロセスが協調動作するため、この差異が致命的になる

未解決の課題

  • Docker daemonレベルでFDを強く制限している可能性
  • cgroup v2環境でのulimits設定の挙動
  • ARM + Docker + Symbolという組み合わせ特有の問題かどうか

根本的な解決には至っていませんが、原因の方向性は「DockerのFD管理まわり」が濃厚です。

アドベントカレンダーの日までに解決したら良かったのですが残念ながら間に合わなかったので今回はここまでです。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?