
Kami secara teratur menemukan basis data Apache Cassandra dan kebutuhan untuk mengoperasikannya dalam kerangka infrastruktur berbasis Kubernetes. Pada artikel ini, kami akan membagikan visi kami tentang langkah-langkah yang diperlukan, kriteria dan solusi yang ada (termasuk tinjauan umum operator) untuk migrasi Cassandra ke K8s.
"Siapa yang bisa mengendalikan wanita akan mengatasi negara"
Siapakah Cassandra? Ini adalah sistem penyimpanan terdistribusi yang dirancang untuk mengelola sejumlah besar data sambil menyediakan ketersediaan tinggi tanpa satu titik kegagalan. Proyek ini hampir tidak membutuhkan pengenalan yang panjang, jadi saya hanya akan memberikan fitur utama Cassandra, yang akan relevan dalam konteks artikel tertentu:
- Cassandra ditulis dalam bahasa Jawa.
- Topologi Cassandra mencakup beberapa tingkatan:
- Node - satu instance Cassandra;
- Rack - sekelompok instance Cassandra, disatukan oleh atribut apa pun, yang terletak di satu pusat data;
- Datacenter - totalitas semua kelompok instance Cassandra yang terletak di satu pusat data;
- Cluster - kumpulan semua pusat data.
- Cassandra menggunakan alamat IP untuk mengidentifikasi tuan rumah.
- Untuk kecepatan operasi baca dan tulis, Cassandra menyimpan sebagian data dalam RAM.
Sekarang untuk potensi perpindahan aktual ke Kubernetes.
Daftar periksa untuk migrasi
Berbicara tentang migrasi Cassandra ke Kubernetes, kami berharap akan menjadi lebih nyaman untuk mengelolanya dengan langkah tersebut. Apa yang akan diperlukan untuk ini, apa yang akan membantu dalam hal ini?
1. Penyimpanan data
Seperti yang telah ditentukan, bagian dari data yang disimpan Cassanda dalam RAM - dalam
Memtable . Tetapi ada bagian lain dari data yang disimpan ke disk - dalam bentuk
SSTable . Untuk data ini ditambahkan
Log Log entitas - catatan semua transaksi yang juga disimpan ke disk.
Skema Transaksi Tulis CassandraDi Kubernetes, kita bisa menggunakan PersistentVolume untuk menyimpan data. Berkat mekanisme yang dikembangkan dengan baik, bekerja dengan data di Kubernet menjadi lebih mudah setiap tahun.
Untuk setiap pod dengan Cassandra, kami akan mengalokasikan PersistentVolume kamiPenting untuk dicatat bahwa Cassandra sendiri menyiratkan replikasi data, menawarkan mekanisme bawaan untuk ini. Oleh karena itu, jika Anda sedang membangun cluster Cassandra dari sejumlah besar node, maka tidak perlu menggunakan sistem terdistribusi seperti Ceph atau GlusterFS untuk menyimpan data. Dalam hal ini, akan logis untuk menyimpan data pada disk host menggunakan disk
persisten lokal atau memasang
hostPath
.
Pertanyaan lain adalah apakah Anda ingin membuat lingkungan pengembangan yang terpisah untuk setiap cabang fitur. Dalam hal ini, pendekatan yang benar adalah dengan menaikkan satu simpul Cassandra, dan menyimpan data dalam penyimpanan terdistribusi, yaitu Ceph dan GlusterFS yang disebutkan akan menjadi pilihan Anda. Maka pengembang akan yakin bahwa ia tidak akan kehilangan data pengujian bahkan jika salah satu node dari cluster Kuberntes hilang.
2. Pemantauan
Pilihan yang sebenarnya non-alternatif untuk pemantauan di Kubernetes adalah Prometheus
(kami membicarakan hal ini secara rinci dalam laporan terkait ) . Bagaimana kabar Cassandra dengan pengekspor metrik untuk Prometheus? Dan, apa yang lebih penting dalam beberapa hal, dengan dashboard yang cocok untuk mereka untuk Grafana?
Contoh penampilan grafik di Grafana for CassandraHanya ada dua eksportir:
jmx_exporter dan
cassandra_exporter .
Kami memilih yang pertama untuk diri kami sendiri, karena:
- Eksportir JMX tumbuh dan berkembang, sedangkan Eksportir Cassandra belum bisa mendapatkan dukungan masyarakat yang tepat. Eksportir Cassandra masih belum mendukung sebagian besar versi Cassandra.
- Anda dapat menjalankannya sebagai javaagent dengan menambahkan flag
-javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180
. - Baginya ada dashboad yang memadai yang tidak kompatibel dengan Cassandra Eksportir.
3. Pemilihan primitif Kubernetes
Menurut struktur cluster Cassandra di atas, kami akan mencoba menerjemahkan semua yang dijelaskan di sana ke dalam terminologi Kubernetes:
- Cassandra Node → Pod
- Cassandra Rack → StatefulSet
- Cassandra Datacenter → kumpulan dari StatefulSets
- Cassandra Cluster → ???
Ternyata beberapa entitas tambahan hilang untuk mengelola seluruh cluster Cassandra sekaligus. Tetapi jika sesuatu tidak ada di sana, kita dapat membuatnya! Kubernetes memiliki mesin definisi sumber daya khusus yang disebut
Custom Resource Definition .
Pengumuman sumber daya tambahan untuk log dan peringatanTetapi Sumber Daya Kustom saja tidak berarti apa-apa: Anda memerlukan
pengontrol untuk itu. Anda mungkin harus menggunakan bantuan
operator Kubernetes ...
4. Identifikasi polong
Poin di atas, kami sepakat bahwa satu simpul Cassandra akan sama dengan satu pod di Kubernetes. Tetapi alamat IP pod akan berbeda setiap kali. Dan identifikasi node di Cassandra terjadi tepat berdasarkan alamat IP ... Ternyata setelah setiap penghapusan pod, cluster Cassandra akan menambahkan node baru.
Ada jalan keluar, dan bahkan tidak ada satu pun:
- Kami dapat menyimpan catatan dengan pengidentifikasi host (UUID yang secara unik mengidentifikasi contoh Cassandra) atau dengan alamat IP dan menyimpan semua ini dalam beberapa struktur / tabel. Metode ini memiliki dua kelemahan utama:
- Risiko kondisi balapan ketika dua node jatuh sekaligus. Setelah upgrade, node Cassandra akan secara bersamaan pergi untuk meminta alamat IP untuk diri mereka sendiri dari tabel dan bersaing untuk sumber daya yang sama.
- Jika simpul Cassandra telah kehilangan datanya, kami tidak akan lagi dapat mengidentifikasinya.
- Solusi kedua sepertinya hack kecil, tapi tetap saja: kita bisa membuat Layanan dengan ClusterIP untuk setiap simpul Cassandra. Masalah dengan implementasi ini:
- Jika ada banyak node di Cassandra cluster, kami harus membuat banyak Layanan.
- Fitur ClusterIP diimplementasikan melalui iptables. Ini bisa menjadi masalah jika cluster Cassandra memiliki banyak (1000 ... atau bahkan 100?) Node. Meskipun balancing berdasarkan IPVS dapat menyelesaikan masalah ini.
- Solusi ketiga adalah menggunakan jaringan node untuk node Cassandra alih-alih jaringan pod khusus dengan mengaktifkan pengaturan
hostNetwork: true
. Metode ini menerapkan batasan tertentu:
- Untuk mengganti node. Perlu bahwa host baru harus memiliki alamat IP yang sama dengan yang sebelumnya (di awan seperti AWS, GCP, ini hampir tidak mungkin dilakukan);
- Menggunakan jaringan node cluster, kami mulai bersaing untuk sumber daya jaringan. Oleh karena itu, menempatkan satu node cluster lebih dari satu pod dengan Cassandra akan bermasalah.
5. Cadangan
Kami ingin menyimpan versi lengkap data untuk satu simpul Cassandra pada jadwal. Kubernetes memberikan peluang yang nyaman menggunakan
CronJob , tapi di sini Cassandra memasukkan tongkat ke roda.
Biarkan saya mengingatkan Anda bahwa sebagian data yang disimpan Cassandra dalam memori. Untuk membuat cadangan penuh, Anda perlu mentransfer data dari memori (
Memtables ) ke disk (
SSTable ). Pada titik ini, simpul Cassandra berhenti menerima koneksi, sepenuhnya dimatikan dari cluster.
Setelah itu, cadangan (
foto ) dihapus dan skema (
keyspace )
disimpan . Dan kemudian ternyata hanya cadangan tidak memberi kita apa-apa: Anda perlu menyimpan pengidentifikasi data yang bertanggung jawab atas simpul Cassandra - ini adalah token khusus.
Distribusi token untuk mengidentifikasi data mana yang bertanggung jawab atas simpul CassandraContoh skrip untuk menghapus Cassandra dari Google di Kubernetes dapat ditemukan di
tautan ini . Satu-satunya titik bahwa skrip tidak memperhitungkan adalah membuang data ke node sebelum menghapus snapshot. Artinya, pencadangan dilakukan bukan untuk kondisi saat ini, tetapi untuk kondisi sedikit lebih awal. Tapi ini membantu untuk tidak membuat simpul keluar dari pekerjaan, 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 bash script untuk menghapus cadangan dari satu simpul CassandraSolusi siap pakai untuk Cassandra di Kubernetes
Apa yang saat ini mereka gunakan untuk menggunakan Cassandra di Kubernetes, dan mana di antaranya yang paling cocok untuk persyaratan yang diberikan?
1. StatefulSet atau Solusi Helm Chart
Menggunakan StatefulSets dasar untuk memulai Cassandra cluster adalah opsi yang baik. Dengan menggunakan grafik Helm dan templat Go, Anda dapat menyediakan antarmuka fleksibel bagi pengguna untuk menggunakan Cassandra.
Biasanya ini berfungsi dengan baik ... sampai sesuatu yang tidak terduga terjadi - misalnya, sebuah simpul turun. Alat standar Kubernetes tidak bisa memperhitungkan semua fitur di atas. Selain itu, pendekatan ini sangat terbatas dalam hal bagaimana dapat diperluas untuk penggunaan yang lebih kompleks: penggantian node, cadangan, pemulihan, pemantauan, dll.
Perwakilan:
Kedua grafik sama-sama bagus, tetapi rentan terhadap masalah yang dijelaskan di atas.
2. Solusi berdasarkan Operator Kubernetes
Opsi semacam itu lebih menarik karena mereka menyediakan kapabilitas manajemen klaster yang luas. Untuk mendesain pernyataan Cassandra, seperti basis data lainnya, pola yang bagus tampak seperti Sidecar <-> Pengontrol <-> CRD:
Diagram manajemen simpul dalam pernyataan Cassandra yang dirancang dengan baikPertimbangkan operator yang ada.
1. Cassandra-operator oleh instaclustr
- Github
- Kesediaan: Alpha
- Lisensi: Apache 2.0
- Diimplementasikan di: Jawa
Ini memang proyek yang sangat menjanjikan dan berkembang pesat dari sebuah perusahaan yang menawarkan penyebaran yang dikelola Cassandra. Itu, seperti dijelaskan di atas, menggunakan wadah sespan yang menerima perintah melalui HTTP. Itu ditulis dalam Java, jadi kadang-kadang tidak memiliki fungsi perpustakaan client-go yang lebih maju. Selain itu, operator tidak mendukung Racks yang berbeda untuk satu Datacenter.
Tetapi operator memiliki keunggulan seperti dukungan pemantauan, manajemen klaster tingkat tinggi menggunakan CRD, dan bahkan dokumentasi untuk menghapus cadangan.
2. Navigator oleh Jetstack
- Github
- Kesediaan: Alpha
- Lisensi: Apache 2.0
- Diimplementasikan di: Golang
Pernyataan untuk menggunakan DB-as-a-Service. Saat ini mendukung dua database: Elasticsearch dan Cassandra. Ini memiliki solusi menarik seperti kontrol akses ke database melalui RBAC (untuk ini, apiserver navigator terpisah dimunculkan). Sebuah proyek yang menarik, yang layak untuk dilihat lebih dekat, tetapi komitmen terakhir dibuat satu setengah tahun yang lalu, yang jelas mengurangi potensinya.
3. Cassandra-operator dari vgkowski
- Github
- Kesediaan: Alpha
- Lisensi: Apache 2.0
- Diimplementasikan di: Golang
Mereka tidak menganggapnya “serius”, karena komit terakhir ke repositori adalah lebih dari setahun yang lalu. Pengembangan operator ditinggalkan: versi terbaru dari Kubernetes, dinyatakan sebagai didukung, adalah 1.9.
4. Cassandra-operator dari Rook
- Github
- Kesediaan: Alpha
- Lisensi: Apache 2.0
- Diimplementasikan di: Golang
Operator yang pengembangannya tidak berjalan secepat yang kita inginkan. Ini memiliki struktur CRD yang dipikirkan dengan matang untuk mengelola cluster, memecahkan masalah mengidentifikasi node menggunakan Layanan dengan ClusterIP ("hack" yang sama) ... tetapi untuk sekarang itu saja. Tidak ada pemantauan dan cadangan di luar kotak sekarang (ngomong-ngomong, kami
mulai memantau
diri kami
sendiri ). Hal yang menarik adalah bahwa dengan menggunakan operator ini Anda juga dapat menggunakan ScyllaDB.
NB: Kami menggunakan operator ini dengan modifikasi kecil di salah satu proyek kami. Tidak ada masalah dalam pekerjaan operator selama seluruh operasi (~ 4 bulan beroperasi).5. CassKop by Orange
- Github
- Kesediaan: Alpha
- Lisensi: Apache 2.0
- Diimplementasikan di: Golang
Operator termuda dalam daftar: komit pertama dibuat pada 23 Mei 2019. Sudah, di gudang senjatanya ada sejumlah besar fitur dari daftar kami, lebih detail yang dapat ditemukan di repositori proyek. Operator didasarkan pada operator populer-SDK. Mendukung pemantauan out-of-box. Perbedaan utama dari operator lain adalah penggunaan
plugin CassKop , diimplementasikan dalam Python dan digunakan untuk komunikasi antara node Cassandra.
Kesimpulan
Jumlah pendekatan dan opsi yang memungkinkan untuk memindahkan Cassandra ke Kubernetes berbicara untuk dirinya sendiri: topiknya sangat diminati.
Pada tahap ini, Anda dapat mencoba salah satu di atas dengan risiko dan risiko Anda sendiri: tidak ada pengembang yang menjamin 100% kinerja solusi mereka di lingkungan produksi. Namun sekarang, banyak produk yang tampak menjanjikan untuk mencoba menggunakannya di tribun pengembangan.
Saya pikir di masa depan wanita di kapal ini harus pergi!
PS
Baca juga di blog kami: