2014-03-25 4 views
4

Мой веб-сервис пишет несколько тысяч транзакций в минуту, и мы сохраняем их на hd.Недостатки использования файлов с отображением памяти

Я тестировал различные способы сохранения этих файлов, и я провел несколько тестов со стандартным IO и с файлами MemoryMapped. В моих результатах запись файлов (20 k текстовых файлов) с файлами MemoryMapped примерно в 4 раза быстрее, чем стандартный IO, и я не смог найти никаких недостатков.

Поскольку у меня не так много опыта с этой технологией, вы думаете, что я могу столкнуться с любой проблемой, использующей их, или вы не видите недостатка?

Спасибо!

EDIT 1, здесь источник:

namespace FileWritingTests.Writers { 
    public class MappedFileWriter : ITestWriter { 
     public void Write(string content, string path,string id) { 
      Byte[] data = System.Text.Encoding.UTF8.GetBytes(content); 

      using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) 

      using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(fileStream, id, data.Count(), 
       MemoryMappedFileAccess.ReadWrite, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, true)) { 
       var viewStream = memoryMapped.CreateViewStream(); 
       viewStream.Write(data, 0, data.Length);      
      } 
     } 
    } 
} 

и это тестер:

public TimeSpan Run(int iterations, Writers.ITestWriter tester, String subfolder) { 
      Console.WriteLine(" -- Starting test {0} with {1} file writings",subfolder, iterations.ToString()); 

      Stopwatch stopWatch = new Stopwatch(); 
      stopWatch.Reset(); 
      stopWatch.Start(); 
      for (int i = 1; i <= iterations; i++) { 
       tester.Write(transaction, this.path + "\\" + subfolder + "\\" + "file_" + i.ToString() + ".txt", i.ToString()); 
      } 
      stopWatch.Stop(); 
      TimeSpan ts = stopWatch.Elapsed; 

      Console.WriteLine(" -- finish test {0} with {1} file writings. Time Elapsed: {2}", subfolder, iterations.ToString(), ts.TotalMilliseconds); 
      return ts; 
     } 

тестер называется несколько раз, и есть несколько типов тестера называются для сравнения.

+0

Я буду беспокоиться о том, что происходит с содержимым файла, если программа или компьютер сбой. – AdrianHHH

+0

Просто идея/намек/мысль: Недавно я провел несколько тестов на MMF, но помимо проблемы с отказом я не любил идею предварительной настройки размера файла вверх (Ханс писал, что это не требуется во всех отношениях - думаю, я никогда не приходил эта точка). В итоге я закончил использование PersistentDictionary, поддерживаемого базой данных ESENT, и быструю сериализацию (protobuf). Объединение двух приложений теперь позволяет обрабатывать 20000+ записей в секунду синхронно, а скорость приближается к MMF. – Linky

+0

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

ответ

12

Основным недостатком MMF является то, что они потребляют ОЗУ, что делает кэш файловой системы менее эффективным. Не проблема с такими маленькими файлами.

Еще один недостаток, хотя, безусловно, намеренный, заключается в том, что вы больше не можете измерять стоимость записи файла. Теперь это работа, которую выполняет ядро, а не ваша программа. Это все еще делается, конечно, нет такой вещи, как бесплатный обед. Это одновременно с остальной частью исполнения вашей программы, так сказать, поточной резьбой. Следите за использованием ЦП процесса «Система» в диспетчере задач. Опять же, очень маловероятно, что это проблема с такими маленькими файлами.

Это микро-оптимизация, взорванная стоимостью создания файла. Который колеблется от 20 до 50 мс на шпиндельном диске. Не забудьте включить это в свои измерения. Запись данных файла работает на скоростях шины памяти, выше 5 гигабайт/с, в зависимости от типа оперативной памяти, которую имеет компьютер. Вырезали только низкоуровневые вызовы WriteFile(), теперь они выполняются ядром. Вы можете попробовать тестирование с помощью FileStream, используйте конструктор, который принимает значение bufferSize. Значение по умолчанию - 4096 байт, увеличьте его до 32K, так что есть только один вызов WriteFile(). Главное преимущество сделать это таким образом, что вам не нужно угадывать размер MMF спереди. Это становится очень уродливым, когда вы догадались слишком низко.

+0

Спасибо за подсказки, я добавлю к своему вопросу код, который я использую для своих тестов, и который я планирую использовать для своего сервера. – Rafa

Смежные вопросы