Migracija Cassandre na Kubernetes: karakteristike i rješenja
Redovno se susrećemo sa bazom podataka Apache Cassandra i potrebom da se njome upravlja unutar infrastrukture zasnovane na Kubernetesu. U ovom materijalu ćemo podijeliti našu viziju potrebnih koraka, kriterija i postojećih rješenja (uključujući pregled operatera) za migraciju Cassandre na K8s.
“Ko može da vlada ženom može i državom”
Ko je Kasandra? To je distribuirani sistem skladištenja dizajniran za upravljanje velikim količinama podataka uz obezbeđivanje visoke dostupnosti bez ijedne tačke kvara. Projekt jedva da treba dugo predstavljati, pa ću dati samo glavne karakteristike Cassandre koje će biti relevantne u kontekstu konkretnog članka:
Cassandra je napisana na Javi.
Cassandra topologija uključuje nekoliko nivoa:
Čvor - jedna raspoređena Cassandra instanca;
Rack je grupa Cassandra instanci, ujedinjenih nekim karakteristikama, smještenih u istom podatkovnom centru;
Datacenter - zbirka svih grupa Cassandra instanci smještenih u jednom podatkovnom centru;
Klaster je skup svih data centara.
Cassandra koristi IP adresu za identifikaciju čvora.
Kako bi ubrzala operacije pisanja i čitanja, Cassandra pohranjuje dio podataka u RAM.
Sada - do stvarnog potencijalnog prelaska na Kubernetes.
Kontrolna lista za transfer
Govoreći o migraciji Cassandre na Kubernetes, nadamo se da će s tim potezom postati praktičnije za upravljanje. Šta će biti potrebno za ovo, šta će pomoći u tome?
1. Skladištenje podataka
Kao što je već pojašnjeno, Cassanda dio podataka pohranjuje u RAM-u Memtable. Ali postoji još jedan dio podataka koji se pohranjuje na disk - u obrascu SSTable. Ovim podacima se dodaje entitet Commit Log — zapisi svih transakcija, koji se takođe čuvaju na disku.
Napišite transakcioni dijagram u Cassandri
U Kubernetesu možemo koristiti PersistentVolume za pohranjivanje podataka. Zahvaljujući dokazanim mehanizmima, rad sa podacima u Kubernetesu iz godine u godinu postaje sve lakši.
Mi ćemo dodijeliti vlastiti PersistentVolume svakoj Cassandra mahuni
Važno je napomenuti da sama Cassandra podrazumijeva replikaciju podataka, nudeći ugrađene mehanizme za to. Stoga, ako gradite Cassandra klaster od velikog broja čvorova, onda nema potrebe da koristite distribuirane sisteme kao što su Ceph ili GlusterFS za skladištenje podataka. U ovom slučaju, bilo bi logično pohraniti podatke na host disk koristeći lokalni trajni diskovi ili montaža hostPath.
Drugo pitanje je da li želite da kreirate posebno okruženje za programere za svaku granu karakteristika. U ovom slučaju, ispravan pristup bi bio podizanje jednog Cassandra čvora i pohranjivanje podataka u distribuirano skladište, tj. pomenuti Ceph i GlusterFS će biti vaše opcije. Tada će programer biti siguran da neće izgubiti testne podatke čak i ako se izgubi jedan od čvorova Kuberntes klastera.
2. Monitoring
Gotovo neosporan izbor za implementaciju nadgledanja u Kubernetes je Prometheus (o tome smo detaljno razgovarali u povezani izvještaj). Kako je Cassandra s izvoznicima metrike za Prometheus? I, što je još važnije, s odgovarajućim kontrolnim pločama za Grafanu?
JMX Exporter raste i razvija se, dok Cassandra Exporter nije mogao dobiti dovoljnu podršku zajednice. Cassandra Exporter još uvijek ne podržava većinu verzija Cassandre.
Možete ga pokrenuti kao javaagent dodavanjem zastavice -javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180.
Prema gornjoj strukturi klastera Cassandra, pokušajmo sve što je tamo opisano prevesti u Kubernetes terminologiju:
Cassandra Node → Pod
Cassandra Rack → StatefulSet
Cassandra Datacenter → bazen iz StatefulSets-a
Cassandra Cluster → ???
Ispostavilo se da nedostaje neki dodatni entitet za upravljanje cijelim Cassandra klasterom odjednom. Ali ako nešto ne postoji, možemo to stvoriti! Kubernetes ima mehanizam za definisanje sopstvenih resursa u tu svrhu - Prilagođene definicije resursa.
Deklarisanje dodatnih resursa za dnevnike i upozorenja
Ali prilagođeni resurs sam po sebi ne znači ništa: na kraju krajeva, on zahtijeva kontroler. Možda ćete morati potražiti pomoć Kubernetes operater...
4. Identifikacija mahuna
U gornjem paragrafu, dogovorili smo se da će jedan Cassandra čvor jednak jednom podu u Kubernetesu. Ali IP adrese podova će svaki put biti različite. A identifikacija čvora u Cassandri se zasniva na IP adresi... Ispada da će nakon svakog uklanjanja pod-a Cassandra klaster dodati novi čvor.
Postoji izlaz, i to ne samo jedan:
Možemo voditi evidenciju prema identifikatorima hosta (UUID-ovi koji jedinstveno identificiraju Cassandra instance) ili po IP adresama i sve to pohraniti u neke strukture/tabele. Metoda ima dva glavna nedostatka:
Rizik od pojave stanja trke ako dva čvora padnu odjednom. Nakon porasta, Cassandra čvorovi će istovremeno tražiti IP adresu iz tabele i takmičiti se za isti resurs.
Ako je Cassandra čvor izgubio svoje podatke, više ga nećemo moći identificirati.
Drugo rješenje izgleda kao mali hak, ali ipak: možemo kreirati uslugu sa ClusterIP-om za svaki Cassandra čvor. Problemi sa ovom implementacijom:
Ako postoji mnogo čvorova u Cassandra klasteru, morat ćemo kreirati mnogo usluga.
Funkcija ClusterIP implementirana je putem iptables. Ovo može postati problem ako Cassandra klaster ima mnogo (1000... ili čak 100?) čvorova. Iako balansiranje zasnovano na IPVS može riješiti ovaj problem.
Treće rješenje je korištenje mreže čvorova za Cassandra čvorove umjesto namjenske mreže podova omogućavanjem postavke hostNetwork: true. Ova metoda nameće određena ograničenja:
Za zamjenu jedinica. Neophodno je da novi čvor mora imati istu IP adresu kao prethodni (u oblacima kao što su AWS, GCP to je gotovo nemoguće učiniti);
Koristeći mrežu čvorova klastera, počinjemo se nadmetati za mrežne resurse. Stoga će postavljanje više od jednog pod sa Cassandra na jedan čvor klastera biti problematično.
5. Sigurnosne kopije
Želimo da sačuvamo punu verziju podataka jednog Cassandra čvora na rasporedu. Kubernetes pruža zgodnu funkciju za korišćenje CronJob, ali ovdje nam sama Cassandra stavlja žbicu u točkove.
Da vas podsjetim da Cassandra neke podatke pohranjuje u memoriju. Da biste napravili potpunu sigurnosnu kopiju, potrebni su vam podaci iz memorije (Memtables) premjestiti na disk (SSTables). U ovom trenutku Cassandra čvor prestaje da prihvata veze, potpuno se isključujući iz klastera.
Nakon toga, sigurnosna kopija se uklanja (snimak) i shema je spremljena (keyspace). A onda se ispostavi da nam samo rezervna kopija ne daje ništa: moramo sačuvati identifikatore podataka za koje je bio odgovoran Cassandra čvor - to su posebni tokeni.
Distribucija tokena za identifikaciju za koje su podatke Cassandra čvorovi odgovorni
Primjer skripte za preuzimanje sigurnosne kopije Cassandre od Google-a u Kubernetesu možete pronaći na ovaj link. Jedina stvar koju skripta ne uzima u obzir je resetiranje podataka na čvor prije snimanja snimka. Odnosno, sigurnosna kopija se ne vrši za trenutno stanje, već za stanje nešto ranije. Ali ovo pomaže da se čvor ne isključi iz rada, što se čini vrlo logičnim.
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}"
Primjer bash skripte za uzimanje sigurnosne kopije sa jednog Cassandra čvora
Spremna rješenja za Cassandru u Kubernetesu
Šta se trenutno koristi za postavljanje Cassandre u Kubernetes i šta od ovoga najbolje odgovara datim zahtevima?
1. Rješenja zasnovana na StatefulSet ili Helm grafikonima
Korištenje osnovnih funkcija StatefulSets za pokretanje Cassandra klastera je dobra opcija. Koristeći Helm chart i Go predloške, možete pružiti korisniku fleksibilno sučelje za implementaciju Cassandre.
Ovo obično dobro funkcionira... sve dok se ne dogodi nešto neočekivano, kao što je kvar čvora. Standardni Kubernetes alati jednostavno ne mogu uzeti u obzir sve gore opisane karakteristike. Osim toga, ovaj pristup je vrlo ograničen u tome koliko se može proširiti za složenije upotrebe: zamjena čvorova, sigurnosna kopija, oporavak, praćenje itd.
Obje karte su podjednako dobre, ali su podložne gore opisanim problemima.
2. Rešenja zasnovana na Kubernetes Operatoru
Takve opcije su interesantnije jer pružaju široke mogućnosti za upravljanje klasterom. Za dizajniranje Cassandra operatora, kao i bilo koje druge baze podataka, dobar obrazac izgleda kao Sidecar <-> Controller <-> CRD:
Šema upravljanja čvorovima u dobro dizajniranom Cassandra operateru
Ovo je zaista vrlo obećavajući projekt koji se aktivno razvija od kompanije koja nudi upravljane implementacije Cassandre. Kao što je gore opisano, koristi bočni kontejner koji prihvata komande putem HTTP-a. Napisano u Javi, ponekad mu nedostaje naprednija funkcionalnost biblioteke za pokretanje klijenta. Također, operater ne podržava različite Rackove za jedan Datacenter.
Ali operater ima takve prednosti kao što su podrška za praćenje, upravljanje klasterima na visokom nivou pomoću CRD-a, pa čak i dokumentacija za pravljenje rezervnih kopija.
Izjava dizajnirana za implementaciju DB-as-a-Service. Trenutno podržava dvije baze podataka: Elasticsearch i Cassandra. Ima tako zanimljiva rješenja kao što je kontrola pristupa bazi podataka preko RBAC-a (za to ima svoj zasebni navigator-apiserver). Zanimljiv projekat koji bi vrijedilo bolje pogledati, ali posljednji angažman je napravljen prije godinu i po dana, što jasno umanjuje njegov potencijal.
Nisu to smatrali "ozbiljno", pošto je posljednje urezivanje u spremište bilo prije više od godinu dana. Razvoj operatera je napušten: najnovija verzija Kubernetesa prijavljena kao podržana je 1.9.
Operater čiji razvoj ne napreduje tako brzo koliko bismo željeli. Ima dobro osmišljenu CRD strukturu za upravljanje klasterima, rješava problem identifikacije čvorova koristeći Service with ClusterIP (isti "hack")... ali to je sve za sada. Trenutno nema nadzora ili rezervnih kopija iz kutije (usput, mi smo za praćenje sami smo ga uzeli). Zanimljiva stvar je da također možete implementirati ScyllaDB koristeći ovaj operator.
Napomena: Koristili smo ovaj operater sa manjim modifikacijama u jednom od naših projekata. Tokom čitavog perioda rada (~4 mjeseca rada) nisu uočeni nikakvi problemi u radu operatera.
Najmlađi operater na listi: prva obrada je izvršena 23. Već sada ima u svom arsenalu veliki broj funkcija sa naše liste, više detalja o kojima možete pronaći u repozitoriju projekta. Operator je izgrađen na bazi popularnog operatora-sdk. Podržava nadgledanje iz kutije. Glavna razlika od ostalih operatera je upotreba CassKop dodatak, implementiran u Python-u i korišten za komunikaciju između Cassandra čvorova.
nalazi
Broj pristupa i mogućih opcija za portiranje Cassandre u Kubernetes govori sam za sebe: tema je tražena.
U ovoj fazi, možete isprobati bilo šta od gore navedenog na vlastitu odgovornost i rizik: nijedan od programera ne garantuje 100% rad svog rješenja u proizvodnom okruženju. Ali već sada mnogi proizvodi izgledaju obećavajuće za isprobavanje u razvojnim stolovima.
Mislim da će u budućnosti ova žena na brodu dobro doći!