Pull to refresh

Переводим раздачу контента на BitTorrent

Reading time 5 min
Views 5.7K
Под катом описан пример перевода файловых серверов на BitTorrent.

У моего друга есть небольшая локальная сеть, абонентов так на 200-300, собственно обычная локальная сеть. Несколько игровых серверов, несколько файловых серверов и гирлянды неуправляемых свитчей. Типичный Пионер.Net начала-середины нулевых. Всё работает, все рады. Но с ростом количества абонентов у файловых серверов возникли проблемы с отдачей контента. После долгих раздумий и прочих экспериментов было решено перейти на битторрент. И вот уже почти полтора года проблем с серверами не возникает, а мой друг не перестает этому радоваться.
Каким именно должен быть сервер, какую систему выбрать, сколько дисков ставить, использовать ли raid, lvm, какую файловую систему предпочесть — у каждого администратора есть свои наработки. Лично я предпочитаю raid5 из 5-6 жестких дисков и xfs, производительность получаемая от такой связки меня полностью устраивает.
Краткая справка с википедии: BitTórrent — пиринговый (P2P) сетевой протокол для кооперативного обмена файлами через Интернет. Файлы передаются частями, каждый torrent-клиент, получая (скачивая) эти части, в то же время отдаёт (закачивает) их другим клиентам, что снижает нагрузку и зависимость от каждого клиента-источника и обеспечивает избыточность данных. Перед началом скачивания клиент подсоединяется к трекеру по адресу, указанному в торрент-файле, сообщает ему свой адрес и хеш-сумму торрент-файла, на что в ответ клиент получает адреса других клиентов, скачивающих или раздающих этот же файл.
Начнем с трекера, я выбрал opentracker. Простой в установке и настройке, нетребовательный к ресурсам.

fs:~# apt-get install gcc make cvs
fs:~# cvs -d :pserver:cvs@cvs.fefe.de:/cvs -z9 co libowfat
fs:~# cd libowfat/
fs:~/libowfat# make
fs:~/libowfat# cd ..
fs:~# cvs -d:pserver:anoncvs@cvs.erdgeist.org:/home/cvsroot co opentracker
fs:~# cd opentracker/
fs:~/opentracker# make
fs:~/opentracker# cp opentracker /usr/local/bin/
fs:~# cat /etc/rc.local |grep opentracker
start-stop-daemon --start --quiet -m -b --pidfile /var/run/opentracker.pid --exec /usr/local/bin/opentracker


В настройках трекера я разрешил регистрацию любых торрент файлов, так мне захотелось, да и так проще.
Клиентом я выбрал btpb. Опять же простой в установке и настройке, очень нетребовательный к ресурсам и без каких либо патчей нормально работает с большим количеством файлов.

fs:~# wget www.murmeldjur.se/btpd/btpd-0.15.tar.gz
fs:~# tar -xf btpd-0.15.tar.gz
fs:~# cd btpd-0.15
fs:~/btpd-0.15# chmod +x configure
fs:~/btpd-0.15# ./configure
fs:~/btpd-0.15# make
fs:~/btpd-0.15# make install
fs:~# cat /etc/rc.local |grep btpd
/usr/local/bin/btpd -d /root/.btpd


Генерировать торрент файлы будем посредством ctorrent
fs:~# apt-get install ctorrent

Собственно теперь у нас есть торрент трекер, торрент клиент и куча файлов, которые нужно раздавать пользователям.
Предположим помимо кучи файлов также имеется каталог с красивым интерфейсом и базой данных, где хранится вся необходимая нам информация.
В моем случае была табличка files, в которой хранились путь к файлу и уникальный id файла.
Для контроля генерации торрент файлов я создал дополнительную таблицу torrents

mysql> desc torrents;
+--------------+---------------+------+-----+---------+----------------+
| Field     | Type     | Null | Key | Default | Extra     |
+--------------+---------------+------+-----+---------+----------------+
| id        | int(16)    | NO   | PRI | NULL  | auto_increment |
| file_id    | int(16)    | YES   |    | NULL  |        |
| is_torrent | enum('1','0') | YES |    | 0     |        |
+------------+---------------+------+-----+---------+----------------+
3 rows in set (0.01 sec



и 3 триггера

mysql> show triggers;
+-----------+--------+-------+--------
| Trigger  | Event | Table | Statement | Timing |
+-----------+--------+-------+--------
| on_insert|INSERT|files| insert into torrents (file_id) values(LAST_INSERT_ID())| AFTER
| on_update|UPDATE|files| update torrents set is_torrent='0' where file_id=NEW.id | AFTER
| on_delete|DELETE|files| delete torrents.* from torrents where torrents.file_id=old.id | AFTER
+-----------+--------+-------+--------



В таблице хранятся данные от торрент файлах, и благодаря триггерам происходит создание, перегенерация, либо удаление торрент файла.

Теперь сам скрипт контроля состояния торрент файлов.
fs:~# cat add_torrent.sh

#!/bin/bash
#определяем адрес трекера
tracker="http://tracker_domain:6969/announce"
#корневая папка где храниться контент
video_home="/home/video";
#папка для хранения торрент файлов
torrent_dir=" /var/www/torrents";

ctorrent="/usr/bin/ctorrent";
btcli="/usr/local/bin/btcli";
mysql="/usr/bin/mysql -pdpass -u duser -D video";

#получаем id файлов для которых не сгенерирован торрент
for i in `echo "select files.id from files,torrents where torrents.file_id=files.id and torrents.is_torrent='0' limit 1;"|${mysql}|sed 1d`
do
id=${i};
#получаем полный путь к файлу
path=`echo "select files.path from files where files.id="${id}" limit 1;"|${mysql}|sed 1d`
#формируем название торрента
torrent_file=${torrent_dir}/${id}.torrent
#если торрент уже был сгенерирован удаляем его из торрент клиента
if [ -e ${torrent_file} ]
then
[ `${btcli} list|awk '{print $1}'|grep -w ${id}|wc -l` -ne 0 ] && ${btcli} del ${torrent_file}
rm ${torrent_file}
fi
cd ${video_home}
path1=`dirname "${path}"`
#генерируем торрент и если все прошло успешно обновляем базу данных
${ctorrent} -t -u ${tracker} -s ${torrent_file} "${path}" && echo "update torrents set is_torrent='1' where file_id="${id}|${mysql}
#если торрент сгенерился добавляем в торрент клиент
[ -e ${torrent_file} ] && ${btcli} add -d "${path1}" -n ${id} --topdir ${torrent_file}
done

#проверяем все ли сгенерированные торрент файлы загружены
ls ${torrent_dir}|sed 's/.torrent//'|sort -n > /tmp/tor_list.files
${btcli} list|awk '{print $1}'|sed 1d|sort -n > /tmp/tor_list.load

diff_list=(`diff /tmp/tor_list.files /tmp/tor_list.load|grep "<"|awk '{print $2}'`)
diff_num=$((${#diff_list[*]}-1))
for i in `seq 0 $diff_num`
do
id=${diff_list[${i}]};
path=`echo "select files.Path from files where files.id="${id}";"|${mysql}|sed 1d`
torrent_file=${torrent_dir}/${id}.torrent
${btcli} del ${torrent_file}
if [ -z ${path[0]} ]
then
rm ${torrent_file};
else
path=`dirname "$path"`
${btcli} add -d ${path} -n ${id} --topdir ${torrent_file}
fi
done


Как видно из листинга, скрипт генерирует торреннт файлы, если торрент уже существовал перегенерирует при необходимости, так же следит за тем что бы все сгенерированные торренты были добавлены в клиент.
Для нормальной работы системы достаточно запускать данный скрипт раз 2-3 минуты.
Единственное что не рализованно, это удаление торрент файлов и контента при удалении записей о нем из базы данных.
Не побоюсь повториться данная система работает уже как полтора года и проблем не возникает, единственное рекомендую в названиях файлов и папок не использовать кирилицу, всякое может случиться.
Tags:
Hubs:
+59
Comments 15
Comments Comments 15

Articles