72 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Markdown
		
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Markdown
		
	
	
| ---
 | ||
| title: Ограничение использования диска, вариант 2
 | ||
| description: 
 | ||
| published: true
 | ||
| date: 2024-08-09T07:42:49.725Z
 | ||
| tags: limit, disk
 | ||
| editor: markdown
 | ||
| dateCreated: 2024-08-09T07:42:49.725Z
 | ||
| ---
 | ||
| 
 | ||
| Первый вариант - [Disk-limit](/sysadmin/Linux/Base-znaniy/Disk-limit)
 | ||
| 
 | ||
| Недавно делал заметку (https://t.me/srv_admin/3817) про ограничение использования диска при создании дампов базы данных, чтобы не вызывать замедление всех остальных процессов в системе. Использовал утилиту pv (https://t.me/srv_admin/3823). Способ простой и рабочий, я его внедрил и оставил. Поставленную задачу решает. 
 | ||
| 
 | ||
| Тем не менее, захотелось сделать это более изящно через использование приоритетов. Если диск не нагружен, то неплохо было бы его использовать с максимальной производительностью. А если нагружен, то отдать приоритет другим процесса. Это был бы наиболее рациональный и эффективный способ. 
 | ||
| 
 | ||
| Я знаю утилиту ionice, которая в большинстве дистрибутивов есть по умолчанию. Она как раз существует для решения именно этой задачи. У неё не так много параметров, так что пользоваться ей просто. Приоритет можно передать через ключи. Для этого нужно задать режим работы:
 | ||
| 
 | ||
| ◽️Idle - идентификатор 1, процесс работает с диском только тогда, когда он не занят
 | ||
| ◽️Best effort - идентификатор 2, стандартный режим работы с возможностью выставления приоритета от 0 до 7 (0 - максимальный)
 | ||
| ◽️Real time - режим работы реального времени тоже с возможностью задавать приоритет от 0 до 7
 | ||
| 
 | ||
| На практике это выглядит примерно так:
 | ||
| ```
 | ||
| # ionice -c 3 cp tempfile ~/
 | ||
| ```
 | ||
| Скопировали tempfile в домашний каталог в режиме idle. По идее, это то, что нужно. На практике этот приоритет не работает. Провёл разные тесты и убедился в том, что в Debian 12 ionice не работает вообще. Стал копать, почему так. 
 | ||
| 
 | ||
| В Linux системах существуют разные планировщики процессов в отношении ввода-вывода. Раньше использовался Cfq, и ionice работает только с ним. В современных системах используется более эффективный планировщик Deadline. Проверить планировщик можно так:
 | ||
| ```
 | ||
| # cat /sys/block/sda/queue/scheduler
 | ||
| [none] mq-deadline
 | ||
| ```
 | ||
| Принципиальная разница этих планировщиков в том, что cfq равномерно распределяет процессы с операциями ввода-вывода, и это нормально подходит для hdd, а deadline отдаёт приоритет чтению в ущерб записи, что в целом уменьшает отклик для ssd дисков. С ними использовать его более рационально. Можно заставить работать ionice, но тогда придётся вернуть планировщик cfq, что не хочется делать, если у вас ssd диски.
 | ||
| 
 | ||
| Для планировщика deadline не смог найти простого и наглядного решения приоритизации процессов записи на диск. Стандартным решением по ограничению скорости, по типу того, что делает pv, является использование параметров systemd:
 | ||
| 
 | ||
| - **IOReadBandwidthMax** - объём данных, который сервису разрешается прочитать с блочных устройств за одну секунду;
 | ||
| - **IOWriteBandwidthMax** - объём данных, который сервису разрешается записать на блочные устройства за одну секунду.
 | ||
| 
 | ||
| Причём у него есть также параметр IODeviceWeight, что является примерно тем же самым, что и приоритет. Но работает он тоже только с cfq.
 | ||
| 
 | ||
| Для того, чтобы ограничить скорость записи на диск с помощью systemd, необходимо создать юнит для этого. Покажу на примере создания тестового файла с помощью dd с ограничением скорости записи в 20 мегабайт в секунду. 
 | ||
| ```
 | ||
| [Unit]
 | ||
| Description=Create file with dd
 | ||
| [Service]
 | ||
| IOWriteBandwidthMax=/dev/sda 20M
 | ||
| ExecStart=/usr/bin/dd if=/dev/zero of=/tempfile bs=1M count=1000 oflag=sync
 | ||
| [Install]
 | ||
| WantedBy=multi-user.target
 | ||
| ```
 | ||
| Запускаем:
 | ||
| ```
 | ||
| # systemctl start createfile.service
 | ||
| ```
 | ||
| Проверяем:
 | ||
| ```
 | ||
| # systemctl status createfile.service
 | ||
| systemd[1]: Started createfile.service - Create file with dd.
 | ||
| dd[1423]: 1000+0 records in
 | ||
| dd[1423]: 1000+0 records out
 | ||
| dd[1423]: 1048576000 bytes (1.0 GB, 1000 MiB) copied, 52.417 s, 20.0 MB/s
 | ||
| systemd[1]: createfile.service: Deactivated successfully.
 | ||
| ```
 | ||
| Это можно использовать как заготовку для реального задания. Если хочется потестировать в консоли, то запускайте так:
 | ||
| ```
 | ||
| # systemd-run --scope -p IOWriteBandwidthMax='/dev/sda 20M' dd status=progress if=/dev/zero of=/tempfile bs=1M count=1000 oflag=sync
 | ||
| ```
 | ||
| Простое рабочее решение без использования дополнительных утилит. Обращаю внимание, что если сработает кэширование записи, то визуально ограничение можно не увидеть. Я это наблюдал. И только с флагом sync её хорошо сразу же видно.
 | ||
| 
 |