Linux tape kezelés gyorsítás (blokkméret kísérletek)

Eddig mindig tar-ral írtam szalagra, az alapbeállításokkal. Ezzel nem is volt semmi baj, de szembejött néhány doksi, hogy lehetne ezt optimálisabban is, például a blokkméret növelésével.

TL;DR: Paraméterezéssel két-háromszorosára lehetett gyorsítani a tar/dd LTO írási/olvasási sebességét az alapértelmezetthez képest

Egy LTO-5 eszközt használva ezt kapom:

# tapeinfo -f /dev/nst0 | grep -i block
MinBlock: 1
MaxBlock: 16777215
BlockSize: 0

# dmesg -t | grep "Block limits"
st 1:0:1:0: [st0] Block limits 1 - 16777215 bytes.

Tehát változó blokkméretet használ az eszköz, mi mondjuk meg az íráskor/olvasáskor, hogy mekkora legyen a blokkméret, 1 és 16M-1 között.

Nézzük a tar alapbeállításait:

# tar --show-defaults
--format=posix -f- -b20 --quoting-style=escape --rmt-command=/usr/bin/rmt --rsh-command=/usr/bin/ssh

A man tar szerint:

   Device blocking
       -b, --blocking-factor=BLOCKS
              Set record size to BLOCKSx512 bytes.

A tar-nál egy blokk 512 byte, egy rekord pedig ennek N-szerese - de a szalagon egy tar rekord = 1 fizikai blokk. A default -b20 csak 10k-s blokkméretet ad ki, ami a fentiek szerint akár 16777215 / 512, azaz -b32767 (~ 16M fizikai blokkméret) is lehetne. Mivel szalagra jellemzően nagy fileokat írunk (a tar-ral összerakott archívum egy filenak minősül), az elméleti maximum blokkméret, a 16M is akár jó érték lehet.

A "man st" ezt mondja:

The  driver  uses an internal buffer that has to be large enough to hold at least one tape block. In kernels before 2.1.121, the buffer is allocated as one contiguous block. This limits the block size to the largest contiguous block of memory the kernel allocator can provide.  The limit is currently 128 kB for 32-bit architectures and 256 kB for 64-bit architectures.  In newer kernels the driver allocates the buffer in several parts if necessary. By default, the maximum number of parts is 16. This means that the maximum block size is very large (2 MB if allocation of 16 blocks of 128 kB succeeds).

Egy HP-UX doksi pedig nem javasol 256k fölé menni, de ez nyilván más driver:

By default, the HP-UX stape driver processes a block size larger than 256 KB by subdividing it into 256 KB blocks for writing to tape (giving a net effect of 256 KB I/O transfers). For example a 1 MB block (1048576 bytes) is written to tape as four 256 KB blocks. During restore, stape attempts to reconstruct the original block size that was larger than 256 KB with the 256 KB blocks from tape. This subdivision and subsequent reconstruction process of block sizes larger than 256 KB adds unnecessary complexity and risk to tape positioning and restore operations and offers no net gain in terms of increased block size. It should therefore be avoided.

Fogtam egy nálam jellemző backup készletet, néhány file, 41G az összméret. Nézzük, hogyan muzsikálnak a különböző értékek.

# time tar cf /dev/nst0 /mnt/backup
real    16m46.509s

# time tar cf /dev/nst0 /mnt/backup -b 128
real    5m9.125s

Eredetileg próbáltam volna még sokkal nagyobb értékeket, de már a -b128 (64k blokkméret) beállítással is elértem az LTO-5 maximális sebességét (tömöríthetetlen adatfolyam esetén 140 MB/s). Annyira durva a különbség, hogy muszáj volt visszaellenőriznem mégegyszer, de tényleg ennyi. Még visszaolvasást is próbáltam, ott is pontosan ugyanezek az értékek jöttek ki (meg kell adni visszaolvasáskor is a blokkméretet). Úgyhogy elővettem egy LTO-7 rendszert is, ott a max. natív sebesség 300 MB/s. Sajnos ezen a gépen még csak 4.4 kernel van (az előzőn 5.3), szerintem a max. blokkméret ezért kevesebb:

# tapeinfo -f /dev/nst0 | grep -i block
MinBlock: 1
MaxBlock: 8388608
BlockSize: 0

Ugyanazt az adatkészletet toltam neki. A -b128 értéknél (64k) már itt is megközelítette az elméleti maximumot, 280 MB/s-t mértem.

# time tar cf /dev/nst0 /mnt/backup
real    5m26.747s

# time tar cf /dev/nst0 /mnt/backup -b 128
real    2m29.832s

dd-nél a helyzet még szélsőségesebb, mert ott a default blokkméret csak 512 byte, ami szalagnál használhatatlan.

# dd if=SLES15SP2.iso of=/dev/nst0 
20742144+0 records in
20742144+0 records out
10619977728 bytes (11 GB, 9.9 GiB) copied, 1138.36 s, 9.3 MB/s

# dd if=SLES15SP2.iso of=/dev/nst0 bs=16k
648192+0 records in
648192+0 records out
10619977728 bytes (11 GB, 9.9 GiB) copied, 154.909 s, 68.6 MB/s

# dd if=SLES15SP2.iso of=/dev/nst0 bs=32k
324096+0 records in
324096+0 records out
10619977728 bytes (11 GB, 9.9 GiB) copied, 46.1232 s, 230 MB/s

# dd if=SLES15SP2.iso of=/dev/nst0 bs=64k
162048+0 records in
162048+0 records out
10619977728 bytes (11 GB, 9.9 GiB) copied, 36.9843 s, 287 MB/s

# dd if=SLES15SP2.iso of=/dev/nst0 bs=128k
81024+0 records in
81024+0 records out
10619977728 bytes (11 GB, 9.9 GiB) copied, 36.858 s, 288 MB/s

Itt is ugyanaz jön ki, mint a tar-nál, hogy 64k blokkméretnél már ki tudjuk az eszközből hozni a maximumot.

Még azt megnéztem, hogy tömöríthető adatfolyamnál számít-e a blokkméret további növelése, mert itt a tar/dd bs értéke nem fizikai blokkméret lesz a szalagon, hiszen az LTO drive tömöríti kiírás előtt. Egy 40G-s MaxDB adatbázisfilet küldtem rá, ami 92%-ban telített (és egyébként 5.5:1 arányban tömöríthető lenne gzippel, de az LTO-ra tömörítetlenül küldjük le, csak a drive hardveres tömörítését használjuk):

# dd if=DISKD0057 of=/dev/nst0 bs=16k 
41943040000 bytes (42 GB, 39 GiB) copied, 372.46 s, 113 MB/s

# dd if=DISKD0057 of=/dev/nst0 bs=32k 
41943040000 bytes (42 GB, 39 GiB) copied, 158.67 s, 264 MB/s

# dd if=DISKD0057 of=/dev/nst0 bs=64k 
41943040000 bytes (42 GB, 39 GiB) copied, 128.04 s, 328 MB/s

# dd if=DISKD0057 of=/dev/nst0 bs=128k 
41943040000 bytes (42 GB, 39 GiB) copied, 110.51 s, 380 MB/s

# dd if=DISKD0057 of=/dev/nst0 bs=256k 
41943040000 bytes (42 GB, 39 GiB) copied, 101.23 s, 414 MB/s

# dd if=DISKD0057 of=/dev/nst0 bs=512k 
41943040000 bytes (42 GB, 39 GiB) copied, 99.870 s, 420 MB/s

# dd if=DISKD0057 of=/dev/nst0 bs=1M
41943040000 bytes (42 GB, 39 GiB) copied, 88.465 s, 474 MB/s

Efölött már nem nőtt, hiába emeltem az értéket. Szerintem itt már elértem a diszkrendszer vagy a HBA áteresztőképességét is, mert az LTO-7 elvileg 750 MB/s-t tudna tömöríthető adatfolyamnál. Elképzelhető, hogy tovább lehetne tuningolni, ha a diszkről olvasásra és szalagra írásra különböző blokkméretet használunk (ibs / obs paraméterek a közös bs helyett), de én itt most egyelőre megállok a kísérletezéssel.

Források:

https://finch.am/projects/tar/
https://www.gnu.org/software/tar/manual/html_node/Blocking-Factor.html
https://en.wikipedia.org/wiki/Linear_Tape-Open

Hozzászólások

Több oldalról is érdekes. Nem is tudtam, hogy a tar-nál van --show-default kapcsoló, meg lehet játszani a blokkmérettel (dd-nél kísérleteztem vele, és tényleg sokat számít). Mindig tanul újat az ember, régebben az is nagy meglepetés volt, hogy a gnu vs. bsd tar-formátum nem azonos. Ilyen szalag még sose volt a kezem között, csak láttam 10+ éve, hogy cégeknél mentenek rá, de csak nézni volt szabad, azt is óvatosan, nehogy szemlenyomatos legyen.

Azt se tudtam, hogy tömörítéssel a szalag 474 MB/sec-et tud, az már egy SATA SSD-dől is nagyon becsülendő. Tuti kísérletezni fogok a tar blokkmérettel, hátha tovább gyorsít SSD-n az amúgy is gyors tar.zst-s tömörítésen.

The world runs on Excel spreadsheets. (Dylan Beattie)

Köszi az írást. Azt már én is megfigyeltem dd-s klónnál, hogy a 32K, és a 64K már kb a mximumot hozza sebességben.

Ahogy észrevettem, ez a disk cache-ektől függ leginkább.

Csak akkor szólok hozzá egy témához, ha értelmét látom.