In de praktijk levert CephFS bij typische hosting-workloads structurele uitdagingen op. Vooral de grote aantallen kleine files, het geheugengebruik van de Metadata Server en de interactie tussen kernel-clients, capabilities en filesystem-locks maken de infrastructuur complex en moeilijk voorspelbaar.

We hebben verschillende optimalisaties onderzocht, onze configuratie met die van andere hostingproviders vergeleken en Ceph-bugs uitgeplozen. Uiteindelijk besloten we voor clustered hosting over te stappen op NFS.

Waarom clustered hosting shared storage nodig heeft

Bij clustered hosting draaien websites en applicaties op meerdere webservers. Een loadbalancer verdeelt het verkeer over die servers. Clustered hosting is niet de standaard op ons managed-hostingplatform Core, maar wel een optie wanneer de applicatie/omgeving van en klant dat vereist.

Stel dat je Laravel-applicatie op drie webservers draait. Een bezoeker uploadt een afbeelding via de eerste server. Bij het volgende request komt diezelfde bezoeker op de tweede server terecht. Die moet de afbeelding dan ook kunnen uitlezen.

Daarvoor moeten de webservers toegang hebben tot dezelfde bestanden. Dat kan met shared storage: één filesystem dat op meerdere servers beschikbaar is. Applicaties blijven gewone filesystem-operaties gebruiken, zoals open(), read(), write() en unlink().

Waarom we aanvankelijk voor CephFS kozen

Bij Cyberfusion gebruiken we Ceph al meer dan tien jaar naar volle tevredenheid, onder andere voor block-storage via RBD.

In de kern verdeelt Ceph data over meerdere storage-nodes en slaat redundante kopieën op. Die storage kan vervolgens op verschillende manieren beschikbaar worden gesteld: als block-storage via RBD, als object-storage via een S3-compatibele interface of als POSIX-compatibel filesystem via CephFS.

Het interessante aan CephFS is de scheiding tussen metadata en file-data.

De Metadata Server (MDS) beheert de directorystructuur, inodes, permissies en filesystem-locks. De daadwerkelijke file-data staat in RADOS, waar Object Storage Daemons (OSD’s) de opslag verzorgen.

Een CephFS-client vraagt de MDS om metadata, maar kan file-data rechtstreeks bij de OSD’s ophalen. Dat maakt CephFS goed schaalbaar: de file-data loopt niet via één centrale fileserver te lopen, maar wordt door clients direct van de OSD's gehaald.

Bij het meer traditionele NFS - wat stamt uit de jaren 80 - is dat anders. Een NFS-server exporteert een filesystem, en handelt de filesystem-operaties van clients af. Alle file-I/O loopt dus via die ene server. In de loop der jaren zijn er wel manieren ontstaan om NFS redundant aan te bieden, voornamelijk door commerciële vendoren.

CephFS daarentegen is open-source, en vereist een heel scala aan componenten: OSD’s, Monitors, MDS’en, hun onderlinge communicatie en een CephFS-client in iedere Linux-kernel. Daarnaast heb je te maken met caching, caps (waarover later meer), locks, en de interactie tussen verschillende softwareversies.

Die complexiteit kan gerechtvaardigd zijn wanneer je vrijwel onbeperkte schaalbaarheid nodig hebt. Bij hosting-workloads met grote aantallen kleine files vormt juist de metadata-afhandeling vaak de beperkende factor.

De MDS als bottleneck

De hostingomgevingen van onze klanten bestaan voornamelijk uit PHP-applicaties. Frameworks en applicaties zoals Laravel en WordPress bevatten veel kleine files, zeker wanneer je dependencies, meerdere releases en uploads meetelt.

Iedere DevOps-er of systeembeheerder met ervaring kan je vertellen: kleine files zijn voor filesystem altijd uitdagend. Lokale storage, netwerkstorage, altijd,

Maar voor CephFS al helemaal, zo bleek. Eén van onze CephFS-clusters telde op een gegeven moment ongeveer 109 miljoen inodes en 7 miljoen directories. De MDS verwerkte doorgaans tussen de 3.000 en 10.000 requests per seconde.

Probleem één: we constateerden dat de performance achteruitging wanneer de dataset groeide en we de MDS-cache niet vergrootten. Uiteindelijk gebruikten we ongeveer 300 GiB MDS-cache voor 5,2 TiB netto opgeslagen data.

Dat was gek, want toen we onze configuratie vergeleken met die van een conculega die aanzienlijk meer data en clients verwerkte, bleek dat hij veel minder MDS-geheugen nodig had.

Daarom onderzochten we onder andere het aantal capabilities dat de MDS aan clients verstrekte.

Miljoenen capabilities

CephFS gebruikt capabilities, afgekort caps, om clients rechten op inodes te geven.

Een client die metadata mag cachen, hoeft daarvoor niet steeds opnieuw de MDS te raadplegen. Dat bespaart roundtrips, maar de MDS moet wel bijhouden welke rechten aan welke clients zijn verstrekt.

Ons cluster had ongeveer 11,8 miljoen caps uitgedeeld aan 106 clients.

De andere, aanzienlijk grotere CephFS-omgeving had meer caps in gebruik, maar een veel lager MDS-geheugengebruik.

Het aantal uitgedeelde capabilities verklaarde het hoge geheugengebruik dus evenmin.

We onderzochten ook de OSD-indeling, de verdeling van placement-groups, het aantal MDS-requests en de mount-opties van de clients.

Een mogelijke optimalisatie was het verhogen van het aantal placement-groups per OSD: de hoeveelheid 'stukjes' waarin alle data op een cluster wordt gehakt. Dat kan lock-contention aan de OSD-kant verminderen.

Maar daarmee bleef de oorzaak van het uitzonderlijke MDS-geheugengebruik onduidelijk. Continu meer RAM toevoegen hield de performance op peil, maar betekende dat de benodigde hoeveelheid geheugen telkens met de dataset moest meegroeien. Dat is onnodig kostbaar, en schaalt niet.

Een tweede uitdaging ontstond bij deployments.

Veel deploymenttools maken eerst een nieuwe release aan, wijzigen daarna een symlink en verwijderen vervolgens oude releases. Onze klanten voeren dagelijks meerdere deployments op deze manier uit.

Zo’n release bevat soms honderdduizenden files. Voor iedere file voert Linux een unlink() uit. CephFS voert die synchroon uit: de client wacht telkens op bevestiging van de MDS, dat de file écht weg is. Met tienduizenden files - wat voor de meeste sites en applicaties bepaald geen gek getal is - ben je dan al snel minutenlang aan het wachten.

De CephFS-ontwikkelaars beschrijven dit fenomeen in de presentatie Asynchronous Directory Operations in CephFS, waarin ze gelijk een oplossing aandragen: 'async dirops'.

In hun test duurt het verwijderen van 10.000 files zonder asynchroniciteit ('async dirops') ongeveer 10 seconden. Mét asynchroniciteit - waarbij de client niet wacht op de MDS - duurt dat minder dan een halve seconde.

Helaas bleek dat geen uitkomst. Tijdens ons onderzoek stuitten we op serieuze bugs rond async dirops, waaronder Ceph issue #61009. Daarom vonden we het onverstandig deze optimalisatie in productie te gebruiken.

Slow-ops en 'late client release' van caps

Naast performanceproblemen hadden we te maken met terugkerende slow-ops: filesystem-operaties die langer duurden dan verwacht.

Een deel daarvan hield verband met MDS_HEALTH_CLIENT_LATE_RELEASE: clients die niet tijdig reageren op het verzoek van de MDS om capabilities vrij te geven. Dat kan komen doordat een client 'gewoon' druk is, maar dat was niet aan de hand.

Gevolg: vertraging wanneer een andere client toegang tot dezelfde metadata nodig heeft, waardoor - in het slechtste geval - een heel cluster tot stilstand komt.

De CephFS-troubleshootingdocumentatie beschrijft hoe je dergelijke problemen kunt onderzoeken via onder andere slow-request-events, clientinformatie en MDS-status.

In de praktijk bleek het lastig om voldoende informatie te verzamelen om ieder probleem te reproduceren.

De kernel-client als extra afhankelijkheid

De Linux-kernel speelt een grote rol in de werking van CephFS.

Ook bij andere productieomgevingen bleken nieuwere kernels en specifieke kernelpatches nodig om bugs in de CephFS-client te verhelpen.

Er waren onder andere problemen met de netfs-code, vastgelegd in kernelbug #219237, en met read-only clients die problemen met de MDS konden veroorzaken, zie Ceph issue #64977.

Ook waren er meldingen dat nieuwere kernels, waaronder versie 6.14, problemen met late releases verminderden.

Wij gebruikten Debian met backports-kernels, maar die bevatten niet alle CephFS-fixes. En zelf kernels compilen heeft nooit onze voorkeur.

Incidenten met de onderliggende Ceph-storage

Tijdens een incident met Ceph Quincy werden meerdere OSD’s herhaaldelijk als 'failed' gemarkeerd. De OSD’s vielen uit, werden opnieuw gestart en veroorzaakten extra belasting doordat Ceph data ging rebalancen.

De oorzaak bleek een bug, vastgelegd als Ceph issue #69764. De versie van Ceph die deze bug bevatte draaiden we al maanden voordat we tegen de bug aanliepen.

Dit incident - dat tot bijna twee uur downtime leidde op één van onze CephFS-clusters - gaf extra gewicht aan de keuze om CephFS te vervangen. De onderlinge afhankelijkheden maakten incidenten ingewikkeld om te onderzoeken en te herstellen.

In december 2025 besloten we na veel onderzoek en testen over te stappen op NFS.

NFS als stabiele basis voor hosting

Tijdens de Dutch Proxmox Day spraken we verschillende andere hostingpartijen die - onafhankelijk van ons - ook van CephFS naar NFS waren overgestapt, op basis van vergelijkbare ervaringen.

CephFS biedt interessante mogelijkheden voor gedistribueerde opslag. En de onderliggende Ceph-technologie is rotsvast. Maar bij hosting-workloads met veel kleine files, wegen die voordelen niet op tegen de weerbarstige complexiteit van metadata-afhandeling, kernel-clients, en capabilities.