Nova implementação de tracker BitTorrent escrita em Elixir
(github.com/Dahrkael)- ExTracker é um novo projeto de tracker BitTorrent baseado em Elixir
- Foi projetado com foco em alto desempenho e baixo uso de memória, e na prática pode ser usado imediatamente com configuração praticamente zero
- Oferece diversidade e compatibilidade por meio do suporte a várias propostas de extensão do protocolo BitTorrent (BEP)
- Inclui recursos importantes para uso prático, como suporte a HTTPS, backup em disco e funcionalidades operacionais de administração
- No momento, ainda está em um estágio incompleto para uso industrial, mas uma instância de teste já está em operação real
Visão geral e importância do projeto
ExTracker é um novo projeto open source de tracker BitTorrent implementado em Elixir, que oferece as seguintes vantagens em relação aos trackers existentes
- Baseado no runtime moderno de Erlang/Elixir, com uma arquitetura de alto desempenho que utiliza todos os múltiplos núcleos
- Garante baixo uso de memória em ambientes com grande volume de peers (cerca de 200MB de RAM para aproximadamente 1 milhão de peers)
- Oferece um ambiente de configuração zero que funciona imediatamente sem necessidade de configuração prévia complexa
- Mantém compatibilidade com os padrões mais recentes de tracker por meio do suporte a várias BitTorrent Enhancement Proposals (BEP)
Em comparação com trackers existentes, ele é leve e eficiente e se diferencia de projetos open source equivalentes ao aproveitar ao máximo o suporte nativo do Elixir a concorrência e ambientes distribuídos
Principais recursos (Features)
- Alto desempenho: uso de todos os núcleos da CPU, armazenamento em memória
- Otimização de memória: cerca de 200MB de RAM por 1 milhão de peers
- Configuração zero: pode ser executado imediatamente sem qualquer configuração adicional
BitTorrent Enhancement Proposals (BEP) suportadas
- BEP 0: conformidade com a especificação do protocolo BitTorrent
- BEP 15: suporte ao protocolo de tracker UDP
- BEP 23: retorno de lista de peers compactada
- BEP 7: extensão de tracker IPv6
- BEP 24: retorno de IP externo
- BEP 41: extensão do protocolo de tracker UDP
- BEP 48: extensão Scrape de tracker (suporte parcial)
- BEP 52: protocolo BitTorrent v2
- Alguns recursos (BEP 27, 21, 31 etc.) ainda não foram implementados ou estão planejados
- BEP 8 (ofuscação de peers no tracker) não é suportada
Outros recursos
- Suporte a conexões HTTPS
- Backup em disco (maior segurança dos dados)
- (Planejado) gerenciamento de whitelist/blacklist de infohash
- (Planejado) gerenciamento de peers: permissões, limpeza periódica, expulsão etc.
- (Planejado) gerenciamento de métricas/indicadores e uso de GeoIP
- Não há planos de oferecer suporte a WebTorrent
Sugestões de usuários/desenvolvedores são aceitas via Issue
Como executar
- Executar diretamente a partir do código-fonte
- Erlang e Elixir são necessários
- Clonar o repositório, configurar o ambiente e executar
- Modo release
- Não há releases oficiais, mas há suporte para build e distribuição manual
- Copiar os arquivos de release, configurar o ambiente e executar
- Docker
- É possível usar a imagem oficial de contêiner
- Um arquivo de exemplo
docker-composeé fornecido - Recomenda-se usar variáveis de ambiente para a configuração dentro do contêiner
Direitos autorais e licença
- Copyright (c) Dahrkael <dahrkael at outlook dot com>
- Distribuído sob a Apache License 2.0
- Para detalhes da licença, consulte o arquivo LICENSE no repositório
1 comentários
Comentários do Hacker News
Achei uma pena, porque eu esperava um design mais centrado em OTP, mas o código real acaba lidando de forma quase procedural, manualmente, com sistemas baseados em ETS como ETS e Application o tempo todo.
Se o autor quiser aprender a projetar serviços em Elixir ou nas linguagens BEAM, recomendo como referência "Designing Elixir Systems with OTP", de James Edward Gray e Bruce Tate, e "Functional Web Development with Elixir, OTP, and Phoenix", de Lance Halvorsen.
No fim, um tracker de torrent é um banco de dados especializado, então penso que o objetivo mais importante é processar os dados o mais rápido possível.
Mesmo assim, pretendo com certeza ler os livros recomendados.
Acho que existe alguma coisa especial que faz desenvolvedores C++ gostarem de Go e Elixir.
Eu mesmo me encaixo nisso.
Quem gosta de C++ por causa de desempenho acaba se apaixonando pelo desempenho multithread de Go ou Elixir.
Projeto muito legal.
Pattern matching reduz a maior parte das ramificações e da complexidade do código, então tudo fica muito mais limpo.
Por causa da filosofia de "Let it crash", mesmo ignorando a maioria dos casos excepcionais, dá para ter confiança de que, se um problema real acontecer, o impacto ficará limitado a um único cliente.
Em mais de 10 anos com apps em Elixir em produção, nunca tive um downtime inesperado.
Fora manutenção e atualizações, a disponibilidade sempre foi de 100%.
Para clientes, eu costumo vender a ideia como: “um serviço feito em Elixir em vez de Python ou Go não só nunca cai, como ainda entrega dashboards incríveis”, e na prática muita gente se convence na hora.
Seria ótimo se existisse alguma linguagem de sistemas que, como Elixir, desse suporte a
struct,enume pattern matching nas assinaturas de função.Eu também já fiz algo parecido em Typescript para aprender BT (BitTorrent).
Depois reimplementei em Rust para aprender Rust também.
Link do meu projeto
No meu caso eu simplesmente usei redis como banco de dados, mas achei interessante que você usa tudo em memória.
Queria saber se houve alguma preocupação, decisão interessante ou problema nessa arquitetura.
Aliás, na minha solução baseada em redis há o problema de que, ao fazer vários announces, os peers nem sempre são embaralhados aleatoriamente.
Os dados de cada peer podem ser lidos e escritos concorrentemente por processos diferentes, então a contenção e a latência ficam mínimas.
A única parte realmente sequencial é quando um swarm novo é criado pela primeira vez, e isso não acontece com frequência, então tudo bem.
Infelizmente não existe suporte nativo para escolher linhas aleatórias de uma tabela, então no momento eu carrego o swarm inteiro e seleciono manualmente um subconjunto aleatório.
Exemplo de código relacionado
Acho o projeto muito legal.
No passado eu também fiz um tracker básico em Elixir.
Link do meu código
Fiquei especialmente curioso sobre o motivo de você ter implementado isso como private tracker.
Parabéns pelo lançamento do projeto.
Queria mais detalhes sobre como ele funciona em comparação com o opentracker, inclusive em desempenho.
Mas o extracker realmente mostra seu valor quando o número de núcleos de CPU chega a dois dígitos.
Ainda não fiz benchmarks adequados.
Projeto muito bem feito.
Como dica simples, talvez valha trocar
IO.putsporLoggere considerar adicionar OTel.Concordo com isso.
Na minha opinião, usar só o
Loggerembutido e a aplicaçãoTelemetryjá é suficiente.Depois fica fácil adicionar opentelemetry ou qualquer outra coisa pelos hooks de Telemetry.
Documentação do Logger
Documentação do Telemetry
Qual sink de otel você prefere usar para enviar as métricas?
Eu realmente adoro Elixir.
Estou desenvolvendo agora um ótimo engine de notificações em Elixir.
Elixir é realmente excepcional.
É um projeto privado ou OSS (open source)?
O ecossistema Elixir precisa de um engine de notificações melhor.
Houve algum projeto em que você se baseou?
Quanto tempo levou para desenvolver?
Em comparação com o qbittorrent, até que ponto os recursos funcionam?
Comecei porque precisava de um tracker para usar em outro projeto, mas desenvolver o tracker em si acabou ficando mais divertido e eu continuei.
Cheguei a olhar o código de outros trackers, mas a maioria era complexa demais ou simples demais, então não serviam muito bem como referência.
Até agora já foram 3 meses de desenvolvimento, em várias noites viradas programando.
Não é um cliente como o qbittorrent, mas tenho uma ideia futura de um projeto de cliente voltado a seedbox.
Tracker não é um cliente de torrent.
Testei pessoalmente, mas tive um problema em que HTTPS não funcionava direito.
Além disso, o console ficava imprimindo a mensagem de aviso
04:43:20.160 [warning] invalid 'event' parameter: size: 6 value: "paused"
repetidamente.
Ainda assim, aparentemente funciona.
Eu também queria ver estatísticas de HTTP, mas só consegui ver estatísticas de UDP.
(No meu caso, o UDP estava desativado.)
O evento
"paused"faz parte da BEP 21 e serve para informar ao tracker que o cliente ainda não concluiu, mas não está mais baixando.Por exemplo, isso é útil quando o usuário quer apenas alguns arquivos de um torrent.
No readme do projeto está indicado que BEP 21 ainda não é suportado.
A Telemetry relacionada a HTTP ainda está na lista de ToDo.
Como estou usando uma biblioteca de terceiros como servidor web, ainda estou pensando na melhor forma de integrar isso.
Para usar HTTPS, é preciso definir em
:https_keyfileo caminho para um certificado válido.Por enquanto, se você quiser HTTPS, recomendo colocar Caddy ou Nginx na frente do tracker.
Também planejo integrar certbot, mas como a maioria dos peers de torrent usa UDP, isso tem prioridade baixa.
Projeto realmente muito legal.
Você pensa em usar Elixir como linguagem principal?
Elixir é uma das minhas opções principais.
Pessoalmente, tenho certeza de que trabalharia com muito mais prazer do que com C++.
No meu caso não, mas trabalho com Elixir há quase 9 anos e 2 meses, e também sei usar Rust e Golang.
Fiquei curioso se alguém está contratando neste momento.