Elixir로 작성한 새로운 BitTorrent 트래커 구현
(github.com/Dahrkael)- ExTracker는 Elixir 기반의 새로운 BitTorrent 트래커 프로젝트임
- 높은 성능과 낮은 메모리 사용량을 기반으로 설계되었으며, 사실상 제로 셋업으로 바로 사용 가능함
- BitTorrent 프로토콜(BEP) 의 여러 확장 제안서 지원으로 다양성과 호환성 제공함
- HTTPS 지원, 디스크 백업, 운영 관리 기능 등 실무에 필요한 주요 기능을 포함함
- 현재는 산업적 사용에는 미완성 단계이지만 테스트 인스턴스가 실제 운영 중임
개요 및 프로젝트 중요성
ExTracker는 Elixir로 구현된 새로운 BitTorrent 트래커 오픈 소스 프로젝트로, 기존 트래커들에 비해 다음과 같은 이점을 제공함
- 최신 Erlang/Elixir 런타임 기반으로, 멀티코어를 모두 활용하는 고성능 구조를 가짐
- 대규모 피어 환경(약 1백만 피어당 200MB RAM)에서 낮은 메모리 사용량을 보장함
- 복잡한 사전 설정 없이 즉시 작동하는 제로 셋업 환경 제공
- 여러 BitTorrent Enhancement Proposal(BEP) 지원으로 최신 트래커 표준과 호환성 유지함
기존 트래커 대비 가볍고 효율적이며, Elixir 고유의 동시성 및 분산 환경 지원을 최대한 활용하여 동급 오픈 소스 프로젝트와 차별화됨
주요 기능 (Features)
- 고성능: 모든 CPU 코어 활용, 인메모리 저장소 사용
- 메모리 최적화: 피어 1백만 명당 약 200MB RAM 사용
- 제로 셋업: 아무런 추가 설정 없이 바로 실행 가능
지원하는 BitTorrent Enhancement Proposals (BEP)
- BEP 0: BitTorrent 프로토콜 명세 준수
- BEP 15: UDP 트래커 프로토콜 지원
- BEP 23: 압축된 피어 리스트 반환
- BEP 7: IPv6 트래커 확장
- BEP 24: 외부 IP 반환
- BEP 41: UDP 트래커 프로토콜 확장
- BEP 48: Scrape 트래커 확장 (부분 지원)
- BEP 52: BitTorrent 프로토콜 v2
- 일부 기능(BEP 27, 21, 31 등)은 미구현이거나, 계획 중임
- BEP 8(트래커 피어 난독화)은 지원하지 않음
기타 기능
- HTTPS 연결 지원
- 디스크 백업 (데이터 안전성 강화)
- (예정) Infohash 화이트리스트/블랙리스트 관리
- (예정) 피어 관리: 권한, 정기 정리, 퇴출 등
- (예정) 메트릭/지표 관리 및 GeoIP 활용
- WebTorrent는 지원 계획 없음
사용자/개발자의 제안사항을 Issue로 접수받음
실행 방법
-
소스 코드 직접 실행
- Erlang 및 Elixir 필요
- 저장소 클론 후 환경설정, 실행
-
릴리즈 방식
- 공식 릴리즈는 없지만 직접 빌드 및 배포 방식 지원
- 릴리즈 파일 복사, 환경설정 후 실행
-
Docker
- 공식 컨테이너 이미지 사용 가능
- docker-compose 예시 파일 제공
- 컨테이너 내부 설정은 환경 변수 이용 권장
저작권 및 라이선스
- Copyright (c) Dahrkael <dahrkael at outlook dot com>
- Apache License 2.0 하에 배포
- 라이선스 상세 내용은 저장소의 LICENSE 파일 참고
Hacker News 의견
-
OTP 중심의 설계를 기대했지만, 실제 코드는 거의 절차적으로 ETS나 Application 같은 ETS 기반 시스템을 매번 직접 다루는 방식임을 아쉬워함
작성자가 Elixir나 BEAM 언어에서 서비스 설계법을 배우고 싶다면 James Edward Gray와 Bruce Tate가 쓴 "Designing Elixir Systems with OTP" 그리고 Lance Halvorsen의 "Functional Web Development with Elixir, OTP, and Phoenix"를 참고서적으로 추천- 첫 시도에서는 OTP 스타일로 작성했지만, 이런 구체적 흐름에서는 확장성이 동일하게 나오는 것은 아니라는 점을 발견
토렌트 트래커는 결국 특수화된 데이터베이스이므로 최대한 빠르게 데이터 처리하는 것이 가장 중요한 목표라는 생각
그래도 추천해 준 책들 꼭 읽어볼 의향 표명
- 첫 시도에서는 OTP 스타일로 작성했지만, 이런 구체적 흐름에서는 확장성이 동일하게 나오는 것은 아니라는 점을 발견
-
C++ 개발자들이 Go와 Elixir를 좋아하는 특별한 뭔가가 있다고 생각
나 스스로도 여기에 해당
성능에 끌려 C++을 좋아하는 사람들이 Go나 Elixir의 멀티스레드 성능을 사랑하게 된다는 점을 이야기
멋진 프로젝트라는 긍정적 의견- C++ 개발자에 대해서는 잘 모르겠으나, Erlang/Elixir는 패턴 매칭 구현 덕분에 프로토콜 파싱에 굉장히 강점이 있다고 느낌
패턴 매칭이 대부분의 분기나 코드의 복잡도를 줄여줘서 코드가 훨씬 깔끔해지는 장점
'Let it crash' 철학 덕분에 대부분의 예외 케이스를 무시해도, 실제 문제가 발생하더라도 영향이 한 클라이언트에 국한됨을 확신
10년 넘게 Elixir로 배포된 앱에서 예기치 않은 다운타임을 경험한 적 없음
유지보수와 업데이트 외에는 항상 100% 가동률이었다는 점을 강조
클라이언트에게는 “Python이나 Go 대신 Elixir로 만든 서비스는 절대 죽지 않을 뿐만 아니라 멋진 대시보드도 제공”이라고 어필하며, 실제로 많은 이들이 바로 설득됨
Elixir처럼 struct와 enum, 그리고 함수 시그니처에서 패턴매칭을 지원하는 시스템 언어가 있다면 바람이라는 생각
- C++ 개발자에 대해서는 잘 모르겠으나, Erlang/Elixir는 패턴 매칭 구현 덕분에 프로토콜 파싱에 굉장히 강점이 있다고 느낌
-
나 역시 BT(비트토렌트) 학습 목적으로 Typescript로 비슷한 작업을 해본 경험
이후 Rust로 다시 구현하며 Rust도 학습
내 프로젝트 링크
나는 데이터베이스로 그냥 redis를 사용했지만, 상대방은 전부 메모리에 올려서 사용한다는 점이 흥미로움
이렇게 설계하면서 고민이나 재밌는 결정사항, 문제점 등이 있는지 궁금
참고로 redis 기반 내 솔루션은 announce를 여러 번 할 때 peer가 항상 무작위로 섞이지 않는 문제점이 있음- 내 경험에서는 인메모리 ETS를 쓰는 것이 최고의 선택
각 피어 데이터를 각각의 프로세스에서 동시적으로 읽고 쓸 수 있어 경합과 레이턴시가 최소임
유일하게 순차적인 부분은 새로운 swarm이 처음 만들어질 때뿐이며, 자주 발생하는 일이 아니라 괜찮음
아쉽게도 테이블에서 무작위로 행을 뽑는 네이티브 지원이 없어서 지금은 swarm 전체를 불러와서 무작위 부분집합을 직접 선택
관련 코드 예시
- 내 경험에서는 인메모리 ETS를 쓰는 것이 최고의 선택
-
멋진 프로젝트라 생각
과거에 나도 Elixir로 기본적인 트래커를 만들었던 경험이 있음
내 코드 링크- 흥미롭다는 생각
특히 private tracker로 구현한 이유가 궁금
- 흥미롭다는 생각
-
프로젝트 출시를 축하
opentracker와 비교해서 어떻게 작동하는지, 성능 등 자세한 정보 궁금- 작은 트래커라면 opentracker가 아마 더 빠르고 메모리도 덜 쓸 것
그러나 extracker는 CPU 코어 개수가 두 자릿수로 올라갈 때 진가를 발휘
아직은 제대로 된 벤치마크는 수행하지 않은 상태
- 작은 트래커라면 opentracker가 아마 더 빠르고 메모리도 덜 쓸 것
-
아주 잘 만든 프로젝트라는 칭찬
간단하게 조언하자면 IO.puts 대신 Logger로 옮기고, OTel 추가도 고려해보면 좋겠다는 의견-
여기에 동의
빌트인 Logger와 Telemetry 애플리케이션만 사용해도 충분하다는 의견
추후 opentelemetry나 다른 것도 Telemetry 훅에 쉽게 추가 가능
Logger documentation
Telemetry documentation -
선호하는 otel sink(메트릭을 어디로 보낼지)에 대한 질문
-
-
Elixir를 정말 좋아하는 마음
지금 멋진 notification 엔진을 Elixir로 개발 중
Elixir가 정말 탁월하다는 감탄- 멋지다는 호응
private 프로젝트인지 아니면 OSS(오픈소스)인지 궁금
Elixir 생태계에 더 나은 notification 엔진이 필요한 상황
- 멋지다는 호응
-
- 어떻게 시작하게 되었는지
-
참고한 프로젝트가 있는지
-
개발에 얼마나 걸렸는지
-
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 미지원 명시 -
HTTP 관련 Telemetry는 아직 ToDo 리스트에 있음
웹서버로 3rd-party 라이브러리를 사용하고 있으니 적절한 연동법을 더 고민 중
HTTPS를 사용하려면 :https_keyfile에 유효한 인증서 경로를 지정해야 함
현재로선 HTTPS를 원하면 트래커 앞단에 Caddy나 Nginx를 두는 것을 추천
certbot 연동도 계획 중이지만, 대부분의 토렌트 피어가 UDP를 쓰기 때문에 우선순위는 낮음
-
-
정말 멋진 프로젝트라는 칭찬
Elixir를 메인 언어로 쓸 생각이 있는지 질문-
Elixir가 주력 옵션 중 하나라는 답변
개인적으로 C++보다 확실히 더 즐겁게 일할 수 있을 것이라는 확신 -
본인은 아니지만, 9년 2개월 가까이 Elixir로 일해왔고 Rust와 Golang도 다룰 줄 안다는 자기소개
현 시점에서 누군가 채용 중인지 궁금함
-