ZFS on Linux: altijd op zoek naar meer I/O performance!

In dit artikel nemen we een diepe technische duik. Zoals jullie misschien wel weten, zijn we een fanatiek gebruiker van ZFS on Linux. Het heeft een aantal eigenschappen waar voor ons geen enkel ander bestandssysteem tegenaan kan boksen. In een recent onderzoek naar een performance bottleneck heb ik veel met ZFS te maken gehad. De bevindingen deel ik graag met jullie. Welkom in de mooie, maar soms wrede wereld van ZFS!

ZFS on Linux: altijd op zoek naar meer I/O performance!

UPDATE – English summary added
We have updated the article with a summary in English.

Waarom we ZFS on Linux gebruiken

Zoals ik zei, zijn we een fervent gebruiker van ZFS on Linux. En dat is zeker niet zonder reden. Het heeft namelijk eigenschappen die voor ons zeer belangrijk zijn. Waar moet je aan denken?

  • Een extreem hoge mate van gegevensintegriteit. De correctheid van de door jouw opgeslagen data is voor ons prioriteit nummer één.
  • Het is open source. We vinden het fijn om in de code van de software te kijken, als het nodig is. Ook in dit onderzoek bewees dat zijn waarde.
  • Geen vendor lock-in. We kiezen voor onafhankelijkheid. Dat zie je in ons gehele bedrijf, dus ook in de software die we kiezen.
  • Flexibiliteit in hardware. We zitten niet vast aan een bepaald type en merk disk of SSD, omdat bijvoorbeeld de fabrikant dit voorschrijft. Wij kiezen wat we kopen.
  • Het voldoet aan onze hoge prestatie-eisen. Daarnaast kun je het erg goed tunen op een specifieke workload. Geen massaproduct, maar een perfect zittend maatpak.
  • Het is een volwassen file system, in november bestaat het veertien jaar. Ondanks deze leeftijd is het nog vol in ontwikkeling.

We gebruiken voor onze webhostingserver vrijwel alleen servers met direct-attached storage (DAS). Een NAS (Network Attached Storage) of SAN (Storage Area Network) zal er bij ons niet snel inkomen. We vinden het erg belangrijk om kleine failure domains te hebben, zodat een enkele verstoring niet onze volledige dienstverlening onderuit haalt. Daarnaast zijn er niet veel NAS- of SAN-servers die aan onze eisen voor performance en latency voldoen.

Vaak kiezen bedrijven voor een NAS of SAN om een schaalbaarheidsprobleem op te lossen. Na vervelende ervaringen met grote centrale opslagsystemen in het verleden, hebben wij ervoor gekozen om dit op een andere manier aan te vliegen. Het resultaat hiervan is dat ons platform horizontaal schaalt, met toch kleine failure domains. Het beste van beide werelden.

Voordelen van zerotolerancebeleid

Naast begrijpen hoe en waarom we ons platform op basis van direct-attached storage hebben ontworpen, is het ook belangrijk om te weten dat we bij Antagonist een zerotolerancebeleid op storingen voeren. Dit houdt in dat elke verstoring die heeft plaatsgevonden, wordt geanalyseerd. Hierbij wordt ook een plan gevormd om herhaling in te toekomst te voorkomen. De ene keer levert dit kleine aanpassingen op, de andere keer grotere.

Dit is een beleid wat we al meerdere jaren voeren en duidelijk zijn vruchten afwerpt: we hebben vrijwel geen verstoringen. Dit is fijn, want dat betekent een hogere mate van kwaliteit van onze dienstverlening. Daarnaast kunnen wij bezig zijn met de zaken die echt belangrijk zijn, zoals features ontwikkelen en het steeds sneller maken van ons platform. Grote stappen zetten in plaats van brandjes blussen.

Ben je op het punt dat je niet meer met kleine verstoringen bezig bent, dan blijven eigenlijk alleen nog de echt grote en complexe uitdagingen over. Uitdagingen die je eerder niet eens opmerkte door alle ruis. Dit zijn regelmatig problemen die niet slechts één oorzaak hebben, vaak zijn het er twee of zelfs meer. Dit maakt het oplossen ervan exponentieel lastiger (en leuker!). Waar ik mij nu in had vastgebeten, was zo’n probleem…

Het onderzoek

Wat was het probleem?

De I/O performance die ons platform in de praktijk bood, kwam voor ons gevoel niet overeen met wat het zou moeten kunnen. Begrijp me hier niet verkeerd, want het was absoluut niet traag. Alleen, een onderbuikgevoel zei dat het nog stukken sneller moet kunnen zijn.

We leunen voor het bieden van een supersnelle read cache voor een groot deel op ARC (Adaptive Replacement Cache). Onder voor ons normale situaties leveren we vrijwel alle opgevraagde data rechtstreeks uit RAM. Een korte blik op wat monitoring leverde gelijk een grote vraag op. Waarom zijn er met enige regelmaat diepe en plotselinge dalen in de ARC te zien?

ZFS on Linux: grafiek met plotselinge dips in de ARC.

En vervolgvragen, want vaak gebeurt dit als ZFS kort met geheugentekort kampt. Waarom zijn er dan nog meerdere tientallen GB’s RAM vrij?

ZFS on Linux: grafiek die toont dat er ruim voldoende RAM beschikbaar is.

En waarom begint de server vlak voor dat de ARC inzakt te swappen? Een combinatie van gebeurtenissen die gevoelsmatig niet logisch zijn. Tijd om te onderzoeken wat er aan de hand is…

ZFS on Linux: swappen.

ZFS geen traditioneel file system

ZFS is niet bepaald een standaard file system. Het wijkt in vele opzichten erg af van bijvoorbeeld ext3, ext4 of xfs. Deze laatstgenoemde file systems schalen bijvoorbeeld qua performance redelijk lineair, ze zijn rechttoe rechtaan. Performance-problemen ontstaan evenredig snel aan de hoeveelheid I/O die ze te verwerken krijgen. Dit komt, doordat het voor de snelheid afhankelijk is van de onderliggende disks of SSD’s.

In de wereld van ZFS schaalt performance niet lineair. Het kan extreem veel I/O verwerken, voordat je prestatievermindering gaat merken. Dit komt grotendeels door de slimme manier waarop de software met verschillende I/O-classes omgaat en copy-on-write toepast. Maar ook door het toepassen van compressie en het gebruiken van een ARC als cache.

Het voordeel van dit niet lineair schalen, is dat je workload kan verdubbelen, maar je bij lange na geen verdubbeling in belasting op je hardware ziet. Waar andere file systems vaak pijn gaan lijden, geeft ZFS geen kik. Een nadeel hiervan is echter, dat prestatievermindering voor veel gebruikers als een verrassing komt. Je moet goed weten wat de meetpunten zijn die je in de gaten moet houden en daarop bijsturen.

ZFS is erg vergevingsgezind als het om een verandering van workload gaat, totdat het te veel wordt. Vergelijk het met een Lamborghini. Hij is razendsnel, maar controleer ‘m wel regelmatig op vroegtijdige signalen van mankementen.

Het probleem ontrafelen

Het onderzoeken van deze problemen voelt vaak alsof je aan een draadje van een trui trekt. Je moet een beginnetje hebben, maar als je dit eenmaal hebt, dan ontrafelt hij snel. Het verschil is dat je een trui liever niet ontrafelt en technische problemen juist wel. Interessant. Je zou kunnen zeggen dat truien en technische problemen aan de ene kant tegenpolen zijn, maar tegelijk in elkaars verlengde liggen 😉

Het draadje waar ik besloot aan te gaan trekken, is waar het plotselinge swappen in combinatie met het inzakken van de ARC en de tientallen vrije GB’s aan RAM vandaan kwam. Om hier antwoord op te krijgen, heb ik me op de broncode – lang leve opensourcesoftware – van de ZFS ARC gestort: arc.c.

Arc.c nader bekeken

We monitoren van ZFS veel metrics. Eén daarvan is memory_indirect_count in /proc/spl/kstat/zfs/arcstats. Deze counter loopt in alle gevallen op als de ARC zo’n duikvlucht neemt.

Nu ben ik geen C-ontwikkelaar. Daarom kijk ik als een systeembeheerder naar zo’n situatie met de vraag, waar wordt deze counter in de code opgehoogd? De enige plek waar dit gebeurt, is de volgende functie. Dit is één van de functies binnen ZFS die voor nauwe samenwerking met de kernel zorgt.

/*
 * If sc->nr_to_scan is zero, the caller is requesting a query of the
 * number of objects which can potentially be freed. If it is nonzero,
 * the request is to free that many objects.
 *
 * Linux kernels >= 3.12 have the count_objects and scan_objects callbacks
 * in struct shrinker and also require the shrinker to return the number
 * of objects freed.
 *
 * Older kernels require the shrinker to return the number of freeable
 * objects following the freeing of nr_to_free.
 */
static spl_shrinker_t
__arc_shrinker_func(struct shrinker *shrink, struct shrink_control *sc)
{
        int64_t pages;

        /* The arc is considered warm once reclaim has occurred */
        if (unlikely(arc_warm == B_FALSE))
                arc_warm = B_TRUE;

        /* Return the potential number of reclaimable pages */
        pages = btop((int64_t)arc_evictable_memory());
        if (sc->nr_to_scan == 0)
                return (pages);

        /* Not allowed to perform filesystem reclaim */
        if (!(sc->gfp_mask & __GFP_FS))
                return (SHRINK_STOP);

        /* Reclaim in progress */
        if (mutex_tryenter(&arc_reclaim_lock) == 0) {
                ARCSTAT_INCR(arcstat_need_free, ptob(sc->nr_to_scan));
                return (0);
        }

        mutex_exit(&arc_reclaim_lock);

        /*
         * Evict the requested number of pages by shrinking arc_c the
         * requested amount.
         */
        if (pages > 0) {
                arc_shrink(ptob(sc->nr_to_scan));
                if (current_is_kswapd())
                        arc_kmem_reap_now();
#ifdef HAVE_SPLIT_SHRINKER_CALLBACK
                pages = MAX((int64_t)pages -
                    (int64_t)btop(arc_evictable_memory()), 0);
#else
                pages = btop(arc_evictable_memory());
#endif
                /*
                 * We've shrunk what we can, wake up threads.
                 */
                cv_broadcast(&arc_reclaim_waiters_cv);
        } else
                pages = SHRINK_STOP;

        /*
         * When direct reclaim is observed it usually indicates a rapid
         * increase in memory pressure. This occurs because the kswapd
         * threads were unable to asynchronously keep enough free memory
         * available. In this case set arc_no_grow to briefly pause arc
         * growth to avoid compounding the memory pressure.
         */
        if (current_is_kswapd()) {
                ARCSTAT_BUMP(arcstat_memory_indirect_count);
        } else {
                arc_no_grow = B_TRUE;
                arc_kmem_reap_now();
                ARCSTAT_BUMP(arcstat_memory_direct_count);
        }

        return (pages);
}

Zoals je in de comment leest, retourneert het het aantal pages (1 page is 4 kilobyte) dat vrijgemaakt kan worden wanneer $sc->nr_to_scan gelijk staat aan 0. Hiervoor maakt het gebruik van arc_evictable_memory(void) – waar we straks ook even naar kijken. Als $sc->nr_to_scan groter dan 0 is, dan wordt de ARC verkleint met het gevraagde aantal pages. Een extra interessant stukje:

arc_shrink(ptob(sc->nr_to_scan));
if (current_is_kswapd())
      arc_kmem_reap_now();

Simpel uitgelegd staat hier: probeer de ARC x bytes kleiner te maken. Als de server hierna aan het swappen is, doe dan arc_kmem_reap_now(). Hier zit blijkbaar een beveiligingsmechanisme om te voorkomen dat de server ARC naar disk gaat swappen. Een stukje verder in de functie zie je ook dat arcstat_memory_indirect_count opgehoogd wordt als de server aan het swappen is tijdens een ARC-reclaim actie. Precies wat ook wij waarnemen.

Notitie voor mezelf
ZFS on Linux bepaalt of er geheugentekort is door tijdens het reclaimen van ARC te kijken of de kernel (current_is_swapd(void) is een kernel-functie) aan het swappen is. Check.

Laten we nu eens naar de functie kijken die rapporteert hoeveel bytes van de ARC opgeruimd of verkleind kan worden.

arc_evictable_memory(void)
{
        uint64_t arc_clean =
            refcount_count(&arc_mru->arcs_esize[ARC_BUFC_DATA]) +
            refcount_count(&arc_mru->arcs_esize[ARC_BUFC_METADATA]) +
            refcount_count(&arc_mfu->arcs_esize[ARC_BUFC_DATA]) +
            refcount_count(&arc_mfu->arcs_esize[ARC_BUFC_METADATA]);
        uint64_t arc_dirty = MAX((int64_t)arc_size - (int64_t)arc_clean, 0);

        /*
         * Scale reported evictable memory in proportion to page cache, cap
         * at specified min/max.
         */
        uint64_t min = (ptob(nr_file_pages()) / 100) * zfs_arc_pc_percent;
        min = MAX(arc_c_min, MIN(arc_c_max, min));

        if (arc_dirty >= min)
                return (arc_clean);

        return (MAX((int64_t)arc_size - (int64_t)min, 0));
}

Kort door de bocht kijkt deze functie hoe groot de ARC nu is, trekt hier arc_c_min vanaf en stuurt deze waarde terug. Hierin zit een onderdeel om rekening te houden met de hoeveelheid page cache die de Linux kernel zelf gebruikt.

Wanneer je ARC en Linux page cache samen gebruikt, dan kan dit voor problemen zorgen. De kernel geeft namelijk de voorkeur aan het terugvragen van RAM aan processen, voordat het z’n eigen page cache kleiner gaat maken. Met zfs_arc_pc_percent, die standaard op 0 staat, kun je dit beter balanceren.

Wanneer ik op een willekeurig systeem kijk hoeveel Linux in de page cache heeft, dan is dit al snel enkele tientallen GB’s. Wat hierbij echter belangrijk is om te weten, is dat een groot deel hiervan ‘shared’ geheugen is. Dit zijn pages die tussen applicaties gedeeld worden. Dit wordt bij de page cache geteld, maar is strikt gezien in onze situatie geen page cache! Hetzelfde geldt voor RAM-drives. Dat wordt er ook bij opgeteld, terwijl het geen page cache is.

Doordat zfs_arc_pc_percent nu op 0 staat, geeft deze functie aan dat alles in de ARC wel teruggegeven kan worden aan de kernel. Dus als de kernel hierom vraagt, dan gooit ZFS alles in ARC overboord, terwijl het veel beter eerst zijn eigen page cache kan opruimen.

Notitie voor mezelf
We zullen zfs_arc_pc_percent moeten instellen om te voorkomen dat de Linux page cache de ARC verdrukt. Maar hierbij moeten we rekening houden dat in ons geval alleen nr_file_pages() een incorrect beeld geeft van de hoeveelheid data in deze cache. Waarschijnlijk gaat hier nog een feature request (en eigen patch) voor komen, zodat ‘shared’ hiervan kan worden afgetrokken.

Samenvattend hebben we tot nu toe het volgende kunnen concluderen:

  • ZFS bepaald of er geheugentekort is door te kijken of het tijdens het reclaimen van ARC tegelijk aan het swappen is. Is dit het geval, dan roept hij arc_kmem_reap_now() aan om zo snel mogelijk RAM vrij te maken. De minder subtiele manier.
  • De Linux kernel geeft de voorkeur aan het terugvragen van geheugen aan processen (zoals ZFS) voordat het zijn eigen page cache opoffert.
  • Je kunt met zfs_arc_pc_percent instellen dat ZFS minder geheugen rapporteert. Hiermee stimuleer je dat de kernel de Linux page cache kleiner maakt in plaats van dat het al het RAM van ZFS afpakt.
  • De instelling zfs_arc_pc_percent geeft in ons geval echter ander effect, omdat we erg veel ‘shared’ geheugen hebben, wat als onderdeel van nr_file_pages() gezien wordt.

Had ik al gezegd dat we tegenwoordig bij de lastige problemen nooit een enkele oorzaak kunnen aanwijzen? Hartstikke mooi dat we dit nu allemaal weten! Maar nu is de hamvraag: waar komt dit geheugentekort vandaan, terwijl we zien dat er nog zat beschikbaar is?

Linux geheugenmanagement

We weten inmiddels veel te veel over het geheugenmanagement van de ARC, maar kunnen nog steeds de hamvraag niet beantwoorden. Daarom moeten we naar het geheugenmanagement van de kernel gaan kijken. Hoe beheert Linux eigenlijk het RAM van een server?

Hi buddy

Geheugenmanagement is een complex onderdeel bij software schrijven. Dit geldt helemaal voor de Linux kernel. Je wilt altijd op de meest gunstige manier geheugen uitdelen aan de processen die hierom vragen. De moderne Linux kernel gebruikt hier het Buddy algoritme voor. Ik zal me inhouden en hier niet gelijk over in detail treden, maar de huidige status van de memory allocation zoals het buddy-systeem dit doet, kun je in /proc/buddyinfo terugvinden.

Na daarin een korte blik te hebben geworpen, viel me gelijk iets op. Bij één van de twee nodes zijn er veel meer blokken beschikbaar, vooral in de hogere regionen. Tegelijk lijkt er krapte te zijn op de andere node (CPU). Interessant!

Node 0, zone  DMA1    1       1       0       2       1      1      0     0    1   1   3 
Node 0, zone  DMA32   1121    1760    1607    1281    937    662    377   198  80  53  11 
Node 0, zone  Normal  402260  304396  354877  131527  5010   0      0     0    0   0   0 
Node 1, zone  Normal  130687  221059  115824  44467   53175  23490  7760  53   0   0   0

Latency en bandwidth

Waar vroeger vooral de grote prestatieverbeteringen werden behaald door de kloksnelheid van de CPU te verhogen, staat deze ontwikkeling nu eigenlijk al jaren stil. De fysieke limieten van de huidige CPU’s zijn bijna bereikt. De laatste jaren wordt er daarom veel meer gekeken naar het versnellen van geheugen. Hierbij spelen de caches op de CPU’s een grote rol, maar ook hoe de CPU het RAM aanspreekt.

Alles hier draait om latency en bandwidth. Om de latency zo laag mogelijk te krijgen, is het het belangrijk om het pad dat data tussen verschillende hardware-onderdelen moet afleggen zo kort mogelijk is. Vergelijk het met de supermarkt om de hoek of een paar kilometer verderop. De ene heeft een andere reistijd dan de andere.

Exact hetzelfde geldt voor computerhardware. Hoe dichter je RAM bij de CPU (met zo min mogelijk tussenliggende controllers), hoe sneller! Dit is ook één van de redenen waarom we zo’n voorstander zijn van direct-attached storage. Daar zit je storage namelijk ook veel dichter bij je RAM en CPU.

NUMA

Als je één CPU in een server hebt, dan is dit niet zo moeilijk te bereiken. Wanneer het er zoals bij ons meerdere zijn die samen moeten werken, dan wordt het een ander verhaal. Geheugen dat bij de ene CPU hoort, moet namelijk wel gebruikt kunnen worden door de andere CPU. Het heeft altijd de voorkeur het geheugen te gebruiken, dat dicht bij de CPU zit waar de software op draait. Hiervoor is NUMA ontwikkeld (Non-Uniform Memory Access).

Waar ik achter kwam, is dat de Linux kernel per NUMA node swapt! Wanneer het geheugen op één van de nodes krap begint te worden, dan geeft het de voorkeur om inactief RAM voor die node naar disk te swappen, voordat het RAM van de andere CPU gaat aanspreken.

Klinkt logisch. En in heel veel gevallen is dat ook exact het gedrag dat je wilt zien. Behalve wanneer ZFS kijkt naar het swapgedrag om te bepalen of er geheugentekort is. Hierdoor krimpt de ARC, terwijl er nog RAM (op de andere node) beschikbaar is. Daar komt ook nog eens bovenop dat de kernel van ZFS te horen krijgt dat in principe de gehele ARC opgeofferd mag worden bij dreigend geheugentekort, voordat het de Linux page cache kleiner maakt.

De oorzaak van het swappen van RAM naar disk, terwijl er nog zat beschikbaar is? De ene node (CPU) heeft meer RAM dan de andere! Als je 96 GB over twee CPU’s moet verdelen, dan zijn er over het algemeen geen bezwaren om de ene 32 GB en de andere 64 GB te geven. Dit is zelfs hoe de fabrikant het aanraadt. Gebruik je echter ZFS, dan gebeuren er rare dingen…

Eindconclusies

Qua beschikbare GB’s RAM op de servers zaten we niet krap. Toch hebben we ervoor gekozen om alle systemen in ons serverpark van een upgrade naar 128 GB te voorzien, 64 GB per node. Je hebt nooit te weinig RAM, toch? 😉

ZFS on Linux: RAM upgraden.

In theorie lost dit het direct zichtbare probleem op. Geen geswap meer dat vervolgens een domino-effect tussen de kernel en ZFS oplevert. Deze upgrade hebben we inmiddels overal afgerond en heeft duidelijk effect.

Nu de hardware en software perfect op elkaar zijn afgestemd, hebben we ook een aantal andere zaken binnen ZFS kunnen tunen. We hebben hiermee een I/O snelheidswinst van gemiddeld minimaal 100% kunnen realiseren.

Gedurende dit onderzoek, en vooral na het aanpakken van de hoofdoorzaak, zijn we op een aantal andere optimalisaties gestuit. Voor nog betere prestaties gaan we waarschijnlijk dit in de nabije toekomst ook aanpassen.

  • We willen van zfs_arc_pc_percent gebruik gaan maken. Voordat we dit kunnen doen, moeten we ervoor zorgen dat ZFS gedeeld geheugen niet meeneemt zijn page cache-berekening. Voor deze code moeten we zelf een patch schrijven of zorgen dat het upstream wordt aangepast.
  • Beide NUMA nodes zijn nu gelijkmatig gevuld. Hierdoor zien we dat een deel van het RAM door fragmentatie niet direct bruikbaar is. Wat hier waarschijnlijk veel in zal gaan helpen, is ZFS recordsize tuning.

Tot slot

Hopelijk heb ik jullie zo een gedetailleerd kijkje in de keuken kunnen geven! Wie weet gaan we in een vervolgblog hier verder op in. Simpel je website hosten en geen omkijken naar het technische verhaal? Dat kan natuurlijk ook! Gebruik ons razendsnelle platform en bekijk onze pakketten. Zoals altijd, heb je vragen, neem dan gerust contact met ons op.

Bekijk hostingpakketten →

P.S. Op de hoogte blijven van alle artikelen, updates, tips en trucs die op ons blog verschijnen? Volg ons via Facebook, Twitter, Instagram, RSS en e-mail!


Summary

During my research – what turned out to be quite a rabbit hole – there was not much to be found online regarding my observations. I believe that sharing information is vital to keep awesome open-source projects going. That is why I took the opportunity to summarize this article in English. If you see similar behavior I hope you benefit from our findings. Here we go 🙂

Issue description

We are happy users of ZFS on Linux. This file system has plenty of features we value and delivers excellent results. During one of my many searches for even more performance I noticed the ARC shrinking or collapsing for no apparent reason. In addition, the server started swapping out RAM to disk just before this happened. Remarkable, because there was plenty of free RAM, a low swappiness value and not too much inactive memory. It just did not add up…

Our findings

  1. Linux servers determine the need for swapping per NUMA-node (used in modern multi-CPU servers).
  2. ZFS determines the amount of memory pressure on the system by looking at the swapping that is being done during ARC reclaims (among other things). If so, it just pulls the plug using arc_kmem_reap_now(void). Some kind of safety measure against OOM situations.
  3. We are using an uneven amount of RAM for the NUMA-nodes. This is causing the server to swap, even when there is plenty of RAM available on the other node. This in turn makes ZFS drop all of its ARC.
  4. After solving the RAM imbalance (by plugging in more dimms), the situation improved significantly.
  5. However, using the Linux page cache together with ARC raised another problem. When available RAM is low, the kernel prefers to reclaim memory from running processes before sacrificing its own page cache. ZFS reports the amount of RAM the kernel can reclaim with arc_evictable_memory(void). Without adjustments this means pretty much everything in the ARC.
  6. To make arc_evictable_memory(void) not report everything in ARC as evictable, there is a setting called zfs_arc_pc_percent. It is designed to make ZFS and the Linux page cache work better together.
  7. When setting the zfs_arc_pc_percent to 100, it should mean that ARC and page cache are equally important. However, for this calculation nr_file_pages() is used. This also includes nr_shrmem (see /proc/vmstat). Our systems are using a lot of shared memory, and none of this should be considered as a page cache. This results in off balance calculations.

Advice and suggestions

  1. Use an equal amount of RAM for both CPU’s/NUMA nodes.
  2. Make sure there is a healthy balance between the importance of Linux page cache and ZFS ARC. Adjust zfs_arc_pc_percent accordingly.
  3. When you have a lot of shared memory in your system, be aware that zfs_arc_pc_percent is not doing what you think it should be doing.

Deel Deel Deel Deel

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *