Migracija Cassandre na Kubernetes: značajke i rješenja

Migracija Cassandre na Kubernetes: značajke i rješenja

Redovito se susrećemo s bazom podataka Apache Cassandra i potrebom da njome upravljamo unutar infrastrukture temeljene na Kubernetesu. U ovom materijalu podijelit ćemo našu viziju potrebnih koraka, kriterija i postojećih rješenja (uključujući pregled operatera) za migraciju Cassandre na K8s.

“Tko može vladati ženom, može vladati i državom”

Tko je Cassandra? To je distribuirani sustav za pohranu dizajniran za upravljanje velikim količinama podataka uz osiguranje visoke dostupnosti bez ijedne točke kvara. Projekt jedva da treba dug uvod, stoga ću dati samo glavne značajke Cassandre koje će biti relevantne u kontekstu određenog članka:

  • Cassandra je napisana na Javi.
  • Topologija Cassandra uključuje nekoliko razina:
    • Čvor - jedna postavljena Cassandra instanca;
    • Rack je skupina Cassandra instanci, ujedinjenih nekim karakteristikama, smještenih u istom podatkovnom centru;
    • Podatkovni centar - skup svih grupa Cassandra instanci smještenih u jednom podatkovnom centru;
    • Klaster je skup svih podatkovnih centara.
  • Cassandra koristi IP adresu za identifikaciju čvora.
  • Kako bi ubrzala operacije pisanja i čitanja, Cassandra pohranjuje neke podatke u RAM.

Sada - do stvarnog potencijalnog prelaska na Kubernetes.

Kontrolna lista za prijenos

Govoreći o migraciji Cassandre na Kubernetes, nadamo se da će s prelaskom postati praktičnija za upravljanje. Što će biti potrebno za to, što će pomoći u tome?

1. Pohrana podataka

Kao što je već pojašnjeno, Cassanda pohranjuje dio podataka u RAM - u Memtable. Ali postoji još jedan dio podataka koji se sprema na disk – u obrascu SSTable. Ovim podacima dodaje se entitet Dnevnik predaje — zapisi svih transakcija, koji se također spremaju na disk.

Migracija Cassandre na Kubernetes: značajke i rješenja
Napišite transakcijski dijagram u Cassandri

U Kubernetesu možemo koristiti PersistentVolume za pohranu podataka. Zahvaljujući provjerenim mehanizmima, rad s podacima u Kubernetesu iz godine u godinu postaje sve lakši.

Migracija Cassandre na Kubernetes: značajke i rješenja
Dodijelit ćemo 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, tada nema potrebe za korištenjem distribuiranih sustava kao što su Ceph ili GlusterFS za pohranu podataka. U ovom slučaju bilo bi logično pohraniti podatke na host disk pomoću lokalni postojani diskovi ili montažu hostPath.

Drugo je pitanje želite li stvoriti zasebno okruženje za programere za svaku granu značajke. U ovom bi slučaju ispravan pristup bio podizanje jednog Cassandra čvora i pohranjivanje podataka u distribuiranu pohranu, tj. spomenuti Ceph i GlusterFS bit će 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. Praćenje

Gotovo neosporan izbor za implementaciju nadzora u Kubernetesu je Prometheus (o tome smo detaljno razgovarali u povezano izvješće). Kako stoji Cassandra s izvoznicima metrike za Prometheus? I, što je još važnije, s odgovarajućim nadzornim pločama za Grafanu?

Migracija Cassandre na Kubernetes: značajke i rješenja
Primjer izgleda grafova u Grafani za Cassandru

Postoje samo dva izvoznika: jmx_izvoznik и cassandra_izvoznik.

Za sebe smo odabrali prvu jer:

  1. JMX Exporter raste i razvija se, dok Cassandra Exporter nije uspio dobiti dovoljnu podršku zajednice. Cassandra Exporter još uvijek ne podržava većinu verzija Cassandre.
  2. Možete ga pokrenuti kao javaagent dodavanjem oznake -javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180.
  3. Ima jedna za njega odgovarajuća instrument tabla, koji nije kompatibilan s Cassandra Exporter.

3. Odabir Kubernetes primitiva

U skladu s gornjom strukturom klastera Cassandra, pokušajmo prevesti sve što je tamo opisano u terminologiju Kubernetesa:

  • Čvor Cassandra → Pod
  • Cassandra Rack → StatefulSet
  • Cassandra Datacenter → bazen iz StatefulSets-a
  • Grozd Cassandra → ???

Ispostavilo se da nedostaje neki dodatni entitet za upravljanje cijelim Cassandra klasterom odjednom. Ali ako nešto ne postoji, mi to možemo stvoriti! Kubernetes ima mehanizam za definiranje vlastitih resursa za tu svrhu - Prilagođene definicije resursa.

Migracija Cassandre na Kubernetes: značajke i rješenja
Deklariranje dodatnih resursa za zapisnike i upozorenja

Ali Custom Resource sam po sebi ne znači ništa: na kraju krajeva, on zahtijeva kontrolor. Možda ćete morati potražiti pomoć Kubernetes operater...

4. Identifikacija mahuna

U gornjem paragrafu, složili smo se da će jedan Cassandra čvor biti jednak jednom podu u Kubernetesu. Ali IP adrese mahuna bit će različite svaki put. A identifikacija čvora u Cassandri temelji se na IP adresi... Ispada da će nakon svakog uklanjanja mahune Cassandra klaster dodati novi čvor.

Postoji izlaz, i to ne samo jedan:

  1. Možemo voditi evidenciju prema identifikatorima računala (UUID-ovi koji jedinstveno identificiraju Cassandra instance) ili prema IP adresama i sve to pohraniti u neke strukture/tablice. Metoda ima dva glavna nedostatka:
    • Rizik od stanja trke ako dva čvora padnu odjednom. Nakon porasta, Cassandra čvorovi će istovremeno tražiti IP adresu iz tablice i natjecati se za isti resurs.
    • Ako je Cassandra čvor izgubio svoje podatke, više ga nećemo moći identificirati.
  2. Drugo rješenje izgleda kao mali hack, ali ipak: možemo stvoriti uslugu s ClusterIP za svaki Cassandra čvor. Problemi s ovom implementacijom:
    • Ako postoji mnogo čvorova u klasteru Cassandra, morat ćemo stvoriti mnogo usluga.
    • Značajka ClusterIP implementirana je putem iptables. To može postati problem ako Cassandra klaster ima mnogo (1000... ili čak 100?) čvorova. Iako balansiranje na temelju IPVS-a može riješiti ovaj problem.
  3. Treće rješenje je korištenje mreže čvorova za Cassandra čvorove umjesto namjenske mreže mahuna omogućavanjem postavke hostNetwork: true. Ova metoda nameće određena ograničenja:
    • Za zamjenu jedinica. Nužno je da novi čvor mora imati istu IP adresu kao prethodni (u oblacima poput AWS, GCP to je gotovo nemoguće učiniti);
    • Koristeći mrežu čvorova klastera, počinjemo se natjecati za mrežne resurse. Stoga će postavljanje više od jednog modula s Cassandrom na jedan čvor klastera biti problematično.

5. Sigurnosne kopije

Želimo spremiti punu verziju podataka jednog Cassandra čvora na rasporedu. Kubernetes pruža praktičnu značajku korištenja CronJob, ali ovdje nam sama Cassandra ubacuje žbicu u kotače.

Dopustite mi da vas podsjetim da Cassandra pohranjuje neke od podataka u memoriju. Za izradu pune sigurnosne kopije potrebni su vam podaci iz memorije (Memtables) premjestiti na disk (SSTables). U ovom trenutku čvor Cassandra prestaje prihvaćati veze, potpuno se isključujući iz klastera.

Nakon toga se sigurnosna kopija uklanja (snimak) i shema je spremljena (razmak tipki). A onda se ispostavi da nam samo sigurnosna kopija ne daje ništa: moramo spremiti identifikatore podataka za koje je Cassandra čvor bio odgovoran - to su posebni tokeni.

Migracija Cassandre na Kubernetes: značajke i rješenja
Distribucija tokena za identifikaciju za koje podatke su odgovorni Cassandra čvorovi

Primjer skripte za preuzimanje sigurnosne kopije Cassandre od Googlea u Kubernetesu može se pronaći na ovaj link. Jedina točka koju skripta ne uzima u obzir je resetiranje podataka na čvor prije snimanja snimke. To jest, backup se ne izvodi za trenutno stanje, već za stanje malo ranije. Ali to 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 pravljenje sigurnosne kopije s jednog Cassandra čvora

Gotova rješenja za Cassandru u Kubernetesu

Što se trenutno koristi za implementaciju Cassandre u Kubernetesu i što od toga najbolje odgovara zadanim zahtjevima?

1. Rješenja temeljena na StatefulSet ili Helm kartama

Korištenje osnovnih StatefulSets funkcija za pokretanje Cassandra klastera dobra je opcija. Koristeći Helm chart i Go predloške, možete korisniku pružiti fleksibilno sučelje za implementaciju Cassandre.

Ovo obično dobro funkcionira... 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 je pristup vrlo ograničen u tome koliko se može proširiti za složenije upotrebe: zamjena čvora, sigurnosno kopiranje, oporavak, nadzor itd.

predstavnici:

Obje karte su jednako dobre, ali podliježu gore opisanim problemima.

2. Rješenja temeljena na Kubernetes Operatoru

Takve opcije su zanimljivije jer pružaju široke mogućnosti za upravljanje klasterom. Za dizajniranje Cassandra operatora, kao i bilo koje druge baze podataka, dobar uzorak izgleda kao Sidecar <-> Controller <-> CRD:

Migracija Cassandre na Kubernetes: značajke i rješenja
Shema upravljanja čvorovima u dobro osmišljenom Cassandra operatoru

Pogledajmo postojeće operatere.

1. Cassandra-operator iz instaclustr

  • GitHub
  • Spremnost: Alfa
  • Licenca: Apache 2.0
  • Implementirano u: Java

Ovo je doista projekt koji obećava i aktivno se razvija od tvrtke koja nudi upravljane implementacije Cassandre. On, kao što je gore opisano, koristi spremnik s prikolicom koji prihvaća naredbe putem HTTP-a. Napisan u Javi, ponekad mu nedostaje naprednija funkcionalnost klijentske biblioteke. Također, operater ne podržava različite police za jedan podatkovni centar.

Ali operater ima takve prednosti kao što su podrška za praćenje, upravljanje klasterom na visokoj razini pomoću CRD-a, pa čak i dokumentaciju za izradu sigurnosnih kopija.

2. Navigator iz Jetstacka

  • GitHub
  • Spremnost: Alfa
  • Licenca: Apache 2.0
  • Implementirano u: Golang

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 putem RBAC-a (za to ima svoj zasebni navigator-apiserver). Zanimljiv projekt koji bi se isplatilo pobliže pogledati, no posljednji commit je napravljen prije godinu i pol, što jasno umanjuje njegov potencijal.

3. Cassandra-operator od vgkowskog

  • GitHub
  • Spremnost: Alfa
  • Licenca: Apache 2.0
  • Implementirano u: Golang

Nisu to smatrali "ozbiljnim", budući da je posljednji commit u repozitorij bio prije više od godinu dana. Razvoj operatera je napušten: najnovija verzija Kubernetesa prijavljena kao podržana je 1.9.

4. Cassandra-operator od Rooka

  • GitHub
  • Spremnost: Alfa
  • Licenca: Apache 2.0
  • Implementirano u: Golang

Operater čiji razvoj ne napreduje brzinom kojom bismo željeli. Ima dobro promišljenu CRD strukturu za upravljanje klasterima, rješava problem identifikacije čvorova pomoću usluge s ClusterIP (isti "hack")... ali to je sve za sada. Trenutačno nema nadzora niti sigurnosnih kopija izvan okvira (usput, mi smo za nadzor uzeli sami). Zanimljivo je da također možete implementirati ScyllaDB koristeći ovaj operator.

NB: Koristili smo ovaj operator uz manje izmjene u jednom od naših projekata. Tijekom cijelog perioda rada (~4 mjeseca rada) nisu uočeni problemi u radu operatera.

5. CassKop iz Orangea

  • GitHub
  • Spremnost: Alfa
  • Licenca: Apache 2.0
  • Implementirano u: Golang

Najmlađi operater na listi: prvi commit napravljen je 23. svibnja 2019. Već sada u svom arsenalu ima velik broj značajki s našeg popisa, o kojima se više detalja može pronaći u repozitoriju projekta. Operator je izgrađen na temelju popularnog operator-sdk. Podržava praćenje izvan kutije. Glavna razlika od ostalih operatera je korištenje CassKop dodatak, implementiran u Pythonu i korišten za komunikaciju između Cassandra čvorova.

Zaključci

Broj pristupa i mogućih opcija za prijenos Cassandre na Kubernetes govori sam za sebe: tema je tražena.

U ovoj fazi možete isprobati bilo što od gore navedenog na vlastitu odgovornost i rizik: niti jedan od programera ne jamči 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 mi u budućnosti ova žena na brodu dobro doći!

PS

Pročitajte i na našem blogu:

Izvor: www.habr.com

Dodajte komentar