Как инженер-программист, бывают случаи, когда вам нужна более медленная система.
На самом деле это происходит не часто: обычно, когда кто-то сообщает об ошибке в вашем программном обеспечении, которую вы никогда раньше не видели и которую вы не можете воспроизвести.
В большинстве случаев причиной этих призрачных ошибок являются условия гонки .
Условия гонки — это проблемы, с которыми вы можете столкнуться при многопоточном программировании . Представьте, что ваше программное обеспечение делает несколько вещей одновременно. Несмотря на то, что в большинстве случаев эти вещи происходят в понятном и интуитивном порядке, иногда этого не происходит; приводя к неожиданному состоянию вашей программы.
Они действительно ошибка. Это вина разработчика. Но у разработчика не так много способов защитить себя от них. Существуют стили и технологии программирования, которые заставляют вас избегать риска в целом, но я думаю, что в целом это условие, с которым должен быть знаком каждый разработчик.
Так почему медленная система помогает?
Поскольку в большинстве случаев условия гонки маскируются тем фактом, что операции все еще происходят «достаточно быстро» . Это неоднозначное «достаточно быстро» является главной проблемой . Там нет четкого ограничения или числа, которое говорит вам, как быстро. У вас просто больше шансов увидеть их, если все происходит достаточно медленно, чтобы показать, что они не происходят в правильном порядке или они не ожидают правильных контрольных точек.
По моему опыту работы с Java-приложениями, основным аспектом, связанным с производительностью, при воспроизведении состояния гонки является скорость доступа к диску. Больше, чем скорость процессора или объем оперативной памяти, я заметил, что скорость диска — это самая большая разница между аналогичными системами.
В этом посте я покажу, как имитировать медленный жесткий диск в Linux, чтобы увеличить ваши шансы воспроизвести условия гонки.
Решение будет основано на nbd
и trickle
и будет использовать сетевой уровень для регулирования пропускной способности nbd
для вашего виртуального жесткого диска.
Я хотел бы добавить, что в этом нет ничего нового, и что я не предлагаю какой-либо особенно революционный подход. Есть много постов, которые описывают, как этого добиться. Но по многим причинам ни одна из тех, что я прочитал, не работала из коробки на моих установках Fedora 22 или Centos 6.
Это главная причина, побудившая меня вернуться в Интернет , добавив, что может быть, просто еще одну страницу с аргументом.
Давайте начнем с идеи использования ndb
или сетевого блочного устройства для имитации нашего жесткого диска.
Насколько я понимаю, нет никаких официальных способов, предоставляемых ядром Linux для регулирования скорости ввода-вывода типовых блочных устройств.
В Интернете вы можете найти много предложений, начиная с отключения кэша чтения и записи, чтобы генерировать реальную нагрузку, которая может сделать вашу систему занятой.
QoS может быть реализовано на сетевом уровне . Таким образом, идея состоит в том, чтобы эмулировать блочное устройство через сеть.
Несмотря на то, что это может показаться очень сложным (и, возможно, это так), проблема уже была решена ядром Linux с модулем nbd
.
Поскольку на моей Fedora 22 этот модуль не включен автоматически по умолчанию, мы должны сначала установить его, а затем включить:
1
2
3
4
5
6
7
8
9
|
# install nbd module sudo yum install ndb # load nbd module sudo modprobe nbd # check nbd module is really loaded lsmod | grep nbd nbd 20480 0 |
Теперь, когда nbd
установлен и модуль загружен, мы создаем файл конфигурации для его демона:
1
2
3
4
5
6
7
|
# run this command as root "cat > /etc/nbd-server/config" <<EOF [generic] [ test ] exportname = /home/pantinor/test_nbd copyonwrite = false EOF |
Где exportname
— это путь к файлу, который будет представлять ваш медленный виртуальный exportname
.
Вы можете создать файл с помощью этой команды:
1
2
|
# create an empty file, and reserve it 1GB of space dd if = /dev/zero of= /home/pantinor/test_nbd bs=1G count=1 |
Теперь, когда конфиг и файлы назначения на месте, вы можете запустить nbd-server
с помощью демона:
1
2
3
4
5
|
# start ndb-server daemon sudo systemctl start nbd-server.service # monitor the daaemon start up with: journalctl -f --unit nbd-server.service |
На этом этапе у вас есть сетевой процесс сервера, прослушивающий порт 10809
которому может подключиться любой клиент вашей сети, чтобы смонтировать его как сетевое блочное устройство.
Мы можем смонтировать его с помощью этой команды:
1
2
3
4
|
# "test" corresponds to the configuration section in daemon config file sudo nbd-client -N test 127.0.0.1 10809 /dev/nbd0 # my Centos 6 version of nbd-client needs a slightly different synatx: # sudo nbd-client -N test 127.0.0.1 /dev/nbd0 |
Теперь мы создали виртуальное блочное устройство, которое называется /dev/nbd0
. Теперь мы можем отформатировать его так, как будто он был нормальным:
01
02
03
04
05
06
07
08
09
10
11
|
# format device sudo mkfs /dev/nbd0 # create folder for mounting sudo mkdir /mnt/nbd # mount device, sync option is important to not allow the kernel to cheat! sudo mount -o sync /dev/nbd0 /mnt/nbd # add write permissions to everyone sudo chmod a+rwx /mnt/nbd |
Не то чтобы мы передали команду mount
флаг -o sync
. Эта команда выполняет важную функцию : отключить расширение ядра Linux, которое задерживает завершение операций записи на устройства. Без этого все операции записи будут выглядеть мгновенно, и ядро фактически выполнит запросы записи в фоновом режиме. С этим флажком все операции будут ждать, пока операция действительно не завершится.
Вы можете проверить, что теперь вы можете читать и писать в точке монтирования /mnt/nbd
.
Давайте теперь временно размонтировать и отключиться от nbd-server
:
1
2
3
|
sudo umount /mnt/nbd sudo nbd-client -d /dev/nbd0 |
И давайте введем trickle
.
Trickle — это программа, которую вы можете использовать, чтобы обернуть другие процессы и ограничить их пропускную способность в сети.
Вы можете использовать его, чтобы ограничить любую другую программу. Простой тест, который вы можете выполнить с помощью curl
:
1
2
|
# download a sample file and limts download speed to 50 KB/s trickle -d 50 -u 50 curl -O http: //download .thinkbroadband.com /5MB .zip |
Теперь, как вы можете ожидать, нам просто нужно объединить поведение trickle
и nbd-server
, чтобы получить желаемое поведение.
Давайте начнем останавливать текущий nbd-server
, чтобы освободить его порт по умолчанию:
1
|
sudo systemctl stop nbd-server.service |
И давайте начнем с помощью trickle
:
1
2
|
# start nbd-server limiting its network throughput trickle -d 20 -u 20 - v nbd-server -d |
-d
присоединяет серверный процесс к консоли, поэтому консоль будет заблокирована и будет освобождена только после закрытия процесса или при отключении клиента .
Не обращайте внимания на сообщение об ошибке: trickle: Could not reach trickled, working independently: No such file or directory
Теперь вы можете повторно выполнить команды для подключения к nbd-server
и заново смонтировать его:
1
2
3
|
sudo nbd-client -N test 127.0.0.1 10809 /dev/nbd0 sudo mount -o sync /dev/nbd0 /mnt/nbd |
И вы сделали! Теперь у вас есть медленный /dev/nbd0
смонтированный в /dev/nbd0
.
Вы можете проверить медленное поведение следующим образом:
1
2
3
4
5
6
7
|
sudo dd if = /dev/nbd0 of= /dev/null bs=65536 skip=100 count=10 10+0 records in 10+0 records out 655360 bytes (655 kB) copied, 18.8038 s, 34.9 kB /s # when run against an nbd-server that doesn't use trickle the output is: # 655360 bytes (655 kB) copied, 0.000723881 s, 905 MB/s |
Теперь, когда у вас медленный раздел, вы можете просто поместить туда файлы вашего sw, чтобы имитировать медленный ввод / вывод.
Все вышеперечисленные шаги можно преобразовать в вспомогательные сценарии, которые значительно упростят процесс, подобный описанным здесь: http://philtortoise.blogspot.it/2013/09/simulation-slow-drive.html .
Ссылка: | Совет по отладке: как смоделировать медленный hardisk от нашего партнера JCG Паоло Антинори из блога Someday Never Comes . |