Migratie van Cassandra naar Kubernetes: functies en oplossingen

Migratie van Cassandra naar Kubernetes: functies en oplossingen

We komen regelmatig de Apache Cassandra-database tegen en de noodzaak om deze binnen een op Kubernetes gebaseerde infrastructuur te exploiteren. In dit materiaal delen we onze visie op de noodzakelijke stappen, criteria en bestaande oplossingen (inclusief een overzicht van operators) voor de migratie van Cassandra naar K8s.

“Wie een vrouw kan regeren, kan ook de staat regeren”

Wie is Cassandra? Het is een gedistribueerd opslagsysteem dat is ontworpen om grote hoeveelheden gegevens te beheren en tegelijkertijd een hoge beschikbaarheid te garanderen zonder een enkel storingspunt. Het project heeft nauwelijks een lange introductie nodig, dus ik zal alleen de belangrijkste kenmerken van Cassandra geven die relevant zullen zijn in de context van een specifiek artikel:

  • Cassandra is geschreven in Java.
  • De Cassandra-topologie omvat verschillende niveaus:
    • Knooppunt: één geïmplementeerde Cassandra-instantie;
    • Rack is een groep Cassandra-instanties, verenigd door een bepaald kenmerk, die zich in hetzelfde datacenter bevinden;
    • Datacenter - een verzameling van alle groepen Cassandra-instanties die zich in één datacenter bevinden;
    • Cluster is een verzameling van alle datacenters.
  • Cassandra gebruikt een IP-adres om een ​​knooppunt te identificeren.
  • Om de schrijf- en leesbewerkingen te versnellen, slaat Cassandra een deel van de gegevens op in het RAM-geheugen.

Nu – naar de daadwerkelijke potentiële overstap naar Kubernetes.

Controlelijst voor overdracht

Over de migratie van Cassandra naar Kubernetes gesproken: we hopen dat het met de verhuizing gemakkelijker te beheren zal worden. Wat is hiervoor nodig, wat helpt daarbij?

1. Gegevensopslag

Zoals al is verduidelijkt, slaat Cassanda een deel van de gegevens op in RAM Memtabel. Maar er is nog een ander deel van de gegevens dat op schijf wordt opgeslagen: in het formulier SSTabel. Aan deze gegevens wordt een entiteit toegevoegd Vastleggingslogboek — records van alle transacties, die ook op schijf worden opgeslagen.

Migratie van Cassandra naar Kubernetes: functies en oplossingen
Schrijf een transactiediagram in Cassandra

In Kubernetes kunnen we PersistentVolume gebruiken om gegevens op te slaan. Dankzij beproefde mechanismen wordt het werken met data in Kubernetes elk jaar eenvoudiger.

Migratie van Cassandra naar Kubernetes: functies en oplossingen
We zullen ons eigen PersistentVolume toewijzen aan elke Cassandra-pod

Het is belangrijk op te merken dat Cassandra zelf gegevensreplicatie impliceert en hiervoor ingebouwde mechanismen biedt. Als u dus een Cassandra-cluster bouwt op basis van een groot aantal knooppunten, is het niet nodig om gedistribueerde systemen zoals Ceph of GlusterFS te gebruiken voor gegevensopslag. In dit geval zou het logisch zijn om gegevens op de hostschijf op te slaan met behulp van lokale persistente schijven of montage hostPath.

Een andere vraag is of je voor elke feature branch een aparte omgeving voor ontwikkelaars wilt creëren. In dit geval zou de juiste aanpak zijn om één Cassandra-knooppunt op te richten en de gegevens op te slaan in een gedistribueerde opslag, d.w.z. de genoemde Ceph en GlusterFS zijn uw opties. Dan weet de ontwikkelaar zeker dat hij geen testdata verliest, zelfs niet als één van de Kuberntes-clusterknooppunten verloren gaat.

2. Toezicht houden

De vrijwel onbetwiste keuze voor het implementeren van monitoring in Kubernetes is Prometheus (we hebben hier uitgebreid over gesproken in gerelateerd rapport). Hoe doet Cassandra het met statistische exporteurs voor Prometheus? En, wat nog belangrijker is, met bijpassende dashboards voor Grafana?

Migratie van Cassandra naar Kubernetes: functies en oplossingen
Een voorbeeld van het verschijnen van grafieken in Grafana voor Cassandra

Er zijn slechts twee exporteurs: jmx_exporteur и cassandra_exporteur.

Wij hebben zelf de eerste gekozen omdat:

  1. JMX Exporter groeit en ontwikkelt zich, terwijl Cassandra Exporter niet genoeg ondersteuning van de gemeenschap heeft kunnen krijgen. Cassandra Exporter ondersteunt de meeste versies van Cassandra nog steeds niet.
  2. Je kunt het als Javaagent uitvoeren door een vlag toe te voegen -javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180.
  3. Er is er één voor hem adequaat dashboard, wat niet compatibel is met Cassandra Exporter.

3. Kubernetes-primitieven selecteren

Laten we, volgens de bovenstaande structuur van het Cassandra-cluster, proberen alles wat daar wordt beschreven te vertalen in Kubernetes-terminologie:

  • Cassandra Knooppunt → Pod
  • Cassandra Rack → StatefulSet
  • Cassandra Datacenter → pool van StatefulSets
  • Cassandra-cluster → ???

Het blijkt dat er een extra entiteit ontbreekt om het hele Cassandra-cluster in één keer te beheren. Maar als iets niet bestaat, kunnen wij het creëren! Kubernetes heeft voor dit doel een mechanisme om zijn eigen bronnen te definiëren: Aangepaste resourcedefinities.

Migratie van Cassandra naar Kubernetes: functies en oplossingen
Extra bronnen declareren voor logboeken en waarschuwingen

Maar Custom Resource zelf betekent niets: het vereist tenslotte controleur. Mogelijk moet u hulp zoeken Kubernetes-operator...

4. Identificatie van peulen

In de bovenstaande paragraaf hebben we afgesproken dat één Cassandra-knooppunt gelijk zal zijn aan één pod in Kubernetes. Maar de IP-adressen van de pods zullen elke keer anders zijn. En de identificatie van een knooppunt in Cassandra is gebaseerd op het IP-adres... Het blijkt dat na elke verwijdering van een pod het Cassandra-cluster een nieuw knooppunt zal toevoegen.

Er is een uitweg, en niet slechts één:

  1. We kunnen gegevens bijhouden op basis van host-ID's (UUID's die Cassandra-instanties op unieke wijze identificeren) of op basis van IP-adressen en dit allemaal opslaan in bepaalde structuren/tabellen. De methode heeft twee belangrijke nadelen:
    • Het risico dat er een race condition optreedt als twee knooppunten tegelijk vallen. Na de opkomst zullen Cassandra-nodes tegelijkertijd een IP-adres uit de tabel opvragen en strijden om dezelfde bron.
    • Als een Cassandra-knooppunt zijn gegevens kwijt is, kunnen we het niet langer identificeren.
  2. De tweede oplossing lijkt een kleine hack, maar toch: we kunnen voor elke Cassandra-node een Service met ClusterIP creëren. Problemen met deze implementatie:
    • Als er veel knooppunten in een Cassandra-cluster zijn, zullen we veel Services moeten creëren.
    • De ClusterIP-functie wordt geïmplementeerd via iptables. Dit kan een probleem worden als het Cassandra-cluster veel (1000... of zelfs 100?) knooppunten heeft. Hoewel balanceren op basis van IPVS kan dit probleem oplossen.
  3. De derde oplossing is om een ​​netwerk van knooppunten voor Cassandra-knooppunten te gebruiken in plaats van een speciaal netwerk van pods door de instelling in te schakelen hostNetwork: true. Deze methode legt bepaalde beperkingen op:
    • Om eenheden te vervangen. Het is noodzakelijk dat het nieuwe knooppunt hetzelfde IP-adres moet hebben als het vorige (in clouds zoals AWS, GCP is dit bijna onmogelijk);
    • Met behulp van een netwerk van clusterknooppunten beginnen we te concurreren om netwerkbronnen. Daarom zal het problematisch zijn om meer dan één pod met Cassandra op één clusterknooppunt te plaatsen.

5. Back-ups

We willen een volledige versie van de gegevens van een enkel Cassandra-knooppunt volgens een schema opslaan. Kubernetes biedt een handige functie met behulp van cronjob, maar hier steekt Cassandra zelf een spaak in onze wielen.

Laat me je eraan herinneren dat Cassandra een deel van de gegevens in het geheugen opslaat. Om een ​​volledige back-up te maken, hebt u gegevens uit het geheugen nodig (Memtafels) verplaatsen naar schijf (SSTabellen). Op dit punt stopt het Cassandra-knooppunt met het accepteren van verbindingen en wordt het volledig afgesloten van het cluster.

Hierna wordt de back-up verwijderd (momentopname) en het schema wordt opgeslagen (sleutelruimte). En dan blijkt dat alleen een back-up ons niets oplevert: we moeten de gegevensidentificaties opslaan waarvoor het Cassandra-knooppunt verantwoordelijk was - dit zijn speciale tokens.

Migratie van Cassandra naar Kubernetes: functies en oplossingen
Distributie van tokens om te identificeren voor welke gegevens Cassandra-knooppunten verantwoordelijk zijn

Een voorbeeldscript voor het maken van een Cassandra-back-up van Google in Kubernetes is te vinden op deze link. Het enige punt waar het script geen rekening mee houdt, is het opnieuw instellen van gegevens op het knooppunt voordat de momentopname wordt gemaakt. Dat wil zeggen dat de back-up niet wordt uitgevoerd voor de huidige staat, maar voor een staat iets eerder. Maar dit helpt om het knooppunt niet buiten bedrijf te stellen, wat heel logisch lijkt.

set -eu

if [[ -z "$1" ]]; then
  info "Please provide a keyspace"
  exit 1
fi

KEYSPACE="$1"

result=$(nodetool snapshot "${KEYSPACE}")

if [[ $? -ne 0 ]]; then
  echo "Error while making snapshot"
  exit 1
fi

timestamp=$(echo "$result" | awk '/Snapshot directory: / { print $3 }')

mkdir -p /tmp/backup

for path in $(find "/var/lib/cassandra/data/${KEYSPACE}" -name $timestamp); do
  table=$(echo "${path}" | awk -F "[/-]" '{print $7}')
  mkdir /tmp/backup/$table
  mv $path /tmp/backup/$table
done


tar -zcf /tmp/backup.tar.gz -C /tmp/backup .

nodetool clearsnapshot "${KEYSPACE}"

Een voorbeeld van een bash-script voor het maken van een back-up van één Cassandra-knooppunt

Kant-en-klare oplossingen voor Cassandra in Kubernetes

Wat wordt momenteel gebruikt om Cassandra in Kubernetes te implementeren en welke past het beste bij de gegeven vereisten?

1. Oplossingen op basis van StatefulSet- of Helm-grafieken

Het is een goede optie om de basisfuncties van StatefulSets te gebruiken om een ​​Cassandra-cluster uit te voeren. Met behulp van de Helm-grafiek en Go-sjablonen kunt u de gebruiker een flexibele interface bieden voor het implementeren van Cassandra.

Dit werkt meestal prima... totdat er iets onverwachts gebeurt, zoals een knooppuntstoring. Standaard Kubernetes-tools kunnen simpelweg geen rekening houden met alle hierboven beschreven functies. Bovendien is deze aanpak zeer beperkt in de mate waarin deze kan worden uitgebreid voor complexere toepassingen: knooppuntvervanging, back-up, herstel, monitoring, enz.

Vertegenwoordigers:

Beide grafieken zijn even goed, maar zijn onderhevig aan de hierboven beschreven problemen.

2. Oplossingen gebaseerd op Kubernetes Operator

Dergelijke opties zijn interessanter omdat ze ruime mogelijkheden bieden voor het beheer van het cluster. Voor het ontwerpen van een Cassandra-operator, zoals elke andere database, ziet een goed patroon eruit als Sidecar <-> Controller <-> CRD:

Migratie van Cassandra naar Kubernetes: functies en oplossingen
Knooppuntbeheerschema in een goed ontworpen Cassandra-operator

Laten we eens kijken naar bestaande operators.

1. Cassandra-operator van instaclustr

  • GitHub
  • Bereidheid: Alfa
  • Licentie: Apache 2.0
  • Geïmplementeerd in: Java

Dit is inderdaad een veelbelovend en zich actief ontwikkelend project van een bedrijf dat beheerde Cassandra-implementaties aanbiedt. Het gebruikt, zoals hierboven beschreven, een zijspancontainer die opdrachten via HTTP accepteert. Het is geschreven in Java en mist soms de meer geavanceerde functionaliteit van de client-go-bibliotheek. Ook ondersteunt de operator geen verschillende racks voor één datacenter.

Maar de operator heeft voordelen als ondersteuning voor monitoring, clusterbeheer op hoog niveau met behulp van CRD en zelfs documentatie voor het maken van back-ups.

2. Navigator van Jetstack

  • GitHub
  • Bereidheid: Alfa
  • Licentie: Apache 2.0
  • Geïmplementeerd in: Golang

Een instructie die is ontworpen om DB-as-a-Service te implementeren. Ondersteunt momenteel twee databases: Elasticsearch en Cassandra. Het heeft zulke interessante oplossingen als databasetoegangscontrole via RBAC (hiervoor heeft het een eigen aparte navigator-apiserver). Een interessant project dat de moeite waard zou zijn om nader te bekijken, maar de laatste toezegging is anderhalf jaar geleden gedaan, wat het potentieel ervan duidelijk vermindert.

3. Cassandra-operator door vgkowski

  • GitHub
  • Bereidheid: Alfa
  • Licentie: Apache 2.0
  • Geïmplementeerd in: Golang

Ze vonden het niet ‘serieus’, aangezien de laatste commit aan de repository meer dan een jaar geleden was. Operatorontwikkeling wordt stopgezet: de nieuwste versie van Kubernetes die als ondersteund wordt gerapporteerd, is 1.9.

4. Cassandra-operator van Rook

  • GitHub
  • Bereidheid: Alfa
  • Licentie: Apache 2.0
  • Geïmplementeerd in: Golang

Een operator waarvan de ontwikkeling niet zo snel gaat als we zouden willen. Het heeft een goed doordachte CRD-structuur voor clusterbeheer, lost het probleem op van het identificeren van knooppunten met behulp van Service met ClusterIP (dezelfde "hack")... maar dat is alles voor nu. Er is momenteel geen monitoring of back-ups out-of-the-box (we zijn trouwens voor monitoring hebben het zelf meegenomen). Een interessant punt is dat je ScyllaDB ook kunt inzetten met deze operator.

NB: Wij hebben deze operator met kleine aanpassingen gebruikt in een van onze projecten. Er werden geen problemen opgemerkt in het werk van de operator gedurende de gehele gebruiksperiode (~4 maanden werking).

5. CassKop van Orange

  • GitHub
  • Bereidheid: Alfa
  • Licentie: Apache 2.0
  • Geïmplementeerd in: Golang

De jongste operator op de lijst: de eerste commit werd gemaakt op 23 mei 2019. Het heeft nu al een groot aantal functies uit onze lijst in zijn arsenaal, waarvan meer details te vinden zijn in de projectrepository. De operator is gebouwd op basis van de populaire operator-sdk. Ondersteunt out-of-the-box monitoring. Het belangrijkste verschil met andere operators is het gebruik CassKop-plug-in, geïmplementeerd in Python en gebruikt voor communicatie tussen Cassandra-knooppunten.

Bevindingen

Het aantal benaderingen en mogelijke opties voor het porten van Cassandra naar Kubernetes spreekt voor zich: er is veel vraag naar het onderwerp.

In dit stadium kunt u al het bovenstaande op eigen risico proberen: geen van de ontwikkelaars garandeert een 100% werking van hun oplossing in een productieomgeving. Maar veel producten zien er nu al veelbelovend uit om te gebruiken in ontwikkelingsbanken.

Ik denk dat deze vrouw op het schip in de toekomst van pas zal komen!

PS

Lees ook op onze blog:

Bron: www.habr.com

Voeg een reactie