Wykorzystanie pamięci RAM metapliku systemu Windows Server 2008 R2

33

Mam serwer z systemem Windows Server 2008 R2 x64 z 4 GB pamięci RAM, który obsługuje około 2-3 miliony plików, z których większość to pliki graficzne.

W ciągu tygodnia zauważyłem, że aplikacje na serwerze zwalniają do indeksowania z powodu nadmiernego stronicowania na dysk z powodu niskiej pamięci, co powoduje efekt domina dla wszystkich aktualnie działających na nim usług, powodując poważne Problem z wydajnością.

Po sprawdzeniu w Menedżerze zadań zauważyłem, że prawie wszystkie 4 GB jest w użyciu, ale kiedy spojrzysz na zakładkę Procesy, suma całego zużycia pamięci nie sumuje się i najwyżej 1,5 GB powinno być w użyciu.

Używając Google do znalezienia rozwiązania, wydaje się, że większość pamięci RAM została wykorzystana w „Metapliku”, który jest pamięcią podręczną informacji NTFS dla plików w systemie plików, dzięki czemu system nie musi ponownie wysyłać zapytań do MFT o informacje. Ta pamięć podręczna nigdy nie jest czyszczona ani oznaczana jako „pamięć podręczna” w Menedżerze zadań lub jako „Czuwanie” w RamMap Sysinternal.

Była propozycja , aby zainstalować poprawkę KB979149 ale po próbuje go zainstalować, to mówi „Ta aktualizacja nie ma zastosowania do komputera”.

Jedyne tymczasowe poprawki, które do tej pory znalazłem, to:

  1. Użyj RAMmap z Sysinternals do „Opróżnij zestaw roboczy systemu” co 1-3 dni, co oznacza pamięć podręczną jako „tryb gotowości” i „pamięć podręczną” w Menedżerze zadań, dzięki czemu pamięć RAM może być używana przez inne aplikacje.
  2. Uruchom ponownie komputer, co jest niepożądane, ponieważ ten serwer obsługuje publiczne strony internetowe.

W tej chwili muszę wykonywać 2. naprawę co kilka dni, aby zapobiec osiągnięciu poziomów wąskiego gardła.

Przed: (Użyto 800 MB pamięci RAM - inne aplikacje nie mogą korzystać z tej pamięci RAM)

wprowadź opis zdjęcia tutaj

Po: (800 MB pamięci RAM oznaczonej jako pamięć podręczna - dostępne dla innych aplikacji)

Więc moje pytanie do was wszystkich brzmi: czy istnieje jakakolwiek metoda ograniczenia użycia pamięci RAM tego metapliku?

al2k4
źródło
4
4 GB pamięci RAM na serwerze, na którym przechowywane są 2-3 miliony plików, jest absurdalne. Zaktualizuj pamięć RAM lub zaktualizuj pamięć RAM.
pauska
1
Nieważne, CacheSet firmy Sysinternals pozwala mi ustawić rozmiar pamięci podręcznej, obecnie uruchamiam to w odstępach czasu, co rozwiązało problem!
al2k4
6
Dodanie pamięci RAM nie rozwiązuje problemu. Pamięć podręczna metaplików również ją zapełni. Próbowałem to zrobić na gościu VMware, który zaczął od 4 GB i zwiększył go do 12 GB i to samo się dzieje. Problem polega na tym, że ta pamięć służy do celów buforowania, ale zgodnie z systemem Windows nie jest oznaczona jako pamięć podręczna. Jest niepoprawnie oznaczony jako pamięć aktywna / w użyciu i niestety, gdy rośnie, wypiera PRAWDZIWĄ pamięć aktywną / w użyciu używaną przez rzeczywiste programy i rozpoczyna stronicowanie na dysk. Gdy fizyczna pamięć RAM zapełni się, wszystko zwalnia i musisz zrobić jedno z dwóch rozwiązań, jak wspomniano w pierwotnym poście.
@ al2k4 Jeśli pytanie zostało rozwiązane, zaznacz je jako rozwiązane, klikając znacznik wyboru obok poprawnej odpowiedzi. Witaj w Server Fault !
Michael Hampton

Odpowiedzi:

16

Najlepszą metodą radzenia sobie z tym problemem jest użycie SetSystemFileCacheSizeinterfejsu API zgodnie z instrukcją stosowaną w instrukcji MS KB976618 .

Nie czyść okresowo pamięci podręcznej

Używanie tej SetSystemFileCacheSizefunkcji zamiast czyszczenia pamięci podręcznej okresowo poprawia wydajność i stabilność. Okresowe czyszczenie pamięci podręcznej spowoduje usunięcie zbyt dużej ilości metaplików i innych informacji z pamięci, a system Windows będzie musiał ponownie odczytać wymagane informacje z powrotem do pamięci RAM z dysku twardego. Powoduje to nagły i poważny spadek wydajności przez kilka sekund po każdym wyczyszczeniu pamięci podręcznej, a następnie dobrą wydajność, która powoli spada, gdy pamięć zapełnia się danymi metapliku.

Korzystanie z SetSystemFileCacheSizezestawów funkcji minimum i maksimum, co spowoduje oznaczenie przez Windows nadmiaru starych danych metapliku jako pamięci rezerwowej, którą normalne funkcje buforowania mogą wykorzystywać lub odrzucać zgodnie z bieżącymi wymaganiami zasobów i normalnymi priorytetami pamięci podręcznej. Pozwala to również na umieszczenie większej ilości danych metapliku niż ustawione maksimum pamięci aktywnej, jako dane rezerwowe, jeśli system Windows nie używa pamięci do niczego innego, zachowując jednocześnie dużo dostępnej pamięci. Jest to idealna sytuacja przez cały czas utrzymująca dobre parametry systemu.

Programy innych firm nie są obsługiwane przez MS

Jeśli jesteś podobny do mnie i nie chcesz uruchamiać pliku binarnego od nieznanej strony trzeciej na twoich serwerach produkcyjnych, potrzebujesz oficjalnego narzędzia MS lub kodu, który możesz sprawdzić przed uruchomieniem na tych serwerach. Narzędzie DynCache dla 2008 R2 jest praktycznie niemożliwe do uzyskania z M $ bez płacenia za zgłoszenie do pomocy technicznej i, szczerze mówiąc, w oparciu o kod z 2008 roku wydaje się nadmiernie rozdęte dla zadania, ponieważ Windows ma już wbudowaną logikę potrzebną do dynamicznego rozmiaru pamięć podręczna - wystarczy znać odpowiednie maksimum dla twojego systemu.

Rozwiązanie wszystkich powyższych

Napisałem skrypt Powershell, który działa na komputerach 64-bitowych. Musisz uruchomić go jako administrator z podwyższonymi uprawnieniami. Powinieneś być w stanie go uruchomić, tak jak jest, na dowolnym systemie Windows x64 Vista / Server 2008 do 10 / Server 2012 R2 włącznie z dowolną ilością pamięci RAM. Nie musisz instalować żadnego dodatkowego oprogramowania, dzięki czemu Twój serwer / stacja robocza będzie w pełni obsługiwana przez MS.

Powinieneś uruchomić ten skrypt przy każdym rozruchu z podwyższonymi uprawnieniami, aby ustawienie było trwałe. Harmonogram zadań systemu Windows może to zrobić za Ciebie. Jeśli instalacja systemu Windows znajduje się na maszynie wirtualnej i zmienisz ilość pamięci RAM przydzielonej do tej maszyny wirtualnej, powinieneś ją również uruchomić po tej zmianie.

Możesz uruchomić ten skrypt w dowolnym momencie na uruchomionym systemie, nawet w trybie produkcyjnym, bez konieczności ponownego uruchamiania systemu lub zamykania jakichkolwiek usług.

# Filename: setfc.ps1
$version = 1.1

#########################
# Settings
#########################

# The percentage of physical ram that will be used for SetSystemFileCache Maximum
$MaxPercent = 12.5

#########################
# Init multipliers
#########################
$OSBits = ([System.IntPtr]::Size) * 8
switch ( $OSBits)
{
    32 { $KiB = [int]1024 }
    64 { $KiB = [long]1024 }
    default {
        # not 32 or 64 bit OS. what are you doing??
        $KiB = 1024 # and hope it works anyway
        write-output "You have a weird OS which is $OSBits bit. Having a go anyway."
    }
}
# These values "inherit" the data type from $KiB
$MiB = 1024 * $KiB
$GiB = 1024 * $MiB
$TiB = 1024 * $GiB
$PiB = 1024 * $TiB
$EiB = 1024 * $PiB


#########################
# Calculated Settings
#########################

# Note that because we are using signed integers instead of unsigned
# these values are "limited" to 2 GiB or 8 EiB for 32/64 bit OSes respectively

$PhysicalRam = 0
$PhysicalRam = [long](invoke-expression (((get-wmiobject -class "win32_physicalmemory").Capacity) -join '+'))
if ( -not $? ) {
    write-output "Trying another method of detecting amount of installed RAM."
 }
if ($PhysicalRam -eq 0) {
    $PhysicalRam = [long]((Get-WmiObject -Class Win32_ComputerSystem).TotalPhysicalMemory) # gives value a bit less than actual
}
if ($PhysicalRam -eq 0) {
    write-error "Cannot Detect Physical Ram Installed. Assuming 4 GiB."
    $PhysicalRam = 4 * $GiB
}
$NewMax = [long]($PhysicalRam * 0.01 * $MaxPercent)
# The default value
# $NewMax = 1 * $TiB


#########################
# constants
#########################

# Flags bits
$FILE_CACHE_MAX_HARD_ENABLE     = 1
$FILE_CACHE_MAX_HARD_DISABLE    = 2
$FILE_CACHE_MIN_HARD_ENABLE     = 4
$FILE_CACHE_MIN_HARD_DISABLE    = 8


################################
# C# code
# for interface to kernel32.dll
################################
$source = @"
using System;
using System.Runtime.InteropServices;

namespace MyTools
{
    public static class cache
    {
        [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool GetSystemFileCacheSize(
            ref IntPtr lpMinimumFileCacheSize,
            ref IntPtr lpMaximumFileCacheSize,
            ref IntPtr lpFlags
            );

        [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool SetSystemFileCacheSize(
          IntPtr MinimumFileCacheSize,
          IntPtr MaximumFileCacheSize,
          Int32 Flags
        );

        [DllImport("kernel32", CharSet = CharSet.Unicode)]
        public static extern int GetLastError();

        public static bool Get( ref IntPtr a, ref IntPtr c, ref IntPtr d )
        {
            IntPtr lpMinimumFileCacheSize = IntPtr.Zero;
            IntPtr lpMaximumFileCacheSize = IntPtr.Zero;
            IntPtr lpFlags = IntPtr.Zero;

            bool b = GetSystemFileCacheSize(ref lpMinimumFileCacheSize, ref lpMaximumFileCacheSize, ref lpFlags);

            a = lpMinimumFileCacheSize;
            c = lpMaximumFileCacheSize;
            d = lpFlags;
            return b;
        }


        public static bool Set( IntPtr MinimumFileCacheSize, IntPtr MaximumFileCacheSize, Int32 Flags )
        {
            bool b = SetSystemFileCacheSize( MinimumFileCacheSize, MaximumFileCacheSize, Flags );
            if ( !b ) {
                Console.Write("SetSystemFileCacheSize returned Error with GetLastError = ");
                Console.WriteLine( GetLastError() );
            }
            return b;
        }
    }

    public class AdjPriv
    {
        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);

        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);

        [DllImport("advapi32.dll", SetLastError = true)]
        internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        internal struct TokPriv1Luid
        {
            public int Count;
            public long Luid;
            public int Attr;
        }
        internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
        internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
        internal const int TOKEN_QUERY = 0x00000008;
        internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;

        public static bool EnablePrivilege(long processHandle, string privilege, bool disable)
        {
            bool retVal;
            TokPriv1Luid tp;
            IntPtr hproc = new IntPtr(processHandle);
            IntPtr htok = IntPtr.Zero;
            retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
            tp.Count = 1;
            tp.Luid = 0;
            if(disable)
            {
                tp.Attr = SE_PRIVILEGE_DISABLED;
            } else {
                tp.Attr = SE_PRIVILEGE_ENABLED;
            }
            retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
            retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
            return retVal;
        }
    }
}
"@
# Add the c# code to the powershell type definitions
Add-Type -TypeDefinition $source -Language CSharp

#########################
# Powershell Functions
#########################
function output-flags ($flags)
{
    Write-output ("FILE_CACHE_MAX_HARD_ENABLE  : " + (($flags -band $FILE_CACHE_MAX_HARD_ENABLE) -gt 0) )
    Write-output ("FILE_CACHE_MAX_HARD_DISABLE : " + (($flags -band $FILE_CACHE_MAX_HARD_DISABLE) -gt 0) )
    Write-output ("FILE_CACHE_MIN_HARD_ENABLE  : " + (($flags -band $FILE_CACHE_MIN_HARD_ENABLE) -gt 0) )
    Write-output ("FILE_CACHE_MIN_HARD_DISABLE : " + (($flags -band $FILE_CACHE_MIN_HARD_DISABLE) -gt 0) )
    write-output ""
}

#########################
# Main program
#########################

write-output ""

#########################
# Get and set privilege info
$ProcessId = $pid
$processHandle = (Get-Process -id $ProcessId).Handle
$Privilege = "SeIncreaseQuotaPrivilege"
$Disable = $false
Write-output ("Enabling SE_INCREASE_QUOTA_NAME status: " + [MyTools.AdjPriv]::EnablePrivilege($processHandle, $Privilege, $Disable) )

write-output ("Program has elevated privledges: " + ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") )
write-output ""
whoami /PRIV | findstr /I "SeIncreaseQuotaPrivilege" | findstr /I "Enabled"
if ( -not $? )  {
    write-error "user Security Token SE_INCREASE_QUOTA_NAME: Disabled`r`n"
}
write-output "`r`n"


#########################
# Get Current Settings
# Init variables
$SFCMin = 0
$SFCMax = 0
$SFCFlags = 0
#Get Current values from kernel
$status = [MyTools.cache]::Get( [ref]$SFCMin, [ref]$SFCMax, [ref]$SFCFlags )
#typecast values so we can do some math with them
$SFCMin = [long]$SFCMin
$SFCMax = [long]$SFCMax
$SFCFlags = [long]$SFCFlags
write-output "Return values from GetSystemFileCacheSize are: "
write-output "Function Result : $status"
write-output "            Min : $SFCMin"
write-output ("            Max : $SFCMax ( " + $SFCMax / 1024 / 1024 / 1024 + " GiB )")
write-output "          Flags : $SFCFlags"
output-flags $SFCFlags


#########################
# Output our intentions
write-output ("Physical Memory Detected : $PhysicalRam ( " + $PhysicalRam / $GiB + " GiB )")
write-output ("Setting Max to " + $MaxPercent + "% : $NewMax ( " + $NewMax / $MiB + " MiB )`r`n")

#########################
# Set new settings
$SFCFlags = $SFCFlags -bor $FILE_CACHE_MAX_HARD_ENABLE # set max enabled
$SFCFlags = $SFCFlags -band (-bnot $FILE_CACHE_MAX_HARD_DISABLE) # unset max dissabled if set
# or if you want to override this calculated value
# $SFCFlags = 0
$status = [MyTools.cache]::Set( $SFCMin, $NewMax, $SFCFlags ) # calls the c# routine that makes the kernel API call
write-output "Set function returned: $status`r`n"
# if it was successfull the new SystemFileCache maximum will be NewMax
if ( $status ) {
    $SFCMax = $NewMax
}


#########################
# After setting the new values, get them back from the system to confirm
# Re-Init variables
$SFCMin = 0
$SFCMax = 0
$SFCFlags = 0
#Get Current values from kernel
$status = [MyTools.cache]::Get( [ref]$SFCMin, [ref]$SFCMax, [ref]$SFCFlags )
#typecast values so we can do some math with them
$SFCMin = [long]$SFCMin
$SFCMax = [long]$SFCMax
$SFCFlags = [long]$SFCFlags
write-output "Return values from GetSystemFileCacheSize are: "
write-output "Function Result : $status"
write-output "            Min : $SFCMin"
write-output ("            Max : $SFCMax ( " + $SFCMax / 1024 / 1024 / 1024 + " GiB )")
write-output "          Flags : $SFCFlags"
output-flags $SFCFlags

U góry znajduje się wiersz, który mówi, $MaxPercent = 12.5że ustawia nowy maksymalny zestaw roboczy (pamięć aktywna) na 12,5% całkowitej fizycznej pamięci RAM. System Windows dynamicznie zmieni rozmiar danych metapliku w aktywnej pamięci na podstawie wymagań systemowych, więc nie trzeba dynamicznie dostosowywać tego maksimum.

To nie rozwiąże żadnych problemów z zbyt dużą pamięcią podręczną mapowanych plików.

Zrobiłem również GetSystemFileCacheSizeskrypt Powershell i opublikowałem go na StackOverflow .


Edycja: Powinienem również zwrócić uwagę, że nie powinieneś uruchamiać żadnego z tych 2 skryptów z tej samej instancji Powershell więcej niż jeden raz, albo pojawi się błąd, że Add-Typewywołanie zostało już wykonane.

Edycja: zaktualizowano SetSystemFileCacheSizeskrypt do wersji 1.1, który oblicza odpowiednią wartość maksymalnej pamięci podręcznej i ma ładniejszy układ wyjściowy statusu.

Edycja: Teraz zaktualizowałem mój laptop z systemem Windows 7, mogę powiedzieć, że skrypt działa poprawnie w systemie Windows 10, chociaż nie przetestowałem, czy nadal jest potrzebny. Ale mój system jest nadal stabilny nawet podczas przenoszenia plików dysków twardych maszyny wirtualnej.

BeowulfNode42
źródło
Narzędzie DynCache jest bezpłatnie dostępne do pobrania z microsoft.com/en-us/download/details.aspx?id=9258 i obsługuje 2008 R2.
Jakub Berezański
To jest teraz. Od wydania systemu Windows R2 do wydania DynCache upłynęło dużo czasu. Zobacz blogs.technet.com/b/yongrhee/archive/2010/02/16/…, aby uzyskać aktualizację wiadomości na blogu ms. Nadal wolę moje rozwiązanie, ponieważ nie wymaga ono dodatkowych zasobów do uruchomienia kolejnej usługi. Nasze serwery stały się bardzo stabilne z moim skryptem, więc nie zmieniam ich na DynCache.
BeowulfNode42
@ BeowulfNode42 - Mamy problemy z powiększeniem pamięci podręcznej mapowanych plików. Czy masz jakieś wskazówki, jak to rozwiązać? Zakładałem, że ustawienie rozmiaru pamięci podręcznej plików systemowych również rozwiąże ten problem ?! Czy masz pomysł, czy (wzdęte) narzędzie DynCache rozwiązałoby ten problem?
Lieven Keersmaekers
fwiw - Właśnie próbowałem na serwerze testowym, a plik mapowany (rammap) dostał się z 12 GB Active, 0 GB Standby do 8GB Active, 4GB Standby. Wydaje się, że to działa również w przypadku mapowanych plików ?!
Lieven Keersmaekers
@LievenKeersmaekers to dziwne. Być może jest to jakiś efekt działania. Nie natknąłem się na dobry sposób rozwiązania problemu pamięci podręcznej mapowanych plików występującej podczas kopiowania plików z szybkiej pamięci do wolnej, chociaż nie próbowałem narzędzia DynCache, ponieważ dla nas problem pamięci podręcznej mapowanych plików jest głównie denerwujący, tymczasowy zwolnij na naszych serwerach, które zarządzają naszymi kopiami zapasowymi. Na przyszłość, ile pamięci RAM ma ten system testowy i czy uruchomiłeś skrypt zgodnie z ustawieniem 12,5%, a jeśli pamiętasz lub masz rekordy innych typów rozmiarów pamięci?
BeowulfNode42
4

Nie twierdzę, że jestem ekspertem w zakresie wewnętrznego działania pamięci lub pamięci podręcznej dysku w systemie operacyjnym Windows, ale mam dwie spostrzeżenia:

  1. Gdyby system operacyjny nie buforował danych w pamięci, musiałby je odczytać z dysku, który jest wykładniczo wolniejszym nośnikiem pamięci niż pamięć, więc problem z wydajnością, który widzisz teraz, prawie na pewno byłby gorszy.

  2. Próbujesz rozwiązać problem, lecząc objaw problemu zamiast jego przyczyny. Przyczyną problemu jest prawie na pewno brak wystarczającej fizycznej pamięci RAM, a moją sugestią byłoby zaradzenie temu.

Ponadto, chociaż pamięć podręczna może wykorzystywać 1,5 GB pamięci RAM, zastanawiałbym się, jakie jest zużycie pamięci na inne procesy i usługi, a rozwiązaniem może być zbadanie tego wykorzystania pod kątem potencjalnych problemów.

joeqwerty
źródło
Dokładnie. Jeśli OP zmniejszy użycie pamięci RAM przez metaplik, system będzie musiał załadować więcej metadanych z dysku, ponieważ mniej będzie w pamięci, co pogorszy sytuację.
David Schwartz
1
Dzięki za opinie. Kilka rzeczy, serwer jest przede wszystkim serwerem sieciowym z bazą danych MySQL i nie czyta plików zbyt często, więc niewielki wpływ metadanych na brak pamięci podręcznej jest minimalny, wydajność dramatycznie wzrasta po wyczyszczeniu. To liczba różnych plików, które odczytuje w czasie, dlatego rozmiar pamięci podręcznej jest coraz większy. Wiem, że więcej pamięci RAM by to rozwiązało, ale czy nie chodzi o „pamięć podręczną”, aby zwolnić pamięć, gdy aplikacje lub skrypty na serwerze naprawdę tego potrzebują, aby uniknąć stronicowania? Dlaczego ta pewna pamięć podręczna jest zawsze oznaczona jako aktywna, myli mnie.
al2k4
Oczywiście sam nigdy nie doświadczyłeś tego problemu. Wiele osób z 32, 64 i 128 GB pamięci RAM ma ten problem, w którym dane metapliku zajmują zbyt dużo pamięci RAM, a system Windows nie zwalnia jej, ponieważ jest oznaczona jako pamięć aktywna i niegotowa (pamięć podręczna). Użycie interfejsu API SetSystemFileCacheSize, jak opisałem w mojej odpowiedzi, zmusza Windows do oznaczenia znacznej części danych metapliku jako pamięci rezerwowej, a system zarządzania pamięcią podręczną może następnie ustalić, co należy zachować w pamięci RAM, a co usunąć.
BeowulfNode42
Troll dużo? To pytanie ma ponad dwa lata.
joeqwerty
@ joeqwerty Cały czas widzę w sieci nowe posty na ten temat. Wiele powiązanych wyszukiwań prowadzi do tego pytania. Ponieważ aktualizowałem własną odpowiedź i uważam, że twoja odpowiedź jest „nieprzydatna”, oznaczyłem ją jako taką i skomentowałem dlaczego. Jeśli to czyni mnie trollem, niech tak będzie.
BeowulfNode42
3

Ludziom, którzy dali oczywiste, ale nieskuteczne rozwiązanie polegające na dodaniu większej ilości pamięci RAM, najwyraźniej nie poradziliście sobie z tym problemem z pierwszej ręki.

Jak stwierdzono we wcześniejszym plakacie, nie ma znaczenia, ile pamięci RAM rzucisz na problem ... wszystko się zapełni. Korzystam z zestawu narzędzi Atlassian na naszym serwerze aplikacji, który został migrowany z wersji 32-bitowej (2003) do 64-bitowej (2008). Natychmiast stało się jasne, że nastąpiła utrata wydajności.

Patrząc na menedżera zadań, prawie cała pamięć została zużyta; nawet jeśli uruchomione procesy nie odzwierciedlają tego. Gdy zwiększyliśmy pamięć z 8 GB do 16 GB, problem zużył również dodatkową pamięć.

Jedynym sposobem na rozwiązanie tego problemu było zrestartowanie serwera, co obniżyło zużycie pamięci równe procesom (około 3,5 GB). Zaczęło się to wspinać ponownie w ciągu około jednego dnia.

Wiedziałem, że to nowy błąd / funkcja Microsoft i z przyjemnością znalazłem ten artykuł. Uwielbiam sposób, w jaki Microsoft pozostawia ten niezwykle ważny szczegół użytkownikom. Pobrałem RamMap, który mógłby być rodzimym narzędziem, i teraz widzę użycie Metafile. Ustawimy pamięć podręczną na czyszczenie co kilka dni i mam nadzieję, że to rozwiąże problem.

Interesujące jest to, że widziałem ten problem tylko na jednym z kilku migrowanych serwerów, więc zastanawiam się, czy metaplik jest zasilany tylko z niektórych rodzajów aplikacji.

James N.
źródło
1
Z mojego doświadczenia wynika, że ​​użycie pamięci metaplików nie wzrośnie znacznie powyżej rozmiaru metadanych systemu plików (w końcu to właśnie buforuje), więc uaktualnienie pamięci RAM, aby umożliwić dopasowanie metadanych systemu plików do pamięci, jest przynajmniej w niektórych przypadkach realnym rozwiązaniem. Poleciłem także klientom zmniejszyć rozmiar metadanych systemu plików, usuwając cruft, taki jak miliony plików tymczasowych, których nie dotykano od miesięcy. Dość niewygodne jest to, że Windows faktycznie woli metadane NTFS w pamięci niż pamięć aplikacji, ale wyszukiwanie klastrów dla pliku może być strasznie wolne bez MFT w pamięci.
James L
2
Zgadzam się - dodanie więcej pamięci RAM nie rozwiązuje problemu, po prostu zużyje więcej, a wszystkie inne procesy w końcu się zatrzymają. Niedawno zaktualizowałem do 24 GB, tylko po to, aby SQL zajmował 8 (w porządku) i miał 12 w metapliku. James N - jakiego narzędzia używasz do okresowego czyszczenia?
sirthomas,
2

Ten problem można rozwiązać szybko i za darmo za pomocą narzędzia SysInternals CacheSet. Wystarczy ustawić maksymalny zestaw roboczy na odpowiednią wartość mniejszą niż ilość pamięci RAM systemu i zastosować.

OneSpeed
źródło
1

Przepraszam, że jestem tak bezpośredni, ale co z uaktualnieniem serwera do ilości pamięci RAM, która jest nieco wyższa niż w dzisiejszych stacjach roboczych? Memboy 16 GB są cholernie tanie. Tańsze niż nawet pół dnia twojego czasu.

TomTom
źródło
2
To rozwiązałoby to na dobre, ale nasze serwery są hostowane zdalnie przez stronę trzecią. Nasi gospodarze będą pobierać dużą sumę tylko w celu zwiększenia pamięci RAM miesięcznie. Dlatego chcielibyśmy tego uniknąć, jeśli to możliwe.
al2k4
2
Tak. Zgadnij co;) Dlatego kupuję sprzęt. Gospodarze są szaleni - pamięć RAM można kupić w 3 miesiące. Cóż, lekcje do nauczenia: nieprofesjonalna konfiguracja powraca, by cię ugryźć.
TomTom
Wszystkie 64-bitowe systemy Windows mają ustawienie 1 TB dla maksymalnej ilości danych metapliku w aktywnej pamięci (nie jest traktowane jako buforowana pamięć rezerwowa gotowa do użycia, gdy inne rzeczy potrzebują więcej pamięci). Nie wiem o tobie, ale nie widziałem jeszcze żadnego okna z taką ilością pamięci. Nie powinieneś instalować więcej pamięci RAM, aby korzystać z większej liczby plików przechowywanych na dysku twardym. NTFS ma obsługiwać do 4 294 967 295 plików na wolumin. Pojedynczy dysk NTFS o pojemności 4 TB powinien być w stanie obsłużyć ponad 900 milionów plików. Spróbuj uruchomić defrag lub kopię zapasową, a to się nie powiedzie lub zaindeksuje.
BeowulfNode42
1
Tak, powinieneś to zrobić, jeśli Twój „Serwer” ma mniej pamięci RAM niż potężny laptop. Tu nie chodzi o „absurdalnie wysoko”. Chodzi o „zdobądź tyle, że serwer zasługuje na tę nazwę”.
TomTom
1

Oto link do pobrania narzędzia Microsoft DynCache - nie trzeba tworzyć biletu ani płacić. http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=9258

(przepraszam - zauważam tylko teraz, że nie jest to wersja R2)

Znany problem dla dalszego wzrostu cache jest opisany tutaj na blogu Microsoft: http://blogs.msdn.com/b/ntdebugging/archive/2007/11/27/too-much-cache.aspx

[aktualizacja] poprawka działania systemu Windows Server 2008 R2.

Znalazłem przykładowy kod C # na Codeplex, szybko utworzyłem konsolowy projekt C # z Visual Studio i skompilowałem, działałem.

https://asstoredprocedures.svn.codeplex.com/svn/ASSP/FileSystemCache.cs

Uwaga: musisz dodać odwołanie do Microsoft.AnalysisServices.AdomdClient, które można znaleźć tutaj:

C: \ Program Files (x86) \ Microsoft.NET \ ADOMD.NET

i skomentuj metodę ClearAllCaches () za pomocą (w moim przypadku) niepotrzebnych odniesień do XMLaDiscover. Rzuć to do TaskScheduler.

sirthomas
źródło
0

Możesz pobrać narzędzie DynCache od MS, które pozwoli ograniczyć użycie pamięci RAM przez metaplik.

Kliknij tutaj, aby pobrać narzędzie z MS .

Cakiran
źródło
Ten link nie zapewnia niczego w systemach 2008 R2. M $ nadal chce twojej karty kredytowej, abyś mógł zapłacić za naprawienie tego znanego problemu.
BeowulfNode42