Есть ли способ записи на SSD, чтобы при его отключении в процессе записи данные не терялись?

У меня есть скрипт Python, который записывает движение с камеры на внешний SSD. Велика вероятность того, что компьютер (Raspberry Pi) получит удар и отключится от накопителя (или даже от это источник питания, но это уже другая тема, верно?), но я бы не хотел потерять данные, когда это произойдет. Это достижимо?

Я читал, что только последний цикл записи теряется, когда диск не извлекается безопасно. Что такое цикл записи и как я могу потенциально использовать его для достижения того, что хочу? Может быть, я мог бы записывать куски по 5 секунд (иметь циклы записи по 5 секунд), чтобы при отключении SSD терялось только 5 секунд, как вы думаете?

Как это будет применяться с точки зрения кода?

Сейчас я использую библиотеку Picamera, и она использует файловые потоки. Если SSD отключается, не хватает времени для close() потока, поэтому данные теряются? В моих тестах, когда я отключаю SSD, я получаю только первые 2-3 секунды видео, независимо от того, длится ли последовательность, которую я записываю, 1 минуту или 15 секунд.

Сразу после отключения SSD я обычно получаю сообщения об ошибках ядра в консоли (Linux):

Message from syslogd@raspberrypi at Nov 12 01:43:41 ...
 kernel:[  138.263099] Internal error: Oops: 5 [#1] PREEMPT SMP ARM

Message from syslogd@raspberrypi at Nov 12 01:43:41 ...
 kernel:[  138.366239] Process vc.ril.video_en (pid: 2403, stack limit = 0xb47c0210)

Message from syslogd@raspberrypi at Nov 12 01:43:41 ...
 kernel:[  138.374211] Stack: (0xb47c1c80 to 0xb47c2000)

Message from syslogd@raspberrypi at Nov 12 01:43:41 ...\
 kernel:[  138.379835] 1c80: 00000000 b5b84ce0 807fd650 b667536c a0000013 00000000 b47c1ccc b47c1ca8\

...

который замораживает все в этом сеансе консоли.

Иногда, но реже (примерно в 1/10 раза), ядро ​​не выдает ошибки, но скрипт вызывает исключение (IOError: [Errno 5] Input/output error) и показывает в консоли трассировку стека.

Любое понимание ценится!

Ваше здоровье!


person maximedupre    schedule 14.11.2015    source источник
comment
Если вы не планировали хранить данные в памяти до того, как они будут записаны на жесткий диск, ответ, скорее всего, будет отрицательным. Но это также зависит от того, сколько памяти у вашей системы и какую кодировку файлов вы используете.   -  person Makoto    schedule 14.11.2015
comment
Когда вы говорите, что если вы не планировали хранить данные в памяти до того, как они будут записаны на жесткий диск, вы имеете в виду сохранение данных до тех пор, пока SSD не будет снова подключен к компьютеру? В системе 1 Гб оперативной памяти и кодировка файлов H264. Однако видео записываются в формате 1080p30, поэтому пространство быстро заполняется, хотя это может быть решением.   -  person maximedupre    schedule 14.11.2015
comment
Периодический вызов fsync() или sync() приведет к принудительной записи данных на диск. Любые вызовы write() перед вызовами fsync() или sync() будут отправлены на диск до того, как вызов sync вернется. Будет хит производительности, потенциально очень большой.   -  person Evan    schedule 14.11.2015
comment
Вы не можете исправить аппаратные проблемы в программном обеспечении. В данном конкретном случае трудно даже смягчить потери. Подтяните фурнитуру.   -  person msw    schedule 02.01.2016


Ответы (2)


Когда ваше приложение вызывает «write()», Linux на самом деле не записывает данные на диск. (Если бы это было так, все было бы очень медленно.)

Причина в том, что диски очень медленны при «поиске» (перемещении по диску), но очень быстры при «потоковой передаче» (последовательной записи данных). Таким образом, Linux будет буферизовать данные в памяти, а затем записывать их большими последовательными порциями.

По умолчанию Linux хранит данные в памяти до 30 секунд, прежде чем они будут записаны. Если это слишком много для вас, вы можете настроить его. Попробуйте echo 500 > /proc/sys/vm/dirty_expire_centiseconds попробовать записывать данные каждые 5 секунд.

См.: http://www.westnet.com/~gsmith/content/linux-pdflush.htm https://lonesysadmin.net/2013/12/22/better-linux-disk-caching-performance-vm-dirty_ratio/

person BraveNewCurrency    schedule 14.11.2015
comment
Если Linux хранит 30 секунд данных в памяти, почему я получаю только 2-3-секундный клип, когда я пишу на диск в течение 1 минуты? Разве я не должен получить 30-секундный клип? И еще, почему у меня получается клип 2-3 секунды, если я пишу на диск 20 секунд? - person maximedupre; 15.11.2015
comment
Возможно, причина, по которой я получаю 2-3-секундные клипы при записи в течение 15 секунд, заключается в том, что Пикамера вызывает fsync в начале. И, может быть, причина, по которой я получаю 2-3-секундные клипы при записи в течение 1 минуты, заключается в том, что я не вызываю flush, который оставляет данные в буфере Python, не позволяя ОС обрабатывать их. - person maximedupre; 15.11.2015

Вот что я сделал, чтобы гарантировать, что будет потеряно очень небольшое количество данных.

  1. Отключите режим буферизации файлового объекта, передав 0 в аргумент buffering метода open (работает только при открытии файлов в бинарном режиме, например, open(fileName, 'wb+', 0)). Вы также можете вызвать flush вручную, чтобы очистить файловый буфер после write.
  2. Как указал @Evan, периодически вызывайте sync или fsync, чтобы принудительно записать данные на диск. Любые вызовы write() перед вызовами fsync() или sync() будут отправлены на диск до того, как вызов sync вернется. Будет хит производительности, потенциально очень большой.
person maximedupre    schedule 02.01.2016