Обмежити флеш-фон Linux (брудні сторінки)


26

Промивання фону в Linux відбувається, коли очікується занадто багато записаних даних (регулюється через / proc / sys / vm / dirty_background_ratio) або досягається час очікування очікування запису (/ proc / sys / vm / dirty_expire_centisecs). Якщо не буде досягнуто іншого обмеження (/ proc / sys / vm / dirty_ratio), можуть зберігатися більше керованих даних. Далі записи блокуються.

Теоретично це має створити фоновий процес виписування брудних сторінок, не порушуючи інших процесів. На практиці це заважає будь-якому процесу читання без кешування чи синхронного запису. Погано. Це пояснюється тим, що фонове відтворення фактично пише зі швидкістю 100% пристрою, і будь-які інші запити пристроїв у цей час будуть затримані (адже всі черги та кеші запису на дорозі заповнені).

Чи є спосіб обмежити кількість запитів в секунду, який виконує процес промивання, або іншим чином ефективно визначити пріоритет вводу / виводу іншого пристрою?


Можливо, це було б гарним питанням надіслати до списку розсилки ядро ​​linux vger.kernel.org/vger-lists.html#linux-kernel

Який IO планувальник ви використовуєте?
3вплив

Пробував різні (cfq, термін), але, мабуть, вони працюють надійно лише тоді, коли кеш-пам'ять запису не підтримується батареєю. Як і один дисковий масив, я з’їдає 1 Гб даних при швидкості шини PCIe (ОЗУ), а потім потрапляє в стіну реальності. Кілька секунд нульовий вводу / виводу для всіх LUN. Проблема вимивання (принаймні фонових) до приблизної оцінки реальної швидкості пристрою вирішить цю проблему перевантаженості.
korkman

1
Нещодавно мені стало відомо, що / sys / block / sdX / queue / nr_requests є основним настроєм. Якщо знизити його до мінімуму (= 4 в моєму випадку) покращує одночасну затримку навантаження: багато випадкових записів Sysbench fsync за секунду підскочило з 4 (!) До 80-90 під час запису на швидкості шини з dd. Навантаження на завантаження не впливає. Планувальники все ті ж, термін або термін здається оптимальним. Це може бути справедливо для більшості конфігурацій BBWC.
korkman

Відповіді:


20

Після багатьох тестів із системою sysbench я приходжу до такого висновку:

Щоб вижити (у перформансі) ситуацію, коли

  • злий процес копіювання заливає брудні сторінки
  • і кеш-пам'ять кеш-пам'яті присутня (можливо, і без цього)
  • а синхронне читання або запис в секунду (IOPS) є критичним

просто скиньте всі ліфти, черги та брудні кеші сторінок. Правильне місце для брудних сторінок знаходиться в оперативній пам’яті цього кеш-пам'яті запису.

Налаштуйте брудний коефіцієнт (або нові брудні байти) якомога менше, але слідкуйте за послідовністю пропускної здатності. У моєму конкретному випадку 15 Мб були оптимальними ( echo 15000000 > dirty_bytes).

Це скоріше хак, ніж рішення, оскільки гігабайти оперативної пам’яті зараз використовуються для кешування читання лише замість брудного кешу. Щоб брудний кеш добре працював у цій ситуації, флеш-фоновому режиму ядра Linux потрібно було б середньо оцінити, з якою швидкістю базовий пристрій приймає запити та відповідно налаштовує промивання фону. Нелегко.


Технічні характеристики та орієнтири для порівняння:

Перевірений під час ddнулів на диску, sysbench показав величезний успіх , збільшивши 10 ниток fsync , записуючи на 16 кБ від 33 до 700 IOPS (ліміт холостого ходу: 1500 IOPS) та одиночний потік від 8 до 400 IOPS.

Без навантаження IOPS не впливали (~ 1500) і пропускна здатність трохи зменшувалася (з 251 Мб / с до 216 Мб / с).

dd дзвінок:

dd if=/dev/zero of=dumpfile bs=1024 count=20485672

для sysbench, тестовий файл.0 був підготовлений до розбору:

dd if=/dev/zero of=test_file.0 bs=1024 count=10485672

sysbench виклик для 10 потоків:

sysbench --test=fileio --file-num=1 --num-threads=10 --file-total-size=10G --file-fsync-all=on --file-test-mode=rndwr --max-time=30 --file-block-size=16384 --max-requests=0 run

виклик sysbench для одного потоку:

sysbench --test=fileio --file-num=1 --num-threads=1 --file-total-size=10G --file-fsync-all=on --file-test-mode=rndwr --max-time=30 --file-block-size=16384 --max-requests=0 run

Менші розміри блоків показали ще більш різкі цифри.

--file-block-size = 4096 з 1 Гб брудних байтів:

sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
1 files, 10Gb each
10Gb total file size
Block size 4Kb
Number of random requests for random IO: 0
Read/Write ratio for combined random IO test: 1.50
Calling fsync() after each write operation.
Using synchronous I/O mode
Doing random write test
Threads started!
Time limit exceeded, exiting...
Done.

Operations performed:  0 Read, 30 Write, 30 Other = 60 Total
Read 0b  Written 120Kb  Total transferred 120Kb  (3.939Kb/sec)
      0.98 Requests/sec executed

Test execution summary:
      total time:                          30.4642s
      total number of events:              30
      total time taken by event execution: 30.4639
      per-request statistics:
           min:                                 94.36ms
           avg:                               1015.46ms
           max:                               1591.95ms
           approx.  95 percentile:            1591.30ms

Threads fairness:
      events (avg/stddev):           30.0000/0.00
      execution time (avg/stddev):   30.4639/0.00

--файл-блок-розмір = 4096 з 15 Мб брудних байтів:

sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
1 files, 10Gb each
10Gb total file size
Block size 4Kb
Number of random requests for random IO: 0
Read/Write ratio for combined random IO test: 1.50
Calling fsync() after each write operation.
Using synchronous I/O mode
Doing random write test
Threads started!
Time limit exceeded, exiting...
Done.

Operations performed:  0 Read, 13524 Write, 13524 Other = 27048 Total
Read 0b  Written 52.828Mb  Total transferred 52.828Mb  (1.7608Mb/sec)
    450.75 Requests/sec executed

Test execution summary:
      total time:                          30.0032s
      total number of events:              13524
      total time taken by event execution: 29.9921
      per-request statistics:
           min:                                  0.10ms
           avg:                                  2.22ms
           max:                                145.75ms
           approx.  95 percentile:              12.35ms

Threads fairness:
      events (avg/stddev):           13524.0000/0.00
      execution time (avg/stddev):   29.9921/0.00

--file-block-size = 4096 з 15 Мб брудних байтів в режимі очікування:

sysbench 0.4.12: багатопотокова система оцінки системи

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
1 files, 10Gb each
10Gb total file size
Block size 4Kb
Number of random requests for random IO: 0
Read/Write ratio for combined random IO test: 1.50
Calling fsync() after each write operation.
Using synchronous I/O mode
Doing random write test
Threads started!
Time limit exceeded, exiting...
Done.

Operations performed:  0 Read, 43801 Write, 43801 Other = 87602 Total
Read 0b  Written 171.1Mb  Total transferred 171.1Mb  (5.7032Mb/sec)
 1460.02 Requests/sec executed

Test execution summary:
      total time:                          30.0004s
      total number of events:              43801
      total time taken by event execution: 29.9662
      per-request statistics:
           min:                                  0.10ms
           avg:                                  0.68ms
           max:                                275.50ms
           approx.  95 percentile:               3.28ms

Threads fairness:
      events (avg/stddev):           43801.0000/0.00
      execution time (avg/stddev):   29.9662/0.00

Тест-система:

  • Adaptec 5405Z (це кеш-пам'ять запису 512 Мб із захистом)
  • Intel Xeon L5520
  • 6 ГБ оперативної пам'яті при 1066 МГц
  • Материнська плата Supermicro X8DTN (чіпсет 5520)
  • 12 дисків Seagate Barracuda 1 TB
    • 10 у програмі Linux RAID 10
  • Ядро 2.6.32
  • Файлова система xfs
  • Debian нестабільний

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


Яка ваша методологія, щоб досягти оптимальної частини "15 Мб для брудних буферів"?
Марцін

1
Метод спроб і помилок. Мовляв, змінити половину суми наступного разу тощо, доки я не закінчив лише 15 МБ та OK IOPS. Поточне ядро ​​3.2 може поводитись дуже по-різному, BTW.
korkman

2
Просто хотів сказати спасибі за те, що поставив мене на правильний шлях. Були деякі подібні проблеми з вузлом XenServer. Виявився кеш PHP-FPM / APC, що спричиняє брудні сторінки. Налаштування моделі пам'яті кеша APC вирішило для нас проблему. DiskIO пішов з 20% використання до 0.
1313

Логічно dirty_bytesповинно бути ледь достатньо високо, щоб не затримувати процесори під час запису процесів, якщо процес пише в середньому з пропускною здатністю пристрою. Якщо ваш додаток робить цикли великих обчислень з подальшим записом величезної кількості даних, то оптимізувати їх буде дуже важко, оскільки середні показники короткого часу сильно відрізняються від середніх тривалих тривалості. Правильним рішенням було б коригування налаштувань для конкретних процесів, dirty_bytesале наскільки я не знаю, Linux не підтримує таке.
Мікко Ранталайнен

3

Навіть незважаючи на те, що налаштування параметрів ядра зупинило проблему, насправді можливо, що ваші проблеми з продуктивністю були наслідком помилки на контролері Adaptec 5405Z, яка була виправлена ​​в оновлення мікропрограмного забезпечення 1 лютого 2012 року. У примітках до випуску написано: "Виправлена ​​проблема, коли прошивка могла зависати під час високої напруги вводу / виводу". Можливо, розповсюдження вводу-виводу, як і ви, було достатньо, щоб запобігти спрацюванню цієї помилки, але це лише здогадка.

Ось примітки до випуску: http://download.adaptec.com/pdfs/readme/relnotes_arc_fw-b18937_asm-18837.pdf

Навіть якщо це не було для вашої конкретної ситуації, я вважав, що це може принести користь користувачам, які в майбутньому натрапляють на цю посаду. У нашому виході dmesg ми побачили такі повідомлення, як наступні, що врешті-решт призвело до оновлення прошивки:

aacraid: Host adapter abort request (0,0,0,0)
[above was repeated many times]
AAC: Host adapter BLINK LED 0x62
AAC0: adapter kernel panic'd 62.
sd 0:0:0:0: timing out command, waited 360s
sd 0:0:0:0: Unhandled error code
sd 0:0:0:0: SCSI error: return code = 0x06000000
Result: hostbyte=DID_OK driverbyte=DRIVER_TIMEOUT,SUGGEST_OK
sd 0:0:0:0: timing out command, waited 360s
sd 0:0:0:0: Unhandled error code
sd 0:0:0:0: SCSI error: return code = 0x06000028
Result: hostbyte=DID_OK driverbyte=DRIVER_TIMEOUT,SUGGEST_OK
sd 0:0:0:0: timing out command, waited 360s
sd 0:0:0:0: Unhandled error code
sd 0:0:0:0: SCSI error: return code = 0x06000028

Ось номери моделей контролерів Adaptec RAID, які вказані у примітках до випуску прошивки, яка має високий рівень виправлення ввімк / виводу: 2045, 2405, 2405Q, 2805, 5085, 5405, 5405Z, 5445, 5445Z, 5805, 5805Q, 5805Z, 5805ZQ, 51245, 51645, 52445.


1
Нічого, дякую за ваш внесок. Хоча для мене це було не так, ви даєте мені ще одну причину взагалі уникати HW RAID та переходити до налаштувань лише HBA. HW RAID все ще має перевагу BBWC, але з такими речами, як bcache, що переміщується в ядро, навіть це зникає. Зворотна сторона HW RAID - це саме та помилка прошивки, яку ви описуєте. У мене була інша система з налаштуванням DRBD і великим завантаженням вводу / виводу, що спричиняє перезавантаження програмного забезпечення, тому це трапляється не рідко (можливо, саме ця помилка).
korkman

1

Ядро, яке включає "WBT":

Покращення рівня шару блоку , LWN.net

За допомогою дроселювання при зворотному записі [блок-блок] намагається отримати максимальну продуктивність без надмірної затримки вводу-виводу за допомогою стратегії, запозиченої у планувальника мережі CoDel. CoDel відстежує спостережувану мінімальну затримку мережевих пакетів і, якщо це перевищує порогове значення, починає скидати пакети. Видалення записів спохмурнюється в підсистемі вводу-виводу, але подібна стратегія дотримується того, що ядро ​​контролює мінімальну затримку обох зчитувань і записів, і, якщо це перевищує порогове значення, воно починає зменшувати величину фонового викупу це робиться. Така поведінка була додана в 4.10; Ексбо зазначив, що помічені досить хороші результати.

WBT не потребує перемикання на новий блок-шар blk-mq. Однак це не працює з планувальниками вводу-виводу CFQ або BFQ. Ви можете використовувати WBT з планувальниками термінів / mq-крайнього / noop / none. Я вважаю, що це також працює з новим "kyber" планувальником вводу / виводу.

Окрім масштабування розміру черги для контролю затримки, код WBT обмежує кількість запитів фонового запиту як частку від обчисленої межі черги.

Конфігурація виконання знаходиться в /sys/class/block/*/queue/wbt_lat_usec.

Параметри конфігурації збірки, які потрібно шукати, є

/boot/config-4.20.8-200.fc29.x86_64:CONFIG_BLK_WBT=y
/boot/config-4.20.8-200.fc29.x86_64:# CONFIG_BLK_WBT_SQ is not set
/boot/config-4.20.8-200.fc29.x86_64:CONFIG_BLK_WBT_MQ=y

Ваша заява про проблему на 100% підтверджена автором WBT - молодець :-).

Блок [PATCHSET]: буферизація буферного зворотного запису

З самого світанку наш фоновий буфер знищений. Коли ми робимо фонову буферизацію, це має мало впливати на активність переднього плану. Це визначення фонової діяльності ... Але, наскільки я пам’ятаю, письменники з важкими буферами так не поводилися. Наприклад, якщо я роблю щось подібне:

$ dd if=/dev/zero of=foo bs=1M count=10k

на моєму ноутбуці, а потім спробуйте запустити хром, він, як правило, не запуститься до того, як буде зроблено буферизація. Або для серверно орієнтованих навантажень, де встановлення великого RPM (або подібного) негативно впливає на зчитування чи синхронізацію записів бази даних. Коли це трапляється, я змушую людей кричати на мене.

Результати деяких останніх тестувань можна знайти тут:

https://www.facebook.com/axboe/posts/10154074651342933

Перегляньте попередні публікації для більшого опису патчету.


Я радий бачити, що проблема виявляється і вирішується всередині ядра. Майте на увазі, blk-mq є досить новим і, можливо, ще не таким дозрілим .
korkman

@korkman зітхаю, я вважаю, що я зроблю цитату, щоб уникнути помилкових наслідків. Я погоджуюсь, що цей додаток додається протягом останніх кількох років, все ще можуть бути регресії продуктивності чи гірше. ПІСЛЯ технічний супровід технічного обслуговування відхиляє виправлення корупційних даних у тому сенсі, що це підробка. Якщо ви використовуєте версії ядра, де розроблено blk-mq, можна сперечатися, наскільки використання блоку "legacy" дозволить уникнути помилок. Виправлена ​​помилка, яку я виправила, була помилкою, яка виникла у blk-mq, потім вона була відновлена, або щось і вплинуло на те і інше. github.com/torvalds/linux/commit/1dc3039bc87a
sourcejedi

0

Який середній ви показник "Брудне" в / proc / meminfo? Зазвичай це не повинно перевищувати ваше / proc / sys / vm / dirty_ratio. На виділеному файловому сервері у мене брудний_рацій встановлений дуже високий відсоток пам'яті (90), оскільки я його ніколи не перевищую. Твоя брудна_рація занадто низька, коли ти її вдариш, усе вилазить, піднімаєш.


Проблема не в тому, що процеси блокуються під час потрапляння на брудний коефіцієнт. Я з цим все гаразд. Але "фоновий" процес виписування брудних даних на диски заповнює черги без милості та вбиває продуктивність IOPS. Я думаю, це називається голодування IO. Насправді, налаштування брудних_раціо_байтів надзвичайно низьких (наприклад, 1 Мб) допомагає дуже багато, тому що промивання буде майже негайно, а черги залишатимуться порожніми. Відношення можливо нижча пропускна здатність для послідовного, але це нормально.
korkman

Ви вимкнули всі ліфти? Що ще ти підкорив із ванільної системи?
Лука

1
Дивіться мою самовідповідь. Кінцем історії було видалити брудне кешування та залишити цю частину контролеру HW. Ліфти якось не мають значення, якщо кеш-пам'ять HW на місці. Контролер має власні алгоритми ліфтів, тому наявність будь-якого елеватора в програмному забезпеченні лише додає накладні витрати.
korkman

Elevevator в програмному забезпеченні є компромісом: жертвуйте затримкою для поліпшення пропускної здатності. Наприклад, уявіть 100K запису операторів у черзі програм, поданих у випадковому порядку; якщо ліфт програмного забезпечення може замовити ці операційні системи, використовуючи величезний буфер, це може в кінцевому підсумку надіслати на пристрій лише 5K значно більших запитів. Однак, як наслідок, затримку потрібно збільшити на 100 кс, оскільки можливо, перші 2 кп та останні 1 кс фактично знаходяться поруч один з одним на пристрої. Без додаткової затримки об'єднати їх буде неможливо.
Мікко Ранталайнен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.