Backup

Bacula 和多個磁帶設備等

  • February 7, 2013

Bacula 不會同時使用 2 個磁帶設備。(為 TL 搜尋**#-#-#**;DR)

可能有點背景。

在嘗試獲得一個體面的工作備份解決方案(備份> 20TB 並不便宜或容易)的過程中$dayjob,我們買了一堆東西讓它工作。

首先,有一個 Spectra Logic T50e 自動轉換器,40 個 LTO5 插槽,該機器人有一對 IBM HH5 Ultrium LTO5 驅動器,通過 FibreChannel Arbitrated Loop 連接到我們的備份伺服器。

有備份伺服器。戴爾 R715 配備 2 個 16 核 AMD 62xx CPU 和 32GB 記憶體。好吃。該伺服器有 2 個 Emulex FCe-12000E 卡和一個 Intel X520-SR 雙埠 10GE NIC。

我們還出售了 Commvault Backup(非 NDMP)。

這就是它變得非常複雜的地方。

Spectra Logic 和 Commvault 都派出了各自的工程師來設置庫和軟體。就控制器工作正常而言,Commvault 執行良好。戴爾伺服器具有 Ubuntu 12.04 伺服器,並為 CommVault 執行 MediaAgent,並將我們的 BlueArc NAS 作為 NFS 安裝到幾個安裝點,/home例如/mnt.

從 NFS 掛載點備份時,我們看到 ~=290GB/hr吞吐量。這太糟糕了,考慮到我們在不到 48 小時的備份視窗內有 20 多個 TB 需要通過。BlueArc 上的額定最大值為700MB/s( 2460GB/hr),磁帶設備上的額定最大寫入速度為 140MB/s,每個驅動器,因此是492GB/hr(或兩倍,對於總吞吐量)。

因此,下一步是使用 IOzone 對 NFS 性能進行基準測試,結果證明我們獲得了史詩般的寫入性能(超過 20 個執行緒),它就像 1.5-2.5TB/hr 寫入,但讀取性能令人絕望。我無法達到最高 343GB/小時的速度。因此,我們假設343GB/hrNAS 上的讀取性能是理論上的最大值,那麼理論上我們應該能夠從a) CommVault 和**b)**任何其他備份代理中獲得該性能。

不是這樣。Commvault 似乎只給了我200-250GB/hr吞吐量,出於實驗,我安裝了 Bacula 以查看遊戲狀態。例如,如果 Bacula 始終提供比 Commvault 更好的性能和速度,那麼我們可以說"**$.$ Refunds Plz $.$**"

#-#-#

唉,我發現了 Bacula 的另一個問題。Commvault 似乎很樂意使用一個執行緒從安裝點的一部分讀取,並將其流式傳輸到磁帶設備,同時使用另一個執行緒從其他目錄讀取,並寫入自動轉換器中的第二個驅動器。

我一輩子都無法讓 Bacula 同時掛載和寫入兩個磁帶驅動

我嘗試過的事情:

  • Maximum Concurrent Jobs = 20在 Director、File 和 Storage Daemons 中設置
  • Prefer Mounted Volumes = no作業定義中的設置
  • 在 Autochanger 資源中設置多個設備。

文件似乎非常以單驅動器為中心,我們感覺有點像把火箭綁在倉鼠身上,有了這個。大多數範例 Bacula 配置用於 DDS4 驅動器、手動磁帶交換和 FreeBSD 或 IRIX 系統。

我可能應該補充一點,如果這不可能,我不會太在意*,*但我會感到驚訝。我基本上想用 Bacula 作為證據,向軟體供應商證明他們的價格過高;)

我在某處讀到@KyleBrandt 用現代磁帶解決方案做了類似的事情..

配置文件: bacula-dir.conf

#
# Default Bacula Director Configuration file

Director {                            # define myself
 Name = backuphost-1-dir
 DIRport = 9101                # where we listen for UA connections
 QueryFile = "/etc/bacula/scripts/query.sql"
 WorkingDirectory = "/var/lib/bacula"
 PidDirectory = "/var/run/bacula"
 Maximum Concurrent Jobs = 20
 Password = "yourekiddingright"         # Console password
 Messages = Daemon
 DirAddress = 0.0.0.0
 #DirAddress = 127.0.0.1
}

JobDefs {
 Name = "DefaultFileJob"
 Type = Backup
 Level = Incremental
 Client = backuphost-1-fd 
 FileSet = "Full Set"
 Schedule = "WeeklyCycle"
 Storage = File
 Messages = Standard
 Pool = File
 Priority = 10
 Write Bootstrap = "/var/lib/bacula/%c.bsr"
}

JobDefs {
 Name = "DefaultTapeJob"
 Type = Backup
 Level = Incremental
 Client = backuphost-1-fd
 FileSet = "Full Set"
 Schedule = "WeeklyCycle"
 Storage = "SpectraLogic"
 Messages = Standard
 Pool = AllTapes
 Priority = 10
 Write Bootstrap = "/var/lib/bacula/%c.bsr"
 Prefer Mounted Volumes = no

}

#
# Define the main nightly save backup job
#   By default, this job will back up to disk in /nonexistant/path/to/file/archive/dir
Job {
 Name = "BackupClient1"
 JobDefs = "DefaultFileJob"
}

Job {
 Name = "BackupThisVolume"
 JobDefs = "DefaultTapeJob"
 FileSet = "SpecialVolume"
}
#Job {
#  Name = "BackupClient2"
#  Client = backuphost-12-fd
#  JobDefs = "DefaultJob"
#}

# Backup the catalog database (after the nightly save)
Job {
 Name = "BackupCatalog"
 JobDefs = "DefaultFileJob"
 Level = Full
 FileSet="Catalog"
 Schedule = "WeeklyCycleAfterBackup"
 # This creates an ASCII copy of the catalog
 # Arguments to make_catalog_backup.pl are:
 #  make_catalog_backup.pl <catalog-name>
 RunBeforeJob = "/etc/bacula/scripts/make_catalog_backup.pl MyCatalog"
 # This deletes the copy of the catalog
 RunAfterJob  = "/etc/bacula/scripts/delete_catalog_backup"
 Write Bootstrap = "/var/lib/bacula/%n.bsr"
 Priority = 11                   # run after main backup
}

#
# Standard Restore template, to be changed by Console program
#  Only one such job is needed for all Jobs/Clients/Storage ...
#
Job {
 Name = "RestoreFiles"
 Type = Restore
 Client=backuphost-1-fd                 
 FileSet="Full Set"                  
 Storage = File                      
 Pool = Default
 Messages = Standard
 Where = /srv/bacula/restore
}

FileSet {
 Name = "SpecialVolume"
 Include {
   Options {
     signature = MD5
   }
 File = /mnt/SpecialVolume
 }
 Exclude {
   File = /var/lib/bacula
   File = /nonexistant/path/to/file/archive/dir
   File = /proc
   File = /tmp
   File = /.journal
   File = /.fsck
 }
}


# List of files to be backed up
FileSet {
 Name = "Full Set"
 Include {
   Options {
     signature = MD5
   }
   File = /usr/sbin
 }

 Exclude {
   File = /var/lib/bacula
   File = /nonexistant/path/to/file/archive/dir
   File = /proc
   File = /tmp
   File = /.journal
   File = /.fsck
 }
}

Schedule {
 Name = "WeeklyCycle"
 Run = Full 1st sun at 23:05
 Run = Differential 2nd-5th sun at 23:05
 Run = Incremental mon-sat at 23:05
}

# This schedule does the catalog. It starts after the WeeklyCycle
Schedule {
 Name = "WeeklyCycleAfterBackup"
 Run = Full sun-sat at 23:10
}

# This is the backup of the catalog
FileSet {
 Name = "Catalog"
 Include {
   Options {
     signature = MD5
   }
   File = "/var/lib/bacula/bacula.sql"
 }
}

# Client (File Services) to backup
Client {
 Name = backuphost-1-fd
 Address = localhost
 FDPort = 9102
 Catalog = MyCatalog
 Password = "surelyyourejoking"          # password for FileDaemon
 File Retention = 30 days            # 30 days
 Job Retention = 6 months            # six months
 AutoPrune = yes                     # Prune expired Jobs/Files
}

#
# Second Client (File Services) to backup
#  You should change Name, Address, and Password before using
#
#Client {
#  Name = backuphost-12-fd                
#  Address = localhost2
#  FDPort = 9102
#  Catalog = MyCatalog
#  Password = "i'mnotjokinganddontcallmeshirley"         # password for FileDaemon 2
#  File Retention = 30 days            # 30 days
#  Job Retention = 6 months            # six months
#  AutoPrune = yes                     # Prune expired Jobs/Files
#}


# Definition of file storage device
Storage {
 Name = File
# Do not use "localhost" here    
 Address = localhost                # N.B. Use a fully qualified name here
 SDPort = 9103
 Password = "lalalalala"
 Device = FileStorage
 Media Type = File
}

Storage {
 Name = "SpectraLogic"
 Address = localhost
 SDPort = 9103
 Password = "linkedinmakethebestpasswords"
 Device = Drive-1
 Device = Drive-2
 Media Type = LTO5
 Autochanger = yes
}



# Generic catalog service
Catalog {
 Name = MyCatalog
# Uncomment the following line if you want the dbi driver
# dbdriver = "dbi:sqlite3"; dbaddress = 127.0.0.1; dbport =  
 dbname = "bacula"; DB Address = ""; dbuser = "bacula"; dbpassword = ""
}

# Reasonable message delivery -- send most everything to email address
#  and to the console
Messages {
 Name = Standard

 mailcommand = "/usr/lib/bacula/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula: %t %e of %c %l\" %r"
 operatorcommand = "/usr/lib/bacula/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula: Intervention needed for %j\" %r"
 mail = root@localhost = all, !skipped            
 operator = root@localhost = mount
 console = all, !skipped, !saved
#
# WARNING! the following will create a file that you must cycle from
#          time to time as it will grow indefinitely. However, it will
#          also keep all your messages if they scroll off the console.
#
 append = "/var/lib/bacula/log" = all, !skipped
 catalog = all
}


#
# Message delivery for daemon messages (no job).
Messages {
 Name = Daemon
 mailcommand = "/usr/lib/bacula/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula daemon message\" %r"
 mail = root@localhost = all, !skipped            
 console = all, !skipped, !saved
 append = "/var/lib/bacula/log" = all, !skipped
}

# Default pool definition
Pool {
 Name = Default
 Pool Type = Backup
 Recycle = yes                       # Bacula can automatically recycle Volumes
 AutoPrune = yes                     # Prune expired volumes
 Volume Retention = 365 days         # one year
}

# File Pool definition
Pool {
 Name = File
 Pool Type = Backup
 Recycle = yes                       # Bacula can automatically recycle Volumes
 AutoPrune = yes                     # Prune expired volumes
 Volume Retention = 365 days         # one year
 Maximum Volume Bytes = 50G          # Limit Volume size to something reasonable
 Maximum Volumes = 100               # Limit number of Volumes in Pool
}

Pool {
 Name = AllTapes
 Pool Type = Backup
 Recycle = yes
 AutoPrune = yes                     # Prune expired volumes
 Volume Retention = 31 days         # one Moth
}

# Scratch pool definition
Pool {
 Name = Scratch
 Pool Type = Backup
}

#
# Restricted console used by tray-monitor to get the status of the director
#
Console {
 Name = backuphost-1-mon
 Password = "LastFMalsostorePasswordsLikeThis"
 CommandACL = status, .status
}

bacula-sd.conf

#
# Default Bacula Storage Daemon Configuration file
#

Storage {                             # definition of myself
 Name = backuphost-1-sd
 SDPort = 9103                  # Director's port      
 WorkingDirectory = "/var/lib/bacula"
 Pid Directory = "/var/run/bacula"
 Maximum Concurrent Jobs = 20
 SDAddress = 0.0.0.0
#  SDAddress = 127.0.0.1
}

#
# List Directors who are permitted to contact Storage daemon
#
Director {
 Name = backuphost-1-dir
 Password = "passwordslinplaintext"
}

#
# Restricted Director, used by tray-monitor to get the
#   status of the storage daemon
#
Director {
 Name = backuphost-1-mon
 Password = "totalinsecurityabound"
 Monitor = yes
}


Device {
 Name = FileStorage
 Media Type = File
 Archive Device = /srv/bacula/archive
 LabelMedia = yes;                   # lets Bacula label unlabeled media
 Random Access = Yes;
 AutomaticMount = yes;               # when device opened, read it
 RemovableMedia = no;
 AlwaysOpen = no;
}


Autochanger {
  Name = SpectraLogic
  Device = Drive-1
  Device = Drive-2
  Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d"
  Changer Device = /dev/sg4
}

Device {
  Name = Drive-1
  Drive Index = 0
  Archive Device = /dev/nst0
  Changer Device = /dev/sg4
  Media Type = LTO5
  AutoChanger = yes
  RemovableMedia = yes;
  AutomaticMount = yes;
  AlwaysOpen = yes;
  RandomAccess = no;
  LabelMedia = yes

}

Device {
  Name = Drive-2
  Drive Index = 1
  Archive Device = /dev/nst1
  Changer Device = /dev/sg4
  Media Type = LTO5
  AutoChanger = yes
  RemovableMedia = yes;
  AutomaticMount = yes;
  AlwaysOpen = yes;
  RandomAccess = no;
  LabelMedia = yes
}

# 
# Send all messages to the Director, 
# mount messages also are sent to the email address
#
Messages {
 Name = Standard
 director = backuphost-1-dir = all
}

bacula-fd.conf

#
# Default  Bacula File Daemon Configuration file
#

#
# List Directors who are permitted to contact this File daemon
#
Director {
 Name = backuphost-1-dir
 Password = "hahahahahaha"
}

#
# Restricted Director, used by tray-monitor to get the
#   status of the file daemon
#
Director {
 Name = backuphost-1-mon
 Password = "hohohohohho"
 Monitor = yes
}

#
# "Global" File daemon configuration specifications
#
FileDaemon {                          # this is me
 Name = backuphost-1-fd
 FDport = 9102                  # where we listen for the director
 WorkingDirectory = /var/lib/bacula
 Pid Directory = /var/run/bacula
 Maximum Concurrent Jobs = 20
 #FDAddress = 127.0.0.1
 FDAddress = 0.0.0.0
}

# Send all messages except skipped files back to Director
Messages {
 Name = Standard
 director = backuphost-1-dir = all, !skipped, !restored
}

當您在 bacula 中設置文件集時,它會逐行讀取 pathspec 並像這樣備份。

它不會創建兩個執行緒來讀取代理中的不同文件路徑。

正如@SpacemanSpiff 所說,如果您想這樣做,那麼前進的方法是設置不同的作業,為您要備份的每個文件規範設置一個。

我給你三個建議:

  • 使用多個儲存守護程序。您可以在同一台機器上的不同埠上執行多個儲存守護程序。
  • 使用基本作業進行重複數據刪除。節省時間和空間。
  • 使用壓縮 - 如果您的磁帶驅動器進行壓縮,很好,但您可能需要權衡它並嘗試使用 bacula-fd 壓縮。這發生在客戶端上,因此也節省了頻寬,只犧牲了少量的 CPU 時間。

引用自:https://serverfault.com/questions/396970