Elixirで書かれた新しいBitTorrentトラッカー実装
(github.com/Dahrkael)- ExTrackerはElixirで作られたBitTorrentトラッカーで、現在は開発途中だが動作しており、全面的な業務利用にはまだ対応していないと明記されている
- 性能目標として、利用可能なすべてのコアを活用する高性能、インメモリストレージベースの動作、100万peerあたり約200MB RAMの使用量、追加設定なしで実行可能な構成を掲げている
- BitTorrent関連のBEPでは、BEP 0、BEP 15、BEP 23、BEP 7、BEP 21、BEP 24、BEP 41、BEP 48、BEP 52を実装しており、Private Torrentsなど一部は未実装または部分実装の状態
- HTTPS、ディスクデータベースのバックアップ、Dockerでの実行をサポートしており、WebTorrentはサポートせず、whitelist/blacklist、peer管理、metrics、GeoIPは部分実装の状態
- 実行方法は、ソースから直接実行、独自にリリースをビルド、Dockerイメージの実行の3種類で、コンテナでは
runtime.exsの代わりに環境変数で設定できる
ExTrackerの状態と目標
- ExTrackerは「The Bittorrent Tracker made in Elixir」として紹介されているBitTorrentトラッカー実装
- プロジェクトはWork In Progressの状態
- 全面的な業務利用にはまだ対応していないと明記されている
- 現時点では動作可能
- テストインスタンスが
extracker.dahrkael.net:6969で稼働しており、現在の機能が有効になっている
主な機能
- 性能と運用のしやすさを主要機能として挙げている
- 高性能: 利用可能なすべてのコアを活用
- インメモリストレージを使用
- メモリ使用量は100万peerあたり約200MB RAM
- Zero setup: 起動すればすぐ動作する形を目指している
BitTorrent BEP対応状況
- 実装状況の表記は
✅ Done、🔰 Partially、🔲 Not Yet、❌ Won't doに分かれる -
完了したBEP
- BEP 0: The BitTorrent Protocol Specification
- BEP 15: UDP Tracker Protocol
- BEP 23: Tracker Returns Compact Peer Lists
- BEP 7: IPv6 Tracker Extension
- BEP 21: Extension for partial seeds
- BEP 24: Tracker Returns External IP
- BEP 41: UDP Tracker Protocol Extensions
- BEP 48: Tracker Protocol Extension: Scrape
- BEP 52: The BitTorrent Protocol Specification v2
-
未実装または対象外のBEP
その他の機能と制限
- 完了した機能
-
HTTPSサポート
- ディスクデータベースのバックアップ
- サポートしていない機能
- WebTorrent
- 部分実装の機能
-
Infohash whitelist/blacklist
- peer管理: interval enforcement、cleanup、banningなど
-
Metrics
- GeoIPサポート: 統計およびpeer制限用
- 機能提案はIssuesで受け付けている
-
実行方法
-
ソースコードから直接実行
- この方法ではシステムにErlangとElixirがインストールされている必要がある
- リポジトリをクローンする
git clone https://github.com/Dahrkael/ExTracker.git && cd ExTracker- 必要に応じてconfig/runtime.exsを修正する
- 実行コマンドは
MIX_ENV=prod iex -S mix
-
リリースビルド
- 現時点で公式リリースビルドはなく、自分でリリースを作成して配布できる
- リポジトリをクローン後、OSに合わせてビルドする
- Linux:
MIX_ENV=prod mix release extracker - Windows:
MIX_ENV=prod mix release extrackerw - リリースファイルは
_build/prod/rel/extrackerフォルダに生成される - 他のマシンへ移す場合はOSとアーキテクチャが同一である必要がある
- 必要に応じて
releases/{VERSION}/runtime.exs設定を修正する - 実行コマンドは
bin/extracker start
-
Dockerでの実行
- 提供されているDockerイメージをそのまま実行できる
docker run ghcr.io/dahrkael/extracker:latest- docker-composeでも利用でき、composeファイルの例が提供されている
- コンテナ内では
runtime.exsを修正して設定調整するのが難しいため、環境変数でも設定できる - 環境変数の一覧はcomposeファイルの例で確認できる
ライセンス
- ExTrackerはApache License 2.0の条件で配布されている
- 詳細はリポジトリのLICENSE fileを参照
1件のコメント
Hacker News のコメント
OTP ファーストの設計を期待していたのですが、コードがほぼすべての処理で ETS や ETS ベースの Application を直接触っていて、手続き型に近く見えるのが残念です
Elixir や他の BEAM 言語で OTP によるサービス設計を学ぶなら、James Edward Gray と Bruce Tate の『Designing Elixir Systems with OTP』、Lance Halvorsen の『Functional Web Development with Elixir, OTP, and Phoenix』を見るとよいです
結局のところ、トレントトラッカーは特殊なデータベースに近く、データをできるだけ高速に処理することが最優先の目標です
それでも、その本は一度読んでみます
今では通信そのものというより、通信アプリケーションのような性質を持つソフトウェアに近く、Erlang の偉大さの半分が並行性と分散性、残り半分がエラー処理能力だとすれば、OTP フレームワークはその「3つ目の半分」と言えます
https://learnyousomeerlang.com/what-is-otp
単一サーバー構成なら ETS が 100% 正しい選択で、水平スケールはできないでしょうが、垂直スケールは非常にうまくいくはずです
いずれにせよ大半は YAGNI である可能性が高いです
追加の GenServer や
gen_statemがうまくハマる場合もあるでしょうが、Elixir と Phoenix の多くの用途では、派手なアーキテクチャ上の選択までは必要ありませんランタイムがすでに十分に派手なことを代わりにやってくれるからです
ETS は OTP に組み込まれているのに、ETS を使うことがなぜ OTP ファーストではないのか分かりません
ETS を使うことの何が問題なのかもよく分からず、単なるインメモリストアにすぎません
コードをざっと見ましたが、手続き型スタイルに近いとは感じませんでした
よくできています。
IO.putsの代わりに Logger へ移行し、OTel の追加も検討するとよさそうです[0] https://hexdocs.pm/logger/1.18.4/Logger.html
[1] https://hexdocs.pm/telemetry/readme.html
Elixir は本当に良いです。今 Elixir で素晴らしい 通知エンジンを作っているのですが、本当に優れています
Elixir には、より良い通知エンジンが本当に必要です
リリースおめでとうございます。opentracker と比べてどのように動作するのか、詳しく教えてもらえるか気になります
性能のような部分にとても関心があります
ExTracker が真価を発揮するのは、コア数が2桁に上がり始めるあたりです
ただし、きちんとしたベンチマークはまだ行う必要があります
良さそうです。後で確認してみます
数年前に Elixir で基本的なトラッカーを作ったことがあり、コードはこちらにあります: https://github.com/aalin/mr_torrent
興味深いです。BitTorrent をもっと学ぶために TypeScript で似たものを作り、Rust を学ぶために Rust で作り直しました: https://github.com/ckcr4lyf/kiryuu
ただ、私はデータベースとして単に Redis を使いました。このプロジェクトはデータベース全体がメモリ上にあるようですが、その際に行った興味深い設計判断や直面した問題があったのか気になります
私の Redis による解法は、後続の announce でピアをランダム化していないようなので、あまり良くありません
各ピアのデータをそれぞれのプロセスで同時に読み書きできるため、競合とレイテンシが最小化されます
逐次処理される唯一の部分は新しい swarm が最初に作成されるときですが、頻繁には起きないので問題ありません
残念ながら、テーブルから任意の行を直接取得するネイティブサポートがないため、今は swarm 全体を取得してからランダムな部分集合を選んでいます: https://github.com/Dahrkael/ExTracker/blob/master/lib/ex_tra...
DHT と PEX が何なのか説明してもらえるとありがたいです。"tracker PEX" で検索するのが難しいです
そのため、もはや中央の場所や公開トラッカーは必要ありません
素晴らしいです。Elixir を本業で使いたいのか気になります
Rust と Go も分かります。採用中ですか?
どうやって始めたのか、他のプロジェクトを参考にしたのか、どれくらい時間がかかったのか、qBittorrent のようなものと比べて機能がどれくらい動くと見ているのか気になります
他のトラッカーのコードもざっと見ましたが、たいていは複雑すぎるか単純すぎるかで、あまり役に立ちませんでした
今のところ、3か月間の 復讐的就寝先延ばしで作った成果です
これは qBittorrent のようなクライアントではありませんが、将来的には seedbox 向けクライアントプロジェクトのアイデアはあります
試してみましたが、HTTPS を動作させることができませんでした
コンソールには
04:43:20.160 [warning] invalid 'event' parameter: size: 6 value: "paused"がずっと出ていますが、動作はしているようですHTTP の統計も見たかったのですが、UDP でも構いません。ただし私は UDP をオフにしています
"paused"イベントは BEP 21 の一部ですクライアントがまだ完了状態ではないものの、これ以上ダウンロードしないことをトラッカーに知らせるときに送ります
たとえば、ユーザーがトレント内の一部ファイルだけを欲しい場合です
プロジェクトの README を見ると、BEP 21 サポートは未実装の状態です
Web サーバーにサードパーティライブラリを使っているので、正しい方法をまだ把握する必要があります
HTTPS を使うには
:https_keyfileに有効な証明書パスを指定する必要がありますが、現時点では HTTPS が必要ならトラッカーの前段に Caddy や Nginx を置くことを推奨しますcertbot 統合も計画はありますが、ほとんどのトレントピアは UDP を使うため、優先度は高くありません