.png)
Ceph is betrouwbaar en goed geïntegreerd in OpenStack. Daarom is het al jaren onze Block Storage-oplossing. Om echter hogere prestaties tegen lagere kosten te bieden, hebben we Exten overgenomen en kunnen we nu onze eigen NVMe block storage-oplossing
- in C++ en Go bouwen. Onze doelen voor de bouw zijn:
- NVMe-schijven gebruiken om volumes met hoge prestaties te bieden
- Slimme coderingsalgoritmen gebruiken zodat minder schijfruimte nodig is (Reed-Solomon-codering, compressie)
Clusters klein en gemakkelijk te onderhouden houden
Exten draait inmiddels al meer dan een jaar in productie. In deze blog leggen we uit hoe het werkt en wat de architectuur in de toekomst mogelijk zal maken. Klik op de link onderaan het artikel om uw feedback te geven en help de toekomst van Exten vorm te geven

Anatomie van een cluster
Een typisch Exten-cluster bestaat uit zes servers. Deze servers bevinden zich dicht bij elkaar, zodat ze onderling een lage latency hebben, maar niet té dichtbij, zodat de kans op het gelijktijdig uitvallen van meerdere servers beperkt is. Elke server heeft tientallen NVMe-schijven om gebruikersgegevens op te slaan.
Exten is gebouwd rond het NVMe-protocol. Het gebruikt NVMe-schijven, maar gebruikt ook het NVMe over Fabric-protocol om gebruikersvolumes bloot te stellen en om tussen hosts te communiceren. Volumes zijn virtuele schijven die klanten aan hun VM's kunnen koppelen. Dit protocol gebruikt dezelfde commando's als NVMe-schijven, maar dan via een netwerkverbinding (TCP of RDMA). Het is ontworpen voor hoge prestaties en lage latency.
Een voordeel van NVMe over Fabric is dat de Linux-kernel dit standaard ondersteunt. Het koppelen van een Exten-volume aan een Linux-host is net zo eenvoudig als het uitvoeren van een nvme connect-commando met de juiste parameters: het volume verschijnt dan precies zoals elke andere lokale NVMe-schijf. Als klant van Public Cloud ziet u hier niets van — het volume wordt gewoon aan uw instance gekoppeld, precies zoals bij Ceph.
Exten is opgedeeld in een data plane geschreven in C++ en een control plane geschreven in Go. Beide communiceren via gRPC. Het data plane ontvangt IO via NVMe over Fabric en stuurt dit door naar de NVMe-schijven. Het control plane biedt een API om volumes aan te maken en te verwijderen en om het cluster te beheren.
Hoe gegevens veilig blijven
Het veilig houden van klantgegevens is de grootste verantwoordelijkheid van een Exten-cluster, en we zorgen hiervoor op meerdere niveaus.
Aan de kant van het control plane gebruiken we het bekende Raft Consensus Algorithm om de integriteit van het cluster op een fouttolerante wijze te garanderen. Dit werkt door een leider te kiezen en alle nieuwe informatie — een nieuw aangemaakt volume, een ingeschakelde schijf — vast te leggen in een log dat naar elke host wordt gerepliceerd. Als een host uitvalt, blijven de andere werken. De enige beperking is dat een meerderheid van de hosts actief moet blijven om "split-brain"-problemen te voorkomen. Een cluster met zes nodes kan twee hosts verliezen en blijven werken.
Gebruikersgegevens zelf, of de daadwerkelijke IO die naar de volumes wordt geschreven, gaat niet via Raft; dat zou veel te traag zijn. In plaats daarvan gebruiken we een ander bekend algoritme: een Reed-Solomon-code.
Deze foutcorrectiecode is conceptueel eenvoudig. Neem RS 4+2: we splitsen gegevens in vier gelijke delen en berekenen vervolgens twee nieuwe delen van dezelfde grootte. Als vier van die zes delen leesbaar zijn, zijn de oorspronkelijke gegevens te herstellen: met de code kan men de twee ontbrekende delen berekenen. Dat levert een verhouding op van 1,5 (opgeslagen gegevens / ontvangen gegevens), dus we kunnen twee schijven verliezen zonder gegevens te verliezen. Het is een zeer efficiënte manier om redundantie toe te voegen. Het naïeve alternatief — meestal mirroring genoemd, wat simpelweg het meermaals kopiëren van alle gegevens naar verschillende schijven is — zou drie kopieën nodig hebben om het verlies van twee schijven te overleven. Met Reed-Solomon slaan we de helft minder gegevens op voor hetzelfde redundantieniveau.
Defecte schijven kunnen op twee manieren worden gedetecteerd: ofwel een leesactie mislukt simpelweg, ofwel deze retourneert beschadigde gegevens — wat wordt gedetecteerd met een checksum die we aan elke sector toevoegen. Wanneer een schijf defect raakt, berekent een automatisch proces het ontbrekende deel opnieuw en slaat dit op een gezonde schijf op, waardoor het risico op gegevensverlies wordt verkleind.
I/O snel uitvoeren
Nu CPU's en RAM sneller zijn, moet opslag dat ook zijn. Het doel van Exten is om de hardware waarop het draait maximaal te benutten en klanten hoogwaardige IO te leveren. De keuze voor het NVMe over Fabric-protocol is een eerste stap naar IO met zo min mogelijk overhead, maar de totale softwarestack is ontworpen voor hoge prestaties.
Het verwerkingsmodel is gegevensgericht. Op het niveau van de netwerkkaart (
Network Interface Card
, NIC) ontvangen en verzenden we gegevens via een aantal buffers met een vaste grootte, die in RAM worden opgeslagen. Een gegeven CPU verwerkt elke buffer met twee doelen: gegevenskopieën vermijden en context-switches vermijden.
- Om gegevenskopieën te vermijden, manipuleert de code vooraf toegewezen buffers met pointers helemaal van de NIC tot aan de schijf, en we wijzigen gegevens alleen wanneer dit onvermijdelijk is (compressie, Reed-Solomon-codering…). Om context-switches te vermijden, handelen we IO af met volledig asynchrone methoden die met kleine stukjes gegevens werken. Een gegeven CPU verwerkt een buffer zoveel mogelijk voordat hij doorgaat naar de volgende, maar het is een balans: de volgende buffer mag niet te lang wachten en de verwerking moet eerlijk blijven. We hebben een compleet framework in C++ gebouwd dat op deze vereisten afgestemd is. Dit houdt de code overzichtelijk en onderhoudbaar.
- Naast de code zelf helpen verschillende andere factoren de prestaties te verbeteren:
- de keuze van het compressiealgoritme (geen compressie is soms de beste keuze, bijvoorbeeld bij versleuteld dataverkeer)
de keuze van het netwerkprotocol: RDMA is sneller dan TCP, maar de implementatie brengt meer beperkingen met zich mee
de manier waarop we CPU-cores aan volumes toewijzen
Op onze Public Cloud-producten passen we ook QoS-regels toe om eerlijkheid tussen alle volumes te garanderen.
Wat is de volgende stap voor Exten
Exten is nu in productie en levert op dit moment volumes aan Public Cloud-klanten. Het is transparant voor klanten en ondersteunt momenteel dezelfde producten als Ceph — maar het is een softwarestack die we volledig in eigen hand hebben, gebouwd rond NVMe voor hoge prestaties.
We verbeteren het voortdurend, met als doel klanten volumes met hogere prestaties, meer flexibiliteit en meer betrouwbaarheid te bieden. We onderzoeken bijvoorbeeld het gebruik van RDMA voor nog betere prestaties (we gebruiken momenteel TCP).De eerste stap van het Exten-traject was het bieden van een betrouwbaar product om Ceph te vervangen. Nu we de stack volledig in eigen hand hebben, kunnen we nieuwe functies toevoegen en het product aan de behoeften van klanten aanpassen.Heeft u use cases voor Block Storage die we horen te kennen, of features die volgens u ontbreken? Vertel ons erover op Discord of de