Penghijrahan Cassandra ke Kubernetes: ciri dan penyelesaian

Penghijrahan Cassandra ke Kubernetes: ciri dan penyelesaian

Kami kerap menemui pangkalan data Apache Cassandra dan keperluan untuk mengendalikannya dalam infrastruktur berasaskan Kubernetes. Dalam bahan ini, kami akan berkongsi visi kami tentang langkah, kriteria dan penyelesaian sedia ada yang diperlukan (termasuk gambaran keseluruhan pengendali) untuk memindahkan Cassandra ke K8.

"Sesiapa yang boleh memerintah seorang wanita juga boleh memerintah negeri"

Siapa Cassandra? Ia adalah sistem storan teragih yang direka untuk mengurus volum data yang besar sambil memastikan ketersediaan tinggi tanpa satu titik kegagalan. Projek ini hampir tidak memerlukan pengenalan yang panjang, jadi saya hanya akan memberikan ciri utama Cassandra yang akan relevan dalam konteks artikel tertentu:

  • Cassandra ditulis dalam bahasa Jawa.
  • Topologi Cassandra merangkumi beberapa peringkat:
    • Nod - satu contoh Cassandra yang digunakan;
    • Rack ialah sekumpulan contoh Cassandra, disatukan oleh beberapa ciri, terletak di pusat data yang sama;
    • Pusat Data - koleksi semua kumpulan kejadian Cassandra yang terletak dalam satu pusat data;
    • Kluster ialah koleksi semua pusat data.
  • Cassandra menggunakan alamat IP untuk mengenal pasti nod.
  • Untuk mempercepatkan operasi menulis dan membaca, Cassandra menyimpan beberapa data dalam RAM.

Sekarang - kepada potensi sebenar berpindah ke Kubernetes.

Senarai semak untuk pemindahan

Bercakap tentang penghijrahan Cassandra ke Kubernetes, kami berharap dengan perpindahan itu ia akan menjadi lebih mudah untuk diuruskan. Apa yang diperlukan untuk ini, apa yang akan membantu dengan ini?

1. Penyimpanan data

Seperti yang telah dijelaskan, Cassanda menyimpan sebahagian daripada data dalam RAM - in Memtable. Tetapi terdapat satu lagi bahagian data yang disimpan ke cakera - dalam bentuk SSTable. Entiti ditambahkan pada data ini Log Komit β€” rekod semua transaksi, yang juga disimpan ke cakera.

Penghijrahan Cassandra ke Kubernetes: ciri dan penyelesaian
Tulis rajah transaksi dalam Cassandra

Dalam Kubernetes, kita boleh menggunakan PersistentVolume untuk menyimpan data. Terima kasih kepada mekanisme yang terbukti, bekerja dengan data dalam Kubernetes menjadi lebih mudah setiap tahun.

Penghijrahan Cassandra ke Kubernetes: ciri dan penyelesaian
Kami akan memperuntukkan PersistentVolume kami sendiri untuk setiap pod Cassandra

Adalah penting untuk ambil perhatian bahawa Cassandra sendiri membayangkan replikasi data, menawarkan mekanisme terbina dalam untuk ini. Oleh itu, jika anda membina gugusan Cassandra daripada sejumlah besar nod, maka tidak perlu menggunakan sistem teragih seperti Ceph atau GlusterFS untuk penyimpanan data. Dalam kes ini, adalah logik untuk menyimpan data pada cakera hos menggunakan cakera berterusan tempatan atau pemasangan hostPath.

Soalan lain ialah jika anda ingin mencipta persekitaran yang berasingan untuk pembangun untuk setiap cawangan ciri. Dalam kes ini, pendekatan yang betul ialah menaikkan satu nod Cassandra dan menyimpan data dalam storan teragih, i.e. Ceph dan GlusterFS yang disebutkan akan menjadi pilihan anda. Kemudian pembangun akan memastikan bahawa dia tidak akan kehilangan data ujian walaupun salah satu nod kluster Kuberntes hilang.

2. Pemantauan

Pilihan yang hampir tidak dapat dipertikaikan untuk melaksanakan pemantauan dalam Kubernetes ialah Prometheus (kami bercakap tentang ini secara terperinci dalam laporan berkaitan). Bagaimanakah keadaan Cassandra dengan pengeksport metrik untuk Prometheus? Dan, apa yang lebih penting, dengan papan pemuka yang sepadan untuk Grafana?

Penghijrahan Cassandra ke Kubernetes: ciri dan penyelesaian
Contoh penampilan graf dalam Grafana untuk Cassandra

Terdapat hanya dua pengeksport: jmx_exporter ΠΈ cassandra_exporter.

Kami memilih yang pertama untuk diri kami sendiri kerana:

  1. JMX Exporter sedang berkembang dan berkembang, manakala Cassandra Exporter belum dapat mendapatkan sokongan komuniti yang mencukupi. Cassandra Exporter masih tidak menyokong kebanyakan versi Cassandra.
  2. Anda boleh menjalankannya sebagai javaagent dengan menambah bendera -javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180.
  3. Ada satu untuk dia papan pemuka yang mencukupi, yang tidak serasi dengan Cassandra Exporter.

3. Memilih primitif Kubernetes

Menurut struktur gugusan Cassandra di atas, mari cuba menterjemah semua yang diterangkan di sana ke dalam terminologi Kubernetes:

  • Cassandra Node β†’ Pod
  • Cassandra Rack β†’ StatefulSet
  • Pusat Data Cassandra β†’ kumpulan daripada StatefulSets
  • Kluster Cassandra β†’ ???

Ternyata beberapa entiti tambahan tiada untuk mengurus keseluruhan gugusan Cassandra sekaligus. Tetapi jika sesuatu tidak wujud, kita boleh menciptanya! Kubernetes mempunyai mekanisme untuk menentukan sumbernya sendiri untuk tujuan ini - Definisi Sumber Tersuai.

Penghijrahan Cassandra ke Kubernetes: ciri dan penyelesaian
Mengisytiharkan sumber tambahan untuk log dan makluman

Tetapi Sumber Tersuai itu sendiri tidak bermakna apa-apa: selepas semua, ia memerlukan pengawal. Anda mungkin perlu mendapatkan bantuan pengendali Kubernetes...

4. Pengenalpastian buah

Dalam perenggan di atas, kami bersetuju bahawa satu nod Cassandra akan menyamai satu pod dalam Kubernetes. Tetapi alamat IP pod akan berbeza setiap kali. Dan pengenalpastian nod dalam Cassandra adalah berdasarkan alamat IP... Ternyata selepas setiap penyingkiran pod, kluster Cassandra akan menambah nod baharu.

Terdapat jalan keluar, dan bukan hanya satu:

  1. Kami boleh menyimpan rekod mengikut pengecam hos (UUID yang mengenal pasti kejadian Cassandra secara unik) atau dengan alamat IP dan menyimpan semuanya dalam beberapa struktur/jadual. Kaedah ini mempunyai dua kelemahan utama:
    • Risiko keadaan perlumbaan berlaku jika dua nod jatuh serentak. Selepas peningkatan, nod Cassandra akan meminta alamat IP secara serentak daripada jadual dan bersaing untuk sumber yang sama.
    • Jika nod Cassandra telah kehilangan datanya, kami tidak akan dapat mengenal pastinya lagi.
  2. Penyelesaian kedua kelihatan seperti penggodaman kecil, tetapi bagaimanapun: kami boleh mencipta Perkhidmatan dengan ClusterIP untuk setiap nod Cassandra. Masalah dengan pelaksanaan ini:
    • Jika terdapat banyak nod dalam gugusan Cassandra, kami perlu mencipta banyak Perkhidmatan.
    • Ciri ClusterIP dilaksanakan melalui iptables. Ini boleh menjadi masalah jika kluster Cassandra mempunyai banyak (1000... atau 100?) nod. Walaupun mengimbangi berdasarkan IPVS dapat menyelesaikan masalah ini.
  3. Penyelesaian ketiga ialah menggunakan rangkaian nod untuk nod Cassandra dan bukannya rangkaian pod khusus dengan mendayakan tetapan hostNetwork: true. Kaedah ini mengenakan sekatan tertentu:
    • Untuk menggantikan unit. Adalah perlu bahawa nod baharu mesti mempunyai alamat IP yang sama seperti yang sebelumnya (dalam awan seperti AWS, GCP ini hampir mustahil untuk dilakukan);
    • Menggunakan rangkaian nod kluster, kami mula bersaing untuk mendapatkan sumber rangkaian. Oleh itu, meletakkan lebih daripada satu pod dengan Cassandra pada satu nod kluster akan menjadi masalah.

5. Sandaran

Kami ingin menyimpan versi penuh data nod Cassandra tunggal pada jadual. Kubernetes menyediakan ciri yang mudah digunakan CronJob, tetapi di sini Cassandra sendiri meletakkan jejari dalam roda kami.

Biar saya ingatkan anda bahawa Cassandra menyimpan beberapa data dalam ingatan. Untuk membuat sandaran penuh, anda memerlukan data daripada memori (Memtables) pindah ke cakera (SSTables). Pada ketika ini, nod Cassandra berhenti menerima sambungan, menutup sepenuhnya daripada kluster.

Selepas ini, sandaran dialih keluar (gambar) dan skema disimpan (ruang kekunci). Dan kemudian ternyata bahawa hanya sandaran tidak memberi kita apa-apa: kita perlu menyimpan pengecam data yang mana nod Cassandra bertanggungjawab - ini adalah token khas.

Penghijrahan Cassandra ke Kubernetes: ciri dan penyelesaian
Pengedaran token untuk mengenal pasti data yang bertanggungjawab untuk nod Cassandra

Skrip contoh untuk mengambil sandaran Cassandra daripada Google dalam Kubernetes boleh didapati di pautan ini. Satu-satunya perkara yang tidak diambil kira oleh skrip ialah menetapkan semula data ke nod sebelum mengambil gambar. Iaitu, sandaran dilakukan bukan untuk keadaan semasa, tetapi untuk keadaan sedikit lebih awal. Tetapi ini membantu untuk tidak mengeluarkan nod daripada operasi, yang kelihatan sangat logik.

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}"

Contoh skrip bash untuk mengambil sandaran daripada satu nod Cassandra

Penyelesaian sedia untuk Cassandra di Kubernetes

Apakah yang kini digunakan untuk menggunakan Cassandra dalam Kubernetes dan yang manakah antara ini paling sesuai dengan keperluan yang diberikan?

1. Penyelesaian berdasarkan carta StatefulSet atau Helm

Menggunakan fungsi StatefulSets asas untuk menjalankan gugusan Cassandra ialah pilihan yang baik. Menggunakan carta Helm dan templat Go, anda boleh menyediakan pengguna dengan antara muka yang fleksibel untuk menggunakan Cassandra.

Ini biasanya berfungsi dengan baik... sehingga sesuatu yang tidak dijangka berlaku, seperti kegagalan nod. Alat Kubernetes standard tidak boleh mengambil kira semua ciri yang diterangkan di atas. Selain itu, pendekatan ini sangat terhad dalam jumlah ia boleh dilanjutkan untuk kegunaan yang lebih kompleks: penggantian nod, sandaran, pemulihan, pemantauan, dsb.

wakil:

Kedua-dua carta adalah sama baik, tetapi tertakluk kepada masalah yang diterangkan di atas.

2. Penyelesaian berdasarkan Operator Kubernetes

Pilihan sedemikian adalah lebih menarik kerana ia menyediakan peluang yang luas untuk menguruskan kluster. Untuk mereka bentuk pengendali Cassandra, seperti mana-mana pangkalan data lain, corak yang baik kelihatan seperti Sidecar <-> Controller <-> CRD:

Penghijrahan Cassandra ke Kubernetes: ciri dan penyelesaian
Skim pengurusan nod dalam pengendali Cassandra yang direka dengan baik

Mari kita lihat operator sedia ada.

1. Cassandra-operator dari instaclustr

  • GitHub
  • Kesediaan: Alpha
  • Lesen: Apache 2.0
  • Dilaksanakan dalam: Java

Ini sememangnya projek yang sangat menjanjikan dan sedang dibangunkan secara aktif daripada syarikat yang menawarkan penempatan Cassandra terurus. Ia, seperti yang diterangkan di atas, menggunakan bekas kereta sampingan yang menerima arahan melalui HTTP. Ditulis dalam Java, ia kadangkala tidak mempunyai fungsi yang lebih maju bagi perpustakaan klien-go. Selain itu, pengendali tidak menyokong Rak berbeza untuk satu Pusat Data.

Tetapi pengendali mempunyai kelebihan seperti sokongan untuk pemantauan, pengurusan kluster peringkat tinggi menggunakan CRD, dan juga dokumentasi untuk membuat sandaran.

2. Navigator daripada Jetstack

  • GitHub
  • Kesediaan: Alpha
  • Lesen: Apache 2.0
  • Dilaksanakan di: Golang

Kenyataan yang direka untuk menggunakan DB-as-a-Service. Pada masa ini menyokong dua pangkalan data: Elasticsearch dan Cassandra. Ia mempunyai penyelesaian yang menarik seperti kawalan capaian pangkalan data melalui RBAC (untuk ini ia mempunyai navigator-apiserver tersendiri). Projek menarik yang patut dilihat dengan lebih dekat, tetapi komitmen terakhir dibuat setahun setengah yang lalu, yang jelas mengurangkan potensinya.

3. Pengendali Cassandra oleh vgkowski

  • GitHub
  • Kesediaan: Alpha
  • Lesen: Apache 2.0
  • Dilaksanakan di: Golang

Mereka tidak menganggapnya "serius", kerana komitmen terakhir untuk repositori adalah lebih daripada setahun yang lalu. Pembangunan operator ditinggalkan: versi terkini Kubernetes yang dilaporkan sebagai disokong ialah 1.9.

4. Cassandra-operator oleh Rook

  • GitHub
  • Kesediaan: Alpha
  • Lesen: Apache 2.0
  • Dilaksanakan di: Golang

Pengendali yang pembangunannya tidak berkembang secepat yang kita mahu. Ia mempunyai struktur CRD yang difikirkan dengan baik untuk pengurusan kluster, menyelesaikan masalah mengenal pasti nod menggunakan Perkhidmatan dengan ClusterIP ("godam" yang sama)... tetapi itu sahaja buat masa ini. Pada masa ini tiada pemantauan atau sandaran di luar kotak (by the way, kami adalah untuk pemantauan ambil sendiri). Perkara yang menarik ialah anda juga boleh menggunakan ScyllaDB menggunakan operator ini.

NB: Kami menggunakan operator ini dengan pengubahsuaian kecil dalam salah satu projek kami. Tiada masalah diperhatikan dalam kerja operator sepanjang tempoh operasi (~4 bulan operasi).

5. CassKop dari Orange

  • GitHub
  • Kesediaan: Alpha
  • Lesen: Apache 2.0
  • Dilaksanakan di: Golang

Pengendali termuda dalam senarai: komitmen pertama dibuat pada 23 Mei 2019. Kini ia mempunyai dalam senjatanya sejumlah besar ciri dari senarai kami, butiran lanjut boleh didapati dalam repositori projek. Operator dibina berdasarkan operator-sdk yang popular. Menyokong pemantauan di luar kotak. Perbezaan utama dari operator lain adalah penggunaan Pemalam CassKop, dilaksanakan dalam Python dan digunakan untuk komunikasi antara nod Cassandra.

Penemuan

Bilangan pendekatan dan pilihan yang mungkin untuk mengalihkan Cassandra ke Kubernetes bercakap untuk dirinya sendiri: topik itu dalam permintaan.

Pada peringkat ini, anda boleh mencuba mana-mana perkara di atas atas risiko dan risiko anda sendiri: tiada pembangun menjamin 100% operasi penyelesaian mereka dalam persekitaran pengeluaran. Tetapi kini banyak produk kelihatan menjanjikan untuk cuba menggunakannya di bangku pembangunan.

Saya fikir pada masa akan datang wanita di atas kapal ini akan berguna!

PS

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komen