2015-11-19 4 views
2

У меня есть ежедневный процесс, который работает в 20 папках с 60k + файлами в нем. Нет подпапок, а входных файлов - не более МБ. Для каждой папки я читаю файлы, разбираю он и записывает некоторые данные в отдельный выходной файл (т. е. 20 выходных файлов). Недавно я обновил наш сервер (более высокие ядравыше памяти) и заметил резкое снижение производительности. Надеюсь, кто-то может указать мне на проблему.Parallel.ForEach медленнее после обновления сервера

Ниже мой код

int iFolderCount = 0; 
DirectoryInfo oSourceFolder = new DirectoryInfo(sInputFolder); 
DirectoryInfo[] oIdDirectoryList = oSourceFolder.GetDirectories().Where(Id => sFolderList.Contains(Id.Name.ToUpper())).ToArray<DirectoryInfo>(); 
Parallel.ForEach(oIdDirectoryList, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, (oId, state) => 
{ 
    FileInfo[] sFileList = oId.GetFiles(); 
    RawCounter.GetOrAdd(oId.Name.ToUpper(), sFileList.Length); 

    using (StreamWriter oHandoffWriter = new StreamWriter(new FileStream(string.Format("{0}{1}_{2}_{3}{4}", sOutputFolder, Day, sOutputFileName, Interlocked.Increment(ref iFolderCount), HANDOFF_FILE_EXTENSION),FileMode.Append,FileAccess.Write,FileShare.Write))) 
    { 
     int iFileCounter = 0; 
     foreach (FileInfo oFileInfo in sFileList) 
     { 
      try 
      { 
       ProcessFile(oFileInfo, oHandoffWriter); 
       iFileCounter++; 
      } 
      catch (Exception ex) 
      { 
       oLog.Info("Failed to process file " + oFileInfo.Name); 
       oLog.Info(ex.Message); 
       oLog.Info(ex.StackTrace); 
       oLog.Info(ex.InnerException); 
       File.Copy(oFileInfo.FullName, sErrorFileFolderPath + oFileInfo.Name, true); 
      } 
     } 
     ProcessedCounter.GetOrAdd(oId.Name.ToUpper(), iFileCounter); 
    } 
}); 

После перехода процесса на новый сервер, я заметил резкое снижение performance.We пошло от 8 ядер до 36 ядер и 8 Гб оперативной памяти, до 128 Гб оперативной памяти.

Server Configuration

Я начал уменьшения степени параллелизма и заметил, что процесс выполняется лучше каждый раз, я уменьшил степень параллельности.

MaxDegreeOfParallelism = 2 

Установив его в 2, я вижу более высокую производительность. Что мне здесь не хватает? MaxDegreeOfParallelism = Environment.ProcessorCount работает быстрее на более старом сервере с сервером Windows 2008, 8 Core, 8 ГБ, а MaxDegreeOfParallelism = 2 быстрее на новом сервере Windows 2012, 32 Core, 128 ГБ оперативной памяти.

EDIT: Я согласен с тем, что процесс имеет интенсивный объем ввода-вывода. Ежедневный размер файла/размер файла не сильно отличается. Ниже приведены полные времена для процесса на старом сервере.

  • Передача обслуживания завершена на день 20151028. Процесс потребовался 504.05125171 минут.
  • Передача обслуживания завершена на день 20151027. Процесс занял 504.37106602 минут.
  • Передача обслуживания завершена на день 20151026. Процесс занимает 549.76132134 минут.
  • Передача обслуживания завершена на день 20151025. Процесс занимает 541.97557402 минут.
  • Передача обслуживания завершена на день 20151024. Процесс занимает 567.14474476 минут.
  • Передача обслуживания завершена на день 20151023. Процесс обработан 513.51368027 минут.
  • Передача обслуживания завершена на день 20151022. Процесс составил 595.21733215 минут.

На новом сервере, когда я использовал Environment.ProcessorCount
- хэндовера завершена за день 20151118.The процесс занял +712,05125171 минут.

На новом сервере, когда я использовал как степень параллельности
- хэндовера завершена за день 20151118.The процесс занял +89,61782427 минут.

Я сделаю больше запусков и обновит этот вопрос.

+1

Похоже, вы задыхаетесь от ввода-вывода. Как ваши диски? – spender

ответ

4

Обработка не привязана ни к процессору, ни к памяти, так что новый сервер вообще не помогает. Кажется, я связан. Изменилось ли оборудование IO? Параллелизм плюс IO может легко означать более медленную производительность, поскольку последовательный IO может быть превращен в случайный IO.

Ошибочно выбирать DOP для ввода-вывода на основе количества ядер процессора. Оптимальная IO DOP не связана с подсчетом ядра. Определите оптимальный DOP эмпирически.

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