Я писал простой скрипт на python для чтения и восстановления данных из вышедшего из строя массива RAID5, который я не смог восстановить каким-либо другим способом. Мой сценарий работает, но медленно. Мой оригинальный сценарий работал со скоростью около 80 МБ / мин. С тех пор я улучшил сценарий, и он работает со скоростью 550 МБ / мин, но это все еще кажется немного низким. Скрипт python работает на 100% процессорной мощности, поэтому он, скорее всего, загружен, а не ограничен диском, что означает, что у меня есть возможность для оптимизации. Поскольку сценарий совсем не длинный, я не могу эффективно его профилировать, поэтому я не знаю, что все это съедает. Вот мой сценарий в его нынешнем виде (или, по крайней мере, важные биты)
disk0chunk = disk0.read(chunkSize)
#disk1 is missing, bad firmware
disk2chunk = disk2.read(chunkSize)
disk3chunk = disk3.read(chunkSize)
if (parityDisk % 4 == 1): #if the parity stripe is on the missing drive
output.write(disk0chunk + disk2chunk + disk3chunk)
else: #we need to rebuild the data in disk1
# disk0num = map(ord, disk0chunk) #inefficient, old code
# disk2num = map(ord, disk2chunk) #inefficient, old code
# disk3num = map(ord, disk3chunk) #inefficient, old code
disk0num = struct.depack("16384l", disk0chunk) #more efficient new code
disk2num = struct.depack("16384l", disk2chunk) #more efficient new code
disk3num = struct.depack("16384l", disk3chunk) #more efficient new code
magicpotato = zip(disk0num,disk2num,disk3num)
disk1num = map(takexor, magicpotato)
# disk1bytes = map(chr, disk1num) #inefficient, old code
# disk1chunk = ''.join(disk1bytes) #inefficient, old code
disk1chunk = struct.pack("16384l", *disk1num) #more efficient new code
#output nonparity to based on parityDisk
def takexor(magicpotato):
return magicpotato[0]^magicpotato[1]^magicpotato[2]
Полужирный шрифт для обозначения актуальных вопросов внутри этого гигантского блока текста:
Могу ли я что-нибудь сделать, чтобы сделать это быстрее / лучше? Если ничего не приходит на ум, могу ли я что-то сделать, чтобы лучше исследовать, что заставляет это идти медленно? (Есть ли способ профилировать Python на уровне строки?) Я даже правильно обращаюсь с этим или есть лучший способ обработки огромных объемов двоичных данных?
Причина, по которой я спрашиваю, состоит в том, что я перестраиваю диск объемом 3 ТБ, и хотя он работает правильно (я могу смонтировать образ ro, зациклить и просматривать файлы), это занимает много времени. Я измерил его до середины января со старым кодом, теперь он будет работать до Рождества (так что это в порядке лучше, но все равно медленнее, чем я ожидал).
Прежде чем вы спросите, это mdadm RAID5 (размер блока 64 КБ, слева симметричный), но метаданные mdadm как-то отсутствуют, и mdadm не позволяет перенастроить RAID5 без перезаписи метаданных на диск, чего я пытаюсь избежать Во что бы то ни стало, я не хочу рисковать, что-то напутать и потерять данные, как бы отдаленно это ни было.