Migrasi Cassandra ke Kubernetes: fitur dan solusi

Migrasi Cassandra ke Kubernetes: fitur dan solusi

Kami sering menemukan database Apache Cassandra dan kebutuhan untuk mengoperasikannya dalam infrastruktur berbasis Kubernetes. Dalam materi ini, kami akan berbagi visi kami tentang langkah-langkah yang diperlukan, kriteria, dan solusi yang ada (termasuk gambaran umum operator) untuk memigrasikan Cassandra ke K8.

“Siapapun yang bisa memerintah seorang wanita, dia juga bisa memerintah negara”

Siapa Cassandra? Ini adalah sistem penyimpanan terdistribusi yang dirancang untuk mengelola data dalam jumlah besar sekaligus memastikan ketersediaan tinggi tanpa satu titik kegagalan pun. Proyek ini hampir tidak memerlukan pengenalan yang panjang, jadi saya hanya akan memberikan fitur utama Cassandra yang relevan dalam konteks artikel tertentu:

  • Cassandra ditulis dalam bahasa Jawa.
  • Topologi Cassandra mencakup beberapa level:
    • Node - satu instance Cassandra yang diterapkan;
    • Rack adalah sekelompok instance Cassandra, disatukan oleh beberapa karakteristik, yang terletak di pusat data yang sama;
    • Pusat Data - kumpulan semua grup instance Cassandra yang terletak di satu pusat data;
    • Cluster adalah kumpulan seluruh pusat data.
  • Cassandra menggunakan alamat IP untuk mengidentifikasi sebuah node.
  • Untuk mempercepat operasi penulisan dan pembacaan, Cassandra menyimpan sebagian data dalam RAM.

Sekarang - menuju potensi perpindahan sebenarnya ke Kubernetes.

Daftar periksa untuk transfer

Berbicara tentang migrasi Cassandra ke Kubernetes, kami berharap dengan perpindahan ini pengelolaannya akan lebih mudah. Apa yang diperlukan untuk ini, apa yang akan membantu dalam hal ini?

1. Penyimpanan data

Seperti yang sudah dijelaskan, Cassanda menyimpan sebagian datanya di RAM - in Tabel Memtable. Tetapi ada bagian lain dari data yang disimpan ke disk - dalam bentuk SSTabel. Entitas ditambahkan ke data ini Log Komit — catatan semua transaksi, yang juga disimpan ke disk.

Migrasi Cassandra ke Kubernetes: fitur dan solusi
Tulis diagram transaksi di Cassandra

Di Kubernetes, kita bisa menggunakan PersistentVolume untuk menyimpan data. Berkat mekanisme yang telah terbukti, bekerja dengan data di Kubernetes menjadi lebih mudah setiap tahunnya.

Migrasi Cassandra ke Kubernetes: fitur dan solusi
Kami akan mengalokasikan PersistentVolume kami sendiri ke setiap pod Cassandra

Penting untuk dicatat bahwa Cassandra sendiri menyiratkan replikasi data, menawarkan mekanisme bawaan untuk ini. Oleh karena itu, jika Anda membangun cluster Cassandra dari sejumlah besar node, maka tidak perlu menggunakan sistem terdistribusi seperti Ceph atau GlusterFS untuk penyimpanan data. Dalam hal ini, logis untuk menyimpan data pada disk host menggunakan disk persisten lokal atau pemasangan hostPath.

Pertanyaan lainnya adalah apakah Anda ingin membuat lingkungan terpisah bagi pengembang untuk setiap cabang fitur. Dalam hal ini, pendekatan yang benar adalah dengan meningkatkan satu node Cassandra dan menyimpan data dalam penyimpanan terdistribusi, yaitu. Ceph dan GlusterFS yang disebutkan akan menjadi pilihan Anda. Kemudian pengembang akan yakin bahwa dia tidak akan kehilangan data pengujian meskipun salah satu node cluster Kuberntes hilang.

2. Pemantauan

Pilihan yang hampir tidak terbantahkan untuk mengimplementasikan pemantauan di Kubernetes adalah Prometheus (kami membicarakan hal ini secara rinci di laporan terkait). Bagaimana kinerja Cassandra dengan eksportir metrik untuk Prometheus? Dan yang lebih penting lagi, dengan dasbor yang cocok untuk Grafana?

Migrasi Cassandra ke Kubernetes: fitur dan solusi
Contoh tampilan grafik di Grafana untuk Cassandra

Hanya ada dua eksportir: jmx_eksportir и cassandra_eksportir.

Kami memilih yang pertama untuk diri kami sendiri karena:

  1. JMX Eksportir semakin tumbuh dan berkembang, sedangkan Cassandra Eksportir belum mampu mendapatkan dukungan masyarakat yang cukup. Cassandra Eksportir masih tidak mendukung sebagian besar versi Cassandra.
  2. Anda dapat menjalankannya sebagai javaagent dengan menambahkan sebuah flag -javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180.
  3. Ada satu untuknya dasbor yang memadai, yang tidak kompatibel dengan Cassandra Eksportir.

3. Memilih primitif Kubernetes

Berdasarkan struktur cluster Cassandra di atas, mari kita coba menerjemahkan semua yang dijelaskan di sana ke dalam terminologi Kubernetes:

  • Node Cassandra → Polong
  • Rak Cassandra → StatefulSet
  • Pusat Data Cassandra → kumpulan dari StatefulSets
  • Gugus Cassandra → ???

Ternyata ada beberapa entitas tambahan yang hilang untuk mengelola seluruh cluster Cassandra sekaligus. Namun jika sesuatu tidak ada, kita bisa menciptakannya! Kubernetes memiliki mekanisme untuk menentukan sumber dayanya sendiri untuk tujuan ini - Definisi Sumber Daya Kustom.

Migrasi Cassandra ke Kubernetes: fitur dan solusi
Mendeklarasikan sumber daya tambahan untuk log dan peringatan

Tetapi Sumber Daya Kustom itu sendiri tidak berarti apa-apa: itu memerlukannya pengontrol. Anda mungkin perlu mencari bantuan Operator Kubernetes...

4. Identifikasi pod

Pada paragraf di atas, kita sepakat bahwa satu node Cassandra sama dengan satu pod di Kubernetes. Namun alamat IP pod akan berbeda setiap saat. Dan identifikasi sebuah node di Cassandra didasarkan pada alamat IP... Ternyata setelah setiap penghapusan sebuah pod, cluster Cassandra akan menambahkan node baru.

Ada jalan keluarnya, dan bukan hanya satu:

  1. Kita dapat menyimpan catatan berdasarkan pengidentifikasi host (UUID yang secara unik mengidentifikasi instance Cassandra) atau berdasarkan alamat IP dan menyimpan semuanya di beberapa struktur/tabel. Metode ini memiliki dua kelemahan utama:
    • Risiko terjadinya kondisi balapan jika dua node jatuh secara bersamaan. Setelah naik, node Cassandra akan secara bersamaan meminta alamat IP dari tabel dan bersaing untuk mendapatkan sumber daya yang sama.
    • Jika node Cassandra kehilangan datanya, kami tidak dapat lagi mengidentifikasinya.
  2. Solusi kedua tampak seperti peretasan kecil, namun demikian: kita dapat membuat Layanan dengan ClusterIP untuk setiap node Cassandra. Masalah dengan implementasi ini:
    • Jika ada banyak node dalam cluster Cassandra, kita harus membuat banyak Layanan.
    • Fitur ClusterIP diimplementasikan melalui iptables. Hal ini dapat menjadi masalah jika cluster Cassandra memiliki banyak (1000... atau bahkan 100?) node. Meskipun penyeimbangan berdasarkan IPVS dapat memecahkan masalah ini.
  3. Solusi ketiga adalah menggunakan jaringan node untuk node Cassandra alih-alih jaringan pod khusus dengan mengaktifkan pengaturan hostNetwork: true. Metode ini mempunyai batasan tertentu:
    • Untuk mengganti unit. Node baru harus memiliki alamat IP yang sama dengan yang sebelumnya (di cloud seperti AWS, GCP, hal ini hampir tidak mungkin dilakukan);
    • Dengan menggunakan jaringan node cluster, kami mulai bersaing untuk mendapatkan sumber daya jaringan. Oleh karena itu, menempatkan lebih dari satu pod dengan Cassandra pada satu node cluster akan menjadi masalah.

5. Cadangan

Kami ingin menyimpan versi lengkap data satu node Cassandra sesuai jadwal. Kubernetes menyediakan fitur yang mudah digunakan Pekerjaan Cron, tapi di sini Cassandra sendiri yang berbicara di roda kami.

Izinkan saya mengingatkan Anda bahwa Cassandra menyimpan sebagian data dalam memori. Untuk membuat cadangan penuh, Anda memerlukan data dari memori (tabel mem) pindah ke disk (SSTable). Pada titik ini, node Cassandra berhenti menerima koneksi, sepenuhnya dimatikan dari cluster.

Setelah ini, cadangan dihapus (foto) dan skema disimpan (ruang kunci). Dan ternyata cadangan saja tidak memberi kita apa-apa: kita perlu menyimpan pengidentifikasi data yang menjadi tanggung jawab node Cassandra - ini adalah token khusus.

Migrasi Cassandra ke Kubernetes: fitur dan solusi
Distribusi token untuk mengidentifikasi data apa yang menjadi tanggung jawab node Cassandra

Contoh skrip untuk mengambil cadangan Cassandra dari Google di Kubernetes dapat ditemukan di link ini. Satu-satunya hal yang tidak diperhitungkan oleh skrip adalah menyetel ulang data ke node sebelum mengambil snapshot. Artinya, pencadangan dilakukan bukan untuk keadaan saat ini, tetapi untuk keadaan sebelumnya. Tapi ini membantu untuk tidak menghentikan operasi node, yang tampaknya sangat logis.

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 cadangan dari satu node Cassandra

Solusi siap pakai untuk Cassandra di Kubernetes

Apa yang saat ini digunakan untuk menerapkan Cassandra di Kubernetes dan manakah yang paling sesuai dengan persyaratan yang diberikan?

1. Solusi berdasarkan grafik StatefulSet atau Helm

Menggunakan fungsi dasar StatefulSets untuk menjalankan cluster Cassandra adalah pilihan yang baik. Dengan menggunakan diagram Helm dan templat Go, Anda dapat menyediakan antarmuka yang fleksibel kepada pengguna untuk menerapkan Cassandra.

Ini biasanya berfungsi dengan baik... sampai sesuatu yang tidak terduga terjadi, seperti kegagalan node. Alat Kubernetes standar tidak bisa memperhitungkan semua fitur yang dijelaskan di atas. Selain itu, pendekatan ini sangat terbatas dalam hal seberapa luas pendekatan ini dapat diperluas untuk penggunaan yang lebih kompleks: penggantian node, pencadangan, pemulihan, pemantauan, dll.

Perwakilan:

Kedua grafik tersebut sama-sama bagus, namun memiliki masalah yang dijelaskan di atas.

2. Solusi berdasarkan Operator Kubernetes

Opsi seperti ini lebih menarik karena memberikan banyak peluang untuk mengelola cluster. Untuk mendesain operator Cassandra, seperti database lainnya, pola yang bagus terlihat seperti Sidecar <-> Controller <-> CRD:

Migrasi Cassandra ke Kubernetes: fitur dan solusi
Skema manajemen node dalam operator Cassandra yang dirancang dengan baik

Mari kita lihat operator yang ada.

1. Cassandra-operator dari instaclustr

  • GitHub
  • Kesiapan: Alfa
  • Lisensi: Apache 2.0
  • Diimplementasikan di: Jawa

Ini memang merupakan proyek yang sangat menjanjikan dan berkembang secara aktif dari perusahaan yang menawarkan penerapan Cassandra terkelola. Ini, seperti dijelaskan di atas, menggunakan wadah sespan yang menerima perintah melalui HTTP. Ditulis dalam Java, terkadang tidak memiliki fungsionalitas yang lebih canggih dari perpustakaan client-go. Selain itu, operator tidak mendukung Rak yang berbeda untuk satu Pusat Data.

Namun operator memiliki keunggulan seperti dukungan pemantauan, manajemen cluster tingkat tinggi menggunakan CRD, dan bahkan dokumentasi untuk membuat cadangan.

2. Navigator dari Jetstack

  • GitHub
  • Kesiapan: Alfa
  • Lisensi: Apache 2.0
  • Diimplementasikan di: Golang

Pernyataan yang dirancang untuk menyebarkan DB-as-a-Service. Saat ini mendukung dua database: Elasticsearch dan Cassandra. Ia memiliki solusi menarik seperti kontrol akses basis data melalui RBAC (untuk ini ia memiliki navigator-apiserver tersendiri). Sebuah proyek menarik yang layak untuk dicermati, tetapi komitmen terakhir dibuat satu setengah tahun yang lalu, yang jelas mengurangi potensinya.

3. Operator Cassandra oleh vgkowski

  • GitHub
  • Kesiapan: Alfa
  • Lisensi: Apache 2.0
  • Diimplementasikan di: Golang

Mereka tidak menganggapnya “serius”, karena komitmen terakhir ke repositori terjadi lebih dari setahun yang lalu. Pengembangan operator ditinggalkan: versi terbaru Kubernetes yang dilaporkan didukung adalah 1.9.

4. Operator Cassandra oleh Benteng

  • GitHub
  • Kesiapan: Alfa
  • Lisensi: Apache 2.0
  • Diimplementasikan di: Golang

Operator yang perkembangannya tidak berkembang secepat yang kita inginkan. Ini memiliki struktur CRD yang dipikirkan dengan matang untuk manajemen cluster, memecahkan masalah identifikasi node menggunakan Layanan dengan ClusterIP (“peretasan” yang sama… tapi itu saja untuk saat ini. Saat ini tidak ada pemantauan atau cadangan (omong-omong, kami sedang memantau mengambilnya sendiri). Hal yang menarik adalah Anda juga dapat menerapkan ScyllaDB menggunakan operator ini.

NB: Kami menggunakan operator ini dengan sedikit modifikasi di salah satu proyek kami. Tidak ada masalah yang terlihat pada pekerjaan operator selama seluruh periode operasi (~4 bulan pengoperasian).

5. CassKop dari Jeruk

  • GitHub
  • Kesiapan: Alfa
  • Lisensi: Apache 2.0
  • Diimplementasikan di: Golang

Operator termuda dalam daftar: komitmen pertama dilakukan pada 23 Mei 2019. Sekarang ia memiliki sejumlah besar fitur dari daftar kami, rincian lebih lanjut dapat ditemukan di repositori proyek. Operator ini dibangun berdasarkan operator-sdk yang populer. Mendukung pemantauan di luar kotak. Perbedaan utama dari operator lain adalah penggunaannya Plugin CassKop, diimplementasikan dengan Python dan digunakan untuk komunikasi antar node Cassandra.

Temuan

Jumlah pendekatan dan opsi yang memungkinkan untuk mem-porting Cassandra ke Kubernetes membuktikan hal ini: topiknya sangat diminati.

Pada tahap ini, Anda dapat mencoba salah satu cara di atas dengan risiko dan risiko Anda sendiri: tidak ada pengembang yang menjamin 100% pengoperasian solusi mereka di lingkungan produksi. Namun saat ini, banyak produk yang terlihat menjanjikan untuk dicoba digunakan di bangku pengembangan.

Saya pikir di masa depan wanita di kapal ini akan berguna!

PS

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komentar