UMGUM.COM 

RSync + rTorrent + Linux ( Реализуем раздачу контента на вторичном сервере под управлением Linux. )

8 августа 2010  (обновлено 15 августа 2016)

OS: Debian Linux Lenny/Squeeze.

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

Пусть распространяемые файлы будут располагаться в директории "/mnt/storage/share/files/", а "торрент"-файлы в директории "/var/lib/share/torrents/":

# mkdir -p /mnt/storage/share/files
# mkdir -p /var/lib/share/torrents

Создаём группу для пользователей сервисов:

# groupadd share-users

В качестве приложения раздачи данных применим заслуженный "rtorrent" запускаемый с помощью "sudo" в сессии "screen", а загрузку (скорее "зеркалирование" с каталогом хранения) "торрент"-файлов с центрального узла будем осуществлять с помощью утилиты "rsync".

Инсталлируем необходимые утилиты:

# aptitude install rtorrent rsync screen sudo

Создаём для rtorrent "домик", где он будет жить:


# mkdir -p /var/lib/rtorrent

Создаем учётную запись пользователя для запуска rtorrent:

# useradd --shell /bin/false --home-dir /var/lib/rtorrent rtorrent

Создаём директорию для хранения файлов и сессий загрузок:

# mkdir -p /var/lib/rtorrent/session

Создаём конфигурационный файл для "rtorrent":

# touch /var/lib/rtorrent/.rtorrent.rc

# Директория сохранения файлов
directory = /mnt/storage/share/files

# Директория хранения файлов сессий загрузок
session = /var/lib/rtorrent/session

# Указываем сохранять состояние сессий
session_save = yes

# Отключаем проверку файла блокировки в директории сессий (лучше проверить факт запуска скриптом, нежели заблокировать rtorrent после аварийного завершения системы)
session_lock = no

# Запускаем планировщик rtorrent для периодической проверки новых "торрент"-файлов
schedule = watch_directory,5,5,load_start=/var/lib/share/torrents/*.torrent

# Диапазон портов для входящих соединений
port_range = 6998-6999

# Проверка контрольной суммы для завершённых закачек
check_hash = yes

# Указываем принимать зашифрованные входящие соединения, при установке исходящих соединений переключатся между режимом с шифрованием и без шифрования в случае ошибок, предпочитать передачу данных простым текстом после установления зашифрованного соединения
encryption = allow_incoming,enable_retry,prefer_plaintext

# Запрещаем использование UDP протокола
use_udp_trackers = no

# Принудительно устанавливаем кодировку для имён файлов, если она не была определена
encoding_list = UTF-8

Наводим порядок с правами доступа:

# chown -R rtorrent:share-users /mnt/storage/share/files /var/lib/rtorrent
# chmod -R ug+rw /mnt/storage/share/files /var/lib/rtorrent

Запускаем rtorrent:

# screen -S screen.rtorrent sudo -H -u rtorrent rtorrent

Проверяем, слушает ли rtorrent порты для входящих соединений:

# netstat -apn | grep rtorrent

tcp  0  0 0.0.0.0:6999  0.0.0.0:*  LISTEN  10920/rtorrent

Подключится к уже существующей сессии screen с запущенным в ней rtorrent можно следующим образом:

# screen -r screen.rtorrent

Для автоматизации запуска rtorrent напишем следующий скрипт:

# touch /etc/init.d/rtorrent
# chmod ugo+x /etc/init.d/rtorrent

#!/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin

### BEGIN INIT INFO
# Provides:          rtorrent
# Required-Start:    $local_fs $network
# Required-Stop:     $local_fs $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Script management of rtorrent
# Description:       Script management of rtorrent
### END INIT INFO

USER="rtorrent"
GROUP="share-users"

case "$1" in
  start)
    STATE=`ps wax | grep -v grep | grep -i screen | grep -c -i rtorrent`
    if [ ${STATE} -eq 0 ]
    then
      # Предварительно удаляем файлы блокировки сессии (они часто остаются при грубом завершении работы программы)
      rm --force /var/lib/rtorrent/session/*.lock

      # Запускаем rtorrent внутри фоновой сессии screen
      screen -dmS screen.rtorrent sudo -H -u ${USER} rtorrent
    fi
  ;;
  stop)
    killall rtorrent
  ;;
  restart|force-reload)
    $0 stop
    sleep 60
    $0 start
  ;;
  *)
    echo "Usage: /etc/init.d/rtorrent {start|stop|restart}"
    exit 1
  ;;
esac

exit 0

Создаем в директориях "runlevels" символические ссылки на скрипт авто-запуска. Прописываем наш скрипт для нужных уровней исполнения в системе:

# update-rc.d rtorrent start 10 2 3 4 5 . stop 10 0 1 6 .

"Rsync" у нас уже установлен, автоматический запуск заблокирован в файле "/etc/default/rsync" директивой "RSYNC_ENABLE=false".

Воспользуемся утилитой, чтобы просмотреть список поддерживаемых сервисом файловых модулей:

# rsync --port=8730 share.storage.local::

В команде выше два двоеточия "::" после адреса сервера указывает на то, что подключение клиента к сервису должно осуществлено напрямую, без посредника, вроде SSH2 или RSH (если нужно осуществить подключение поверх транспортной прослойки - нужно указывать одно двоеточие ":"). Как более академический вариант можно использовать следующий стиль написания запроса прямого соединения: "rsync://[user@]ip.primary.server[:port][/object]".

Вывод для запроса без точного указания объекта обращения даст нам список поддерживаемых сервисом "модулей" (тех, что мы описали в конфигурационном файле сервиса rsyncd) - что то вроде следующего:

torrents

Более точный запрос с указанием объекта даст содержимое описанное запрашиваемым модулем (мы помним, что из всей директории "/etc" доступ разрешён только к четырём файлам реквизитов пользователей):

# rsync --port=8730 share.storage.local::torrents

drwxrwxr-x    4096 2010/08/05 09:55:30 .
-rwxrwxr--     240 2010/08/06 12:01:01 file0.torrent
-rwxrwxr--    1778 2010/08/06 12:01:01 file1.torrent
-rwxrwxr--    2116 2010/08/06 12:01:02 file2.torrent
....

Запрос (в "читабельном" виде) доставит нам в директорию "/tmp/test" содержимое директории "/var/lib/share/torrents" сервера "share.storage.local":

# rsync --checksum --recursive --delete rsync://share.storage.local:8730/torrents/ /tmp/test

Где:

"--checksum"   - применяем сверку по контрольным суммам файлов, а не по времени изменения и размеру (дольше но точнее);
"--delete"     - указываем удалять файлы, которых нет на стороне сервера;
"--recursive"  - указываем осуществлять рекурсивный обход директорий.

Применение "/" после имени директории в описании объекта "зеркалирования" в клиентском запросе указывает rsync оперировать только содержимым директории, а отсутствие этого символа делает директорию, как и её содержимое, объектом проводимой операции; иначе говоря, в отсутствии "/" копируется, как сама директория, так и её содержимое, а в присутствии "/" - только содержимое.

Вывод содержимого директории "/tmp/test":

# ls -l /tmp/test

-rwxr-xr-- 1 root root   240 2010-08-06 14:07 file0.torrent
-rwxr-xr-- 1 root root  1778 2010-08-06 14:07 file1.torrent
-rwxr-xr-- 1 root root  2116 2010-08-06 14:07 file2.torrent
....

Зеркалирование инкрементальное и замещающее с удалением отсутствующих файлов.

Пишем скриптик, запускающий доставку "торрент"-файлов:

# mkdir -p /usr/local/etc/torrent
# touch /usr/local/etc/torrent/rsync.sh
# chmod ugo+x /usr/local/etc/torrent/rsync.sh

#!/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin

USER="rtorrent"
GROUP="share-users"

rsync --checksum --recursive --delete rsync://share.storage.local:8730/torrents/ /var/lib/share/torrents
chown -R ${USER}:${GROUP} /var/lib/share/torrents

exit 0

Внесем в таблицу "/etc/crontab" указание на запуск скрипта "зеркалирования" с определённой периодичностью. Можно и раз в день, а можно и раз в три часа. Учитывая то, что утилита rsync копирует только изменённые данные, нагрузка в процессе эксплуатации на оборудование не будет настолько великой, чтобы переносить время процедуры на ночное время:

# cat /etc/crontab

....
1  */3  *  *  *  root  /usr/local/etc/torrent/rsync.sh &
....

Теперь "rsync" каждые три часа будет доставлять обновления "торрент"-файлов с центрального узла и удалять ненужные файлы, а "rtorrent" закачивать из себе в хранилище для последующего предоставления клиентам.


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )