UMGUM.COM 

Bacula parallel execution ( Параллельное исполнение заданий резервирования Bacula. )

12 ноября 2010  (обновлено 31 января 2015)

OS: Linux Debian Lenny/Squeeze/Wheezy.
Application: Bacula v.3.2/v.5.2.

Запустили мы наш сервис резервирования на основе приложений Bacula и начали включать в него новых и новых клиентов; некоторые из которых подключены к сети по низко-скоростному каналу. Смотрим статус и наблюдаем невесёлую картину, в очереди стоит штук десять заданий на пару сотен гигабайт общим объёмом и в самом её начале клиенты подключённые на скорости в 512 Kbps. Пропускную способность каналов передачи данных мы не увеличим, а вот пустить исполнение задач параллельно вполне в наших силах.

Несмотря на то, что, если бы мы в конфигурации "Директора" мы указали параметром "Maximum Concurrent Jobs = 5" на возможность одновременного запуска пяти конкурентных заданий выполнения резервного копирования, этого не произошло бы в рамках текущей конфигурации. На самом деле, Bacula работает со всеми устройствами так, как будто это устройства с последовательным доступом (иначе говоря дописывает в конец файла), вроде магнитных лент, и на них по определению не может производится одновременная параллельная запись. Каждое задание может работать только с одним "томом" (Volume), а на одном "устройстве" (Device) может быть одновременно активным только один из "томов" (Volume) (вроде как бы это магнитная лента в приводе). Запуск нескольких одновременных заданий возможен только в том случае, если все они будут работать со своим "устройствами" (Device) в "хранилищах" (Storage). Иначе говоря, сколько мы имеем "устройств" (Device) в "хранилищах" (Storage), столько сможем запустить одновременно исполняемых заданий.


Наша задача отработать настройку и использования таких устройств. Создаем директории "хранилищ":

# mkdir -p /mnt/storage/bacula/dev0
# mkdir -p /mnt/storage/bacula/dev1
# mkdir -p /mnt/storage/bacula/dev2
# chown -R bacula:bacula /mnt/storage/bacula/dev0
# chown -R bacula:bacula /mnt/storage/bacula/dev1
# chown -R bacula:bacula /mnt/storage/bacula/dev2

Определимся с простыми, но эффективными правилами распределения устройств между заданиями:

пускаем в "dev0" задачи с высокоскоростных каналов (GigabitEthernet, FastEthernet);
пускаем в "dev1" задачи с низко-скоростных каналов (SHDSL 2-4Mbs, Radio-link 5-10Mbs);
пускаем в "dev2" задачи с особо "не одарённых" скоростью каналов ("деревенский" DSL, GPRS, "dial-up").

Само собой разумеется то, что можно завести ещё большее количество хранилищ с более детальным дифференцированием нагрузки на них.

Корректируем конфигурационный файл сервиса "Storage Daemon" добавляя описания новых "устройств" Storage:

# cat /etc/bacula/bacula-sd.conf

Storage {
  Name = sd0.backup.local
....
  # Ограничиваем количество одновременных подключений к сервису "Storage Daemon" (больше для порядка)
  Maximum Concurrent Jobs = 10
....
}

Device {
  Name = "dev0.sd0.backup.local"
  Media Type = "FileDev0"
  Archive Device = "/mnt/storage/bacula/dev0"
  LabelMedia = yes; Random Access = Yes; AutomaticMount = yes; RemovableMedia = no; AlwaysOpen = no;
}

Device {
  Name = "dev1.sd0.backup.local"
  Media Type = "FileDev1"
  Archive Device = "/mnt/storage/bacula/dev1"
  LabelMedia = yes; Random Access = Yes; AutomaticMount = yes; RemovableMedia = no; AlwaysOpen = no;
}

Device {
  Name = "dev2.sd0.backup.local"
  Media Type = "FileDev2"
  Archive Device = "/mnt/storage/bacula/dev2"
  LabelMedia = yes; Random Access = Yes; AutomaticMount = yes; RemovableMedia = no; AlwaysOpen = no;
}
....

Проверим корректность конфигурации средствами самого Bacula:

# bacula-sd -c /etc/bacula/bacula-sd.conf -t

Перезапустим "Storage Daemon":

# /etc/init.d/bacula-sd restart

Убедимся в том, что "Storage Daemon" успешно пере-запущен и слушает назначенный ему порт:

# netstat -apn | grep bacula-sd

tcp  0  0 0.0.0.0:9103  0.0.0.0:*  LISTEN  4027/bacula-sd

Заглянем в консоли Bacula на состояние Storage:

# bconsole

Connecting to Director dir0.backup.local:9101
1000 OK: dir0.backup.local
Enter a period to cancel a command.
*status
Status available for:
  1: Director
  2: Storage
  3: Client
  4: All
Select daemon type for status (1-4): 2
Automatically selected Storage: sd0.backup.local
....
Device status:
Device "dev0.sd0.backup.local" (/mnt/storage/bacula/dev0) is not open.
Device "dev1.sd0.backup.local" (/mnt/storage/bacula/dev1) is not open.
Device "dev2.sd0.backup.local" (/mnt/storage/bacula/dev2) is not open.
*

Отлично, видим три доступных устройства.

Перейдем к конфигурационному файлу "Директора" с целью описать там подключение к нашим новым устройствам:

# cat /etc/bacula/bacula-dir.conf

....
Director {
  Name = "dir0.backup.local"
....
  # Указываем "Директору" на возможность обработки достаточно длинной очереди из заданий, иначе таковые будут попросту "заморожены" в ожидании окончания исполнения предыдущих (в любом случае эти задания будут ждать освобождения соответствующих им "томов")
  Maximum Concurrent Jobs = 100
}
....
Storage {
  Name = "dev0.sd0.backup.local"
  Device = "dev0.sd0.backup.local"
  Media Type = "FileDev0"
  Address = "sd0.backup.local"; SDPort = 9103
  Password = "strongPasswordForStorage"
  # Ограничиваем количество одновременных подключений к "устройству"
  Maximum Concurrent Jobs = 2
}

Storage {
  Name = "dev1.sd0.backup.local"
  Device = "dev1.sd0.backup.local"
  Media Type = "FileDev1"
  Address = "sd0.backup.local"; SDPort = 9103
  Password = "strongPasswordForStorage"
  Maximum Concurrent Jobs = 2
}

Storage {
  Name = "dev2.sd0.backup.local"
  Device = "dev2.sd0.backup.local"
  Media Type = "FileDev2"
  Address = "sd0.backup.local"; SDPort = 9103
  Password = "strongPasswordForStorage"
  Maximum Concurrent Jobs = 2
}
....

Вообще, разработчики Bacula несколько недодумали, на мой взгляд, схему именования сущностей, отчего может происходить некоторая путаница в понимании сути происходящего с сервисами. Именем "Storage" они называют, применительно к конфигурированию "Storage Daemon", сам сервис, а применительно к конфигурированию "Директора" - устройство хранения, иначе говоря "хранилище". Потому я применил имя "sd0.backup.local" для обращения исключительно к сервису, а имена "dev0-X.sd0.backup.local" - для обращения к субъектам этого сервиса. Опять же, ещё больше путаницы вносит своеобразный подход к выводу запрашиваемой информации в консоли Bacula; в частности, на запрос о состоянии определённого ресурса сервиса "Storage Daemon" вываливается масса информации о всех без исключении ресурсах этого сервиса, что не способствует чёткому разделению между понятиями. Но, как бы то ни было, оно работает именно так, как представляется должным.

Проверим корректность конфигурации средствами самого Bacula:

# bacula-dir -c /etc/bacula/bacula-dir.conf -t

Пере-запускаем "Директора":

# /etc/init.d/bacula-director restart

Убедимся в том, что сервис успешно пере-запущен и слушает назначенный ему порт:

# netstat -apn | grep bacula-dir

tcp  0  0 0.0.0.0:9101  0.0.0.0:*  LISTEN  4045/bacula-dir

Вот и всё, теперь в описании задания на резервирование нужно избирательно указывать тот "Storage", на который мы хотели бы осуществлять запись. Например:

# cat /etc/bacula/bacula-dir.conf

....
Job {
  Name = "job-backup-test0.domain.local"
....
  Storage = "dev0.sd0.backup.local"
  # Ограничиваем количество одновременных запусков задания
  Maximum Concurrent Jobs = 2
....
}
Job {
  Name = "job-backup-test1.domain.local"
....
  Storage = "dev1.sd0.backup.local"
  Maximum Concurrent Jobs = 2
....
}
Job {
  Name = "job-backup-test2.domain.local"
....
  Storage = "dev2.sd0.backup.local"
  Maximum Concurrent Jobs = 2
....
}
....

Принудительно запускаем пять заданий, пишущих в три "Storage". Смотрим в консоли Bacula на статус заданий:

*status
Status available for:
  1: Director
  2: Storage
  3: Client
  4: All
Select daemon type for status (1-4): 1
dir0.backup.local
....
Running Jobs:
JobId Level   Name                       Status
======================================================================
  22 Full    job-backup-test0.domain.local.2010-07-08_16.54.50.03 is running
  23 Full    job-backup-test1.domain.local.2010-07-08_16.55.41.04 is running
  24 Full    job-backup-test2.domain.local.2010-07-08_16.56.03.05 is running
  25 Full    job-backup-test3.domain.local.2010-07-08_16.57.07.06 is waiting on max Storage jobs
  26 Full    job-backup-test4.domain.local.2010-07-08_16.58.00.07 is waiting on max Storage jobs
....

Видим, что три задания работают параллельно в разные "Storage" а два стоят за ними в очереди. Сделали бы пять "Storage", было бы пять исполняющихся параллельных заданий.


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


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