2016-11-07 17 views
1

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

Метод обнаружения и расчета этого топ-32 размер файла приведен в Technet блоге: https://blogs.technet.microsoft.com/askds/2011/07/13/how-to-determine-the-minimum-staging-area-dfsr-needs-for-a-replicated-folder/

Он основан на использовании Get-ChildItem, чтобы найти все файлы и их размеры в пути, сортировать по размеру, отбросить все но 32 крупнейших, а затем вычислить сумму.

Это нормально, когда у вас ограниченное количество файлов на вашем пути, но есть серьезные недостатки при индексировании папки сотен тысяч, если не миллионов файлов. Процесс сбрасывает все в память во время его выполнения - в моем примере он потребляет более 2 ГБ виртуальной памяти - и занимает много времени, даже когда отдельные файлы довольно малы. Память остается выделенной до тех пор, пока экземпляр PS не будет закрыт.

PS C:\> measure-command { (get-childitem F:\Folder\with\966693\items -recurse | 
sort-object length -descending | select-object -first 32 | 
measure-object -property length -sum).sum } 
Days    : 0 
Hours    : 0 
Minutes   : 6 
Seconds   : 6 
Milliseconds  : 641 
Ticks    : 3666410633 
TotalDays   : 0.00424353082523148 
TotalHours  : 0.101844739805556 
TotalMinutes  : 6.11068438833333 
TotalSeconds  : 366.6410633 
TotalMilliseconds : 366641.0633 

ответ

0

С небольшой подстройкой - инстанцирование System.Collections.ArrayList, чтобы сохранить список длин файлов - время, чтобы выполнить запрос через тот же каталог, почти в два раз. Вы добавляете к нему новый элемент not constantly creating/destroying a standard fixed-sized array.

Использование памяти для процесса Powershell для этого образца остается на уровне менее 900 МБ. Мне также нравится иметь переменную, чтобы установить значение $ null, если я хочу повторно использовать консоль PS.

measure command { $total = New-Object System.Collections.ArrayList; 
gci F:\Folder\with\966693\items -file -r | 
ForEach { $total.Add($_.length)>$null } ; 
(($total | sort -descending | select -first 32 |measure-object -sum).sum/1GB) } 
Days    : 0 
Hours    : 0 
Minutes   : 3 
Seconds   : 34 
Milliseconds  : 215 
Ticks    : 2142159038 
TotalDays   : 0.00247935073842593 
TotalHours  : 0.0595044177222222 
TotalMinutes  : 3.57026506333333 
TotalSeconds  : 214.2159038 
TotalMilliseconds : 214215.9038 

опрятнее версия многострочный:

$total = New-Object System.Collections.ArrayList 
gci F:\Folder\with\966693\items -file -r | ForEach { $total.Add($_.length)>$null } 
($total | sort -descending | select -first 32 | measure-object -sum).sum/1GB 
1

Я был бы удивлен, если вы могли бы ускорить Get-ChildItem много, если вы не могли бы избежать строительства [IO.FileInfo] объектов для каждого файла (.Net DirectorySearcher может быть?) ,

Но вы можете уменьшить требования к памяти, не сохраняя всех результатов, только текущий N наибольший, 100 в этом примере, но приспосабливайтесь к тестированию памяти/производительности, например.

$BufferSize = 100 
$FileSizes = New-Object System.Collections.ArrayList 

Get-ChildItem 'd:\downloads' -Force -Recurse -File | ForEach { 

    $null = $FileSizes.Add($_.Length) 
    if ($FileSizes.Count -gt $BufferSize) 
    { 
     $FileSizes.Sort() 
     $FileSizes.RemoveRange(0, ($BufferSize-32)) 
    } 
} 
($FileSizes[0..31] | measure-object -Sum).Sum/1GB 

Добавлен параметр -Force в GCI в случае, если некоторые из самых больших файлов скрыты.

+0

Спасибо, что выглядит еще эффективнее, сбрасывая ненужные результаты. Что касается моих результатов, они были довольно последовательны при тестировании с файлами 100K + в деревьях папок. Я хотел исправить эту проблему, потому что в основном я получал утечку памяти на сервере каждый раз, когда я пробовал исходный процесс на 1,2 млн. Наборов файлов элементов. Особенностью этих конкретных наборов файлов является то, что большая часть из них состоит из файлов размером <5 КБ. – Trix