Как избежать физического дискового ввода-вывода - PullRequest
3 голосов
/ 23 августа 2011

У меня есть процесс, который записывает огромные данные по сети.Допустим, он работает на машине A и выдает около 70-80 ГБ файла на машине B через NFS.После завершения и завершения процесса 1 мой процесс 2 запускается на машине A и получает этот файл с машины B по NFS.Узким местом во всем цикле является запись и чтение этого огромного файла данных.Как я могу сократить это время ввода / вывода?Можно ли каким-то образом сохранить данные, загруженные в память, готовыми к использованию процессом 2 даже после завершения процесса 1?

Буду признателен за идеи по этому поводу.Спасибо.

Редактировать: поскольку процесс 2 «читает» данные непосредственно из сети, было бы лучше сначала скопировать данные локально, а затем прочитать с локального диска?Я имею в виду (время чтения по сети)> (cp на локальный диск) + (чтение с локального диска)

Ответы [ 6 ]

2 голосов
/ 23 августа 2011

Если вы хотите сохранить данные в памяти, вам потребуется 70-80 ГБ ОЗУ.

Лучше всего подключить локальное хранилище (жесткий диск) к системе А, чтобысохраните этот файл локально.

1 голос
/ 23 августа 2011

Независимо от того, используете ли вы mmap или просто read / write, это не имеет большого значения;в любом случае, все происходит через кеш / буферы файловой системы.Большая проблема - NFS.Единственный способ сделать это эффективным - хранить промежуточные данные локально на компьютере A, а не отправлять их по всей сети на компьютер B, а затем сразу же возвращать их обратно.

1 голос
/ 23 августа 2011

При таком подходе много сетевых и операций ввода-вывода. Таким образом, вы не сможете уменьшить задержку еще ниже.

  1. Поскольку размер файла превышает 80 ГБ, создайте mmap, в который будет записывать процесс 1, и позже процесс 2 сможет читать из него - сеть не задействована, используйте только компьютер A - но все еще будут накладные расходы ввода-вывода неизбежный.
  2. Еще быстрее: оба процесса могут выполняться одновременно, и у вас может быть семафор или другой механизм сигнализации, в котором процесс 1 может указать процессу 2, что файл готов к чтению.
  3. Самый быстрый подход: пусть процесс 1 создаст общую память и поделится ею с процессом 2. Всякий раз, когда достигается предел (максимальный блок данных, который может быть загружен в память в зависимости от размера вашей ОЗУ), пусть процесс 1 сигнализирует процессу 2 что данные могут быть прочитаны и обработаны - это решение будет осуществимо только в том случае, если файл / данные могут фактически обрабатываться порциями вместо одного большого блока из ваших 80 ГБ.
1 голос
/ 23 августа 2011

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

0 голосов
/ 23 августа 2011

Используйте tmpfs , чтобы использовать память как (временные) файлы.

Используйте mbuffer с netcat для простой ретрансляции с одного порта на другойбез сохранения промежуточного потока, но все же позволяющий осуществлять потоковую передачу с различными скоростями:

machine1: 8001 -> machine2: 8002 -> machine3: 8003

На компьютере 2 настроитьработа вроде:

 netcat -l -p 8002 | mbuffer -m 2G | netcat machine3 8003

Это позволит буферизировать не более 2 гигабайт данных.Если буфер заполнен на 100%, machine2 просто начнет блокировать чтения с machine1, задерживая поток вывода без сбоев.

Когда машина1 завершила передачу, вторая netcat будет оставаться до тех пор, пока mbuffer не будет исчерпан

0 голосов
/ 23 августа 2011
  1. Вы можете использовать RAM-диск в качестве хранилища
  2. NFS работает медленно. Попробуйте использовать альтернативный способ передачи данных на другой компьютер. Для примера - поток TCP / IP.
  3. Другое решение - вы можете использовать базу данных памяти (TimesTen для образца)
...