Cassandra migrációja Kubernetesre: funkciók és megoldások
Rendszeresen találkozunk az Apache Cassandra adatbázissal és azzal, hogy Kubernetes-alapú infrastruktúrán belül kell működtetni. Ebben az anyagban megosztjuk elképzelésünket a szükséges lépésekről, kritériumokról és meglévő megoldásokról (beleértve az operátorok áttekintését is) a Cassandra K8s-ra való migrálásához.
"Aki uralni tud egy nőt, az uralkodhat az államon is"
Ki az a Cassandra? Ez egy elosztott tárolórendszer, amelyet nagy mennyiségű adat kezelésére terveztek, miközben magas rendelkezésre állást biztosít egyetlen hibapont nélkül. A projektet aligha kell hosszasan bemutatni, ezért csak a Cassandra főbb jellemzőit adom meg, amelyek egy adott cikk kontextusában relevánsak lesznek:
A Cassandra Java nyelven íródott.
A Cassandra topológia több szintet foglal magában:
Csomópont – egy telepített Cassandra-példány;
A Rack Cassandra-példányok csoportja, amelyeket egyes jellemzők egyesítenek, és amelyek ugyanabban az adatközpontban találhatók;
Adatközpont – a Cassandra-példányok összes csoportja egy adatközpontban található;
A fürt az összes adatközpont gyűjteménye.
Cassandra IP-címet használ a csomópont azonosítására.
Az írási és olvasási műveletek felgyorsítása érdekében a Cassandra az adatok egy részét a RAM-ban tárolja.
Most - a tényleges lehetséges átköltözéshez a Kuberneteshez.
Ellenőrző lista az átvitelhez
A Cassandra Kubernetesbe költözéséről szólva reméljük, hogy a költözéssel kényelmesebbé válik a kezelés. Mi kell ehhez, mi segít ezen?
1. Adattárolás
Amint azt már tisztáztuk, a Cassanda az adatok egy részét a RAM-ban tárolja Emlékezhető. De van egy másik része az adatoknak, amelyek a lemezre kerülnek - az űrlapon SSTable. A rendszer hozzáad egy entitást ehhez az adathoz Végrehajtási napló — az összes tranzakció rekordja, amely szintén lemezre kerül.
Írjon tranzakciós diagramot Cassandra nyelven
A Kubernetesben a PersistentVolume-ot használhatjuk adatok tárolására. A bevált mechanizmusoknak köszönhetően az adatokkal való munka a Kubernetesben évről évre könnyebbé válik.
Minden Cassandra podhoz saját PersistentVolume-ot rendelünk
Fontos megjegyezni, hogy a Cassandra magában foglalja az adatreplikációt, és ehhez beépített mechanizmusokat kínál. Ezért ha nagyszámú csomópontból épít Cassandra-fürtöt, akkor nincs szükség olyan elosztott rendszerekre, mint a Ceph vagy a GlusterFS az adattárolásra. Ebben az esetben logikus lenne az adatokat a gazdalemezen tárolni a használatával helyi állandó lemezek vagy szerelés hostPath.
Másik kérdés, hogy minden szolgáltatásághoz külön környezetet akarunk-e létrehozni a fejlesztők számára. Ebben az esetben a helyes megközelítés az lenne, ha felemelnénk egy Cassandra csomópontot, és az adatokat egy elosztott tárolóban tárolnánk, pl. az említett Ceph és GlusterFS lesz a választásod. Ekkor a fejlesztő biztos lesz abban, hogy a tesztadatokat akkor sem veszíti el, ha a Kuberntes-fürt egyik csomópontja elveszik.
2. Monitoring
A Kubernetes monitorozásának gyakorlatilag vitathatatlan választása a Prometheus (erről részletesen itt beszéltünk kapcsolódó jelentés). Hogy áll Cassandra a Prometheus mérőszám-exportőreivel? És mi a még fontosabb, hogy a Grafana számára megfelelő műszerfalak?
Példa a grafikonok megjelenésére a Grafana for Cassandra számára
A JMX Exporter növekszik és fejlődik, míg a Cassandra Exporter nem kapott elegendő közösségi támogatást. A Cassandra Exporter továbbra sem támogatja a Cassandra legtöbb verzióját.
Futtathatja javaagentként egy zászló hozzáadásával -javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180.
Van egy neki megfelelő műszerfal, amely nem kompatibilis a Cassandra Exporterrel.
3. Kubernetes primitívek kiválasztása
A Cassandra klaszter fenti struktúrája szerint próbáljunk meg mindent lefordítani Kubernetes terminológiára:
Cassandra Node → Pod
Cassandra Rack → StatefulSet
Cassandra Datacenter → készlet a StatefulSets-től
Cassandra Cluster → ???
Kiderült, hogy hiányzik néhány további entitás a teljes Cassandra-fürt egyszerre történő kezeléséhez. De ha valami nem létezik, megalkothatjuk! A Kubernetes rendelkezik egy olyan mechanizmussal, amely erre a célra saját erőforrásait határozza meg - Egyéni erőforrás-definíciók.
További erőforrások deklarálása naplókhoz és riasztásokhoz
De az Egyéni Erőforrás önmagában nem jelent semmit: végül is megköveteli ellenőr. Lehet, hogy segítséget kell kérnie Kubernetes operátor...
4. A hüvelyek azonosítása
A fenti bekezdésben megállapodtunk abban, hogy egy Cassandra-csomópont a Kubernetesben egy pod lesz. De a hüvelyek IP-címe minden alkalommal más lesz. A Cassandra csomópontjának azonosítása pedig az IP-címen alapul... Kiderült, hogy minden egyes pod eltávolítása után a Cassandra-fürt új csomópontot ad hozzá.
Van kiút, és nem csak egy:
A rekordokat gazdagépazonosítók (UUID-k, amelyek egyedileg azonosítják a Cassandra-példányokat) vagy IP-címek alapján vezethetjük, és mindezt eltárolhatjuk bizonyos struktúrákban/táblázatokban. A módszernek két fő hátránya van:
A versenyhelyzet előfordulásának kockázata, ha két csomópont egyszerre esik le. Az emelkedés után a Cassandra csomópontok egyszerre kérnek IP-címet a táblázatból, és versenyeznek ugyanazért az erőforrásért.
Ha egy Cassandra csomópont elvesztette az adatait, többé nem tudjuk azonosítani.
A második megoldás kis hacknek tűnik, de ennek ellenére: minden Cassandra csomóponthoz létrehozhatunk egy Service-t ClusterIP-vel. Problémák ezzel a megvalósítással:
Ha sok csomópont van egy Cassandra-fürtben, akkor sok szolgáltatást kell létrehoznunk.
A ClusterIP szolgáltatás az iptables-on keresztül valósul meg. Ez problémát jelenthet, ha a Cassandra klaszternek sok (1000... vagy akár 100?) csomópontja van. Habár IPVS alapú kiegyensúlyozás meg tudja oldani ezt a problémát.
A harmadik megoldás az, hogy a Cassandra-csomópontokhoz csomópont-hálózatot használunk egy dedikált pod-hálózat helyett a beállítás engedélyezésével. hostNetwork: true. Ez a módszer bizonyos korlátozásokat ír elő:
Egységek cseréjéhez. Szükséges, hogy az új csomópontnak ugyanazzal az IP-címmel kell rendelkeznie, mint az előzőnek (felhőkben, mint az AWS, GCP ez szinte lehetetlen);
A fürtcsomópontok hálózatát használva versenyezni kezdünk a hálózati erőforrásokért. Emiatt egynél több Cassandrát tartalmazó pod elhelyezése egy fürtcsomóponton problémás lesz.
5. Biztonsági mentések
Egyetlen Cassandra csomópont adatainak teljes verzióját szeretnénk menteni ütemezetten. A Kubernetes kényelmes funkciót biztosít CronJob, de itt Cassandra maga tesz küllőt a kerekeinkbe.
Hadd emlékeztesselek arra, hogy Cassandra az adatok egy részét a memóriában tárolja. A teljes biztonsági mentéshez adatokra van szükség a memóriából (Memtables) mozgassa a lemezre (SSTtables). Ezen a ponton a Cassandra csomópont már nem fogad kapcsolatokat, és teljesen leáll a fürtből.
Ezt követően a biztonsági másolat eltávolításra kerül (snapshot) és a séma mentésre kerül (keyspace). Aztán kiderül, hogy pusztán egy biztonsági mentés nem ad nekünk semmit: el kell mentenünk azokat az adatazonosítókat, amelyekért a Cassandra csomópont felelős volt - ezek speciális tokenek.
Tokenek elosztása annak azonosítására, hogy a Cassandra csomópontok milyen adatokért felelősek
A Kubernetes rendszerben található Cassandra biztonsági másolat készítésére szolgáló példaszkript a következő címen található: ez a kapcsolat. Az egyetlen pont, amit a szkript nem vesz figyelembe, az az adatok visszaállítása a csomópontra a pillanatkép készítése előtt. Vagyis a biztonsági mentés nem az aktuális állapotra, hanem egy kicsit korábbi állapotra történik. De ez segít abban, hogy a csomópont ne kerüljön ki a működésből, ami nagyon logikusnak tűnik.
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}"
Példa egy bash-szkriptre, amellyel biztonsági másolatot készíthet egy Cassandra csomópontról
Kész megoldások Cassandra számára Kubernetesben
Jelenleg mit használnak a Cassandra telepítéséhez a Kubernetesben, és ezek közül melyik felel meg a legjobban az adott követelményeknek?
1. StatefulSet vagy Helm diagramokon alapuló megoldások
Az alapvető StatefulSets függvények használata Cassandra-fürt futtatásához jó lehetőség. A Helm diagram és a Go sablonok segítségével rugalmas felületet biztosíthat a felhasználónak a Cassandra telepítéséhez.
Ez általában jól működik... amíg valami váratlan nem történik, például csomóponthiba. A szabványos Kubernetes-eszközök egyszerűen nem tudják figyelembe venni a fent leírt összes funkciót. Ezenkívül ez a megközelítés nagyon korlátozott abban, hogy mennyivel bővíthető összetettebb felhasználásokra: csomópontcsere, biztonsági mentés, helyreállítás, figyelés stb.
Mindkét diagram egyformán jó, de ki vannak téve a fent leírt problémáknak.
2. Kubernetes Operator alapú megoldások
Az ilyen lehetőségek érdekesebbek, mert bőséges lehetőséget kínálnak a fürt kezelésére. Cassandra operátor tervezésénél, mint bármely más adatbázisnál, egy jó minta így néz ki: Sidecar <-> Controller <-> CRD:
Csomópontkezelési séma egy jól megtervezett Cassandra operátorban
Ez valóban egy nagyon ígéretes és aktívan fejlődő projekt egy olyan cégtől, amely felügyelt Cassandra telepítéseket kínál. A fent leírtak szerint oldalkocsis tárolót használ, amely HTTP-n keresztül fogadja el a parancsokat. Java nyelven írva néha hiányzik a client-go könyvtár fejlettebb funkciói. Ezenkívül az üzemeltető nem támogatja a különböző állványokat egy adatközponthoz.
Az üzemeltetőnek azonban olyan előnyei vannak, mint a monitorozás támogatása, a CRD-vel végzett magas szintű fürtkezelés, és még a biztonsági mentések készítésének dokumentációja is.
A DB-as-a-Service üzembe helyezésére szolgáló utasítás. Jelenleg két adatbázist támogat: Elasticsearch és Cassandra. Olyan érdekes megoldásai vannak, mint az adatbázis hozzáférés vezérlése RBAC-on keresztül (ehhez külön navigátor-apiszerverrel rendelkezik). Érdekes projekt, amit érdemes lenne közelebbről is szemügyre venni, de az utolsó commit másfél éve történt, ami egyértelműen csökkenti a benne rejlő lehetőségeket.
Nem vették „komolyan”, hiszen az utolsó kötelezettségvállalás több mint egy éve volt a tárhelyen. Az operátorfejlesztést felhagyták: a Kubernetes támogatottként bejelentett legújabb verziója az 1.9.
Egy üzemeltető, akinek a fejlesztése nem halad olyan gyorsan, mint szeretnénk. Jól átgondolt CRD-struktúrával rendelkezik a fürtkezeléshez, megoldja a csomópontok azonosítását a Service with ClusterIP segítségével (ugyanaz a „hack”)... de egyelőre ennyi. Jelenleg nincs felügyelet vagy biztonsági mentés (egyébként a monitorozásért vagyunk). magunk vettük). Érdekes pont, hogy a ScyllaDB-t is telepítheti ezzel az operátorral.
Megjegyzés: Kisebb módosításokkal ezt az operátort használtuk az egyik projektünkben. A teljes üzemidő alatt (~4 hónap üzemidő) nem észleltek problémát a kezelő munkájában.
A legfiatalabb operátor a listán: az első commit 23. május 2019-án történt. Már most is nagyszámú szolgáltatást tartalmaz a listánkból, amelyek további részleteit a projekttárban találja. Az operátor a népszerű operator-sdk alapján épül fel. Támogatja a felügyeletet a dobozból. A fő különbség a többi operátorhoz képest a használat CassKop bővítményPythonban implementálva, és a Cassandra csomópontok közötti kommunikációra használják.
Álláspontja
A Cassandra Kubernetesre történő portolásának számos megközelítése és lehetséges lehetőségei önmagáért beszélnek: a téma keresett.
Ebben a szakaszban a fentiek bármelyikét kipróbálhatja saját felelősségére és kockázatára: egyik fejlesztő sem garantálja a megoldás 100%-os működését éles környezetben. De már most sok termék ígéretesnek tűnik a fejlesztői padokban való felhasználásra.
Szerintem a jövőben jól fog jönni ez a nő a hajón!