Dokumen ini membandingkan konsep dan praktik Apache Cassandra dan Spanner. Panduan ini mengasumsikan bahwa Anda sudah terbiasa dengan Cassandra dan ingin memigrasikan aplikasi yang ada atau mendesain aplikasi baru saat menggunakan Spanner sebagai database.
Cassandra dan Spanner adalah database terdistribusi berskala besar yang dibuat untuk aplikasi yang memerlukan skalabilitas tinggi dan latensi rendah. Meskipun kedua database ini dapat mendukung beban kerja NoSQL yang berat, Spanner menyediakan fitur lanjutan untuk pemodelan data, kueri, dan operasi transaksional. Untuk informasi selengkapnya tentang cara Spanner memenuhi kriteria database NoSQL, lihat Spanner untuk workload non-relasional.
Bermigrasi dari Cassandra ke Spanner
Untuk bermigrasi dari Cassandra ke Spanner, Anda dapat menggunakan Adaptor Proxy Cassandra ke Spanner. Alat open source ini memungkinkan Anda memigrasikan beban kerja dari Cassandra ke Spanner tanpa perubahan pada logika aplikasi Anda.
Konsep inti
Bagian ini membandingkan konsep utama Cassandra dan Spanner.
Terminologi
Cassandra | Spanner |
---|---|
Cluster |
Instance Cluster Cassandra setara dengan instance Spanner - kumpulan server dan resource penyimpanan. Karena Spanner adalah layanan terkelola, Anda tidak perlu mengonfigurasi hardware atau software yang mendasarinya. Anda hanya perlu menentukan jumlah node yang ingin dicadangkan untuk instance atau memilih penskalaan otomatis untuk menskalakan instance secara otomatis. Instance bertindak seperti penampung untuk database, dan topologi replikasi data (regional, region ganda, atau multi-region) dipilih di tingkat instance. |
Keyspace |
Database Keyspace Cassandra setara dengan database Spanner, yang merupakan kumpulan tabel dan elemen skema lainnya (misalnya, indeks dan peran). Tidak seperti ruang kunci, Anda tidak perlu mengonfigurasi faktor replikasi. Spanner secara otomatis mereplikasi data Anda ke region yang ditetapkan di instance Anda. |
Tabel |
Tabel Di Cassandra dan Spanner, tabel adalah kumpulan baris yang diidentifikasi oleh kunci utama yang ditentukan dalam skema tabel. |
Partisi |
Pisahkan Cassandra dan Spanner diskalakan dengan melakukan sharding data. Di Cassandra, setiap shard disebut partisi, sedangkan di Spanner, setiap shard disebut bagian. Cassandra menggunakan partisi hash, yang berarti setiap baris ditetapkan secara independen ke node penyimpanan berdasarkan hash kunci utama. Spanner memiliki shard rentang, yang berarti baris yang berdekatan di ruang kunci utama juga berdekatan dalam penyimpanan (kecuali di batas pemisahan). Spanner menangani pemisahan dan penggabungan berdasarkan beban dan penyimpanan, dan ini bersifat transparan untuk aplikasi. Implikasi utama adalah bahwa tidak seperti Cassandra, pemindaian rentang pada awalan kunci utama adalah operasi yang efisien di Spanner. |
Baris |
Baris Di Cassandra dan Spanner, baris adalah kumpulan kolom yang diidentifikasi secara unik oleh kunci utama. Seperti Cassandra, Spanner mendukung kunci utama gabungan. Tidak seperti Cassandra, Spanner tidak membedakan antara kunci partisi dan kunci pengurutan, karena data di-shard rentang. Anda dapat menganggap Spanner hanya memiliki kunci pengurutan, dengan partisi yang dikelola di balik layar. |
Kolom |
Kolom Di Cassandra dan Spanner, kolom adalah kumpulan nilai data yang memiliki jenis yang sama. Ada satu nilai untuk setiap baris tabel. Untuk mengetahui informasi selengkapnya tentang cara membandingkan jenis kolom Cassandra dengan Spanner, lihat Jenis Data. |
Arsitektur
Cluster Cassandra terdiri dari sekumpulan server dan penyimpanan yang ditempatkan bersama dengan server tersebut. Fungsi hash memetakan baris dari ruang kunci partisi ke node virtual (vnode). Kumpulan vnode kemudian ditetapkan secara acak ke setiap server untuk menayangkan sebagian ruang kunci cluster. Penyimpanan untuk vnode terpasang secara lokal ke node penayangan. Driver klien terhubung langsung ke node penayangan dan menangani load balancing serta perutean kueri.
Instance Spanner terdiri dari kumpulan server dalam topologi replikasi. Spanner secara dinamis melakukan sharding setiap tabel ke dalam rentang baris berdasarkan penggunaan CPU dan disk. Shard ditetapkan ke node komputasi untuk ditayangkan. Data disimpan secara fisik di Colossus, sistem file terdistribusi Google, terpisah dari node komputasi. Driver klien terhubung ke server frontend Spanner yang melakukan pemilihan rute permintaan dan load balancing. Untuk mempelajari lebih lanjut, lihat laporan resmi Proses Operasi Baca & Tulis Spanner.
Pada tingkat tinggi, kedua arsitektur diskalakan saat resource ditambahkan ke cluster yang mendasarinya. Pemisahan komputasi dan penyimpanan Spanner memungkinkan beban di antara node komputasi diimbangi dengan lebih cepat sebagai respons terhadap perubahan beban kerja. Tidak seperti Cassandra, pemindahan shard tidak melibatkan pemindahan data karena data tetap berada di Colossus. Selain itu, partisi berbasis rentang Spanner mungkin lebih alami untuk aplikasi yang mengharapkan data diurutkan berdasarkan kunci partisi. Sisi lain dari partisi berbasis rentang adalah beban kerja yang menulis ke salah satu ujung ruang kunci (misalnya, tabel yang diberi kunci berdasarkan stempel waktu saat ini) mungkin mengalami hotspotting tanpa pertimbangan desain skema tambahan. Untuk mengetahui informasi selengkapnya tentang teknik untuk mengatasi hotspot, lihat Praktik terbaik desain skema.
Konsistensi
Dengan Cassandra, Anda harus menentukan tingkat konsistensi untuk setiap operasi. Jika Anda menggunakan tingkat konsistensi kuorum, mayoritas node replika harus merespons node koordinator agar operasi dianggap berhasil. Jika Anda menggunakan level konsistensi satu, Cassandra memerlukan satu node replika untuk merespons agar operasi dianggap berhasil.
Spanner memberikan konsistensi yang kuat. Spanner API tidak mengekspos replika ke klien. Klien Spanner berinteraksi dengan Spanner seolah-olah itu adalah satu database mesin. Operasi tulis selalu ditulis ke sebagian besar replika sebelum dikonfirmasi kepada pengguna. Setiap operasi baca berikutnya akan mencerminkan data yang baru ditulis. Aplikasi dapat memilih untuk membaca snapshot database pada satu waktu di masa lalu, yang mungkin memiliki manfaat performa dibandingkan dengan pembacaan yang kuat. Untuk mengetahui informasi selengkapnya tentang properti konsistensi Spanner, lihat Ringkasan transaksi.
Spanner dibuat untuk mendukung konsistensi dan ketersediaan yang diperlukan dalam aplikasi skala besar. Spanner memberikan konsistensi yang kuat dalam skala besar dan dengan performa tinggi. Untuk kasus penggunaan yang memerlukannya, Spanner mendukung pembacaan snapshot yang melonggarkan persyaratan keaktualan.
Pemodelan data
Bagian ini membandingkan model data Cassandra dan Spanner.
Deklarasi tabel
Sintaksis deklarasi tabel cukup mirip di Cassandra dan Spanner. Anda menentukan nama tabel, nama dan jenis kolom, serta kunci utama yang secara unik mengidentifikasi baris. Perbedaan utamanya adalah Cassandra dipartisi hash dan membuat perbedaan antara kunci partisi dan kunci pengurutan, sedangkan Spanner dipartisi rentang. Spanner dapat dianggap hanya memiliki kunci pengurutan, dengan partisi yang otomatis dikelola di balik layar. Seperti Cassandra, Spanner mendukung kunci utama gabungan.
Satu bagian kunci utama
Perbedaan antara Cassandra dan Spanner terletak pada nama jenis dan lokasi klausa kunci utama.
Cassandra | Spanner |
---|---|
CREATE TABLE users ( user_id bigint, first_name text, last_name text, PRIMARY KEY (user_id) ) |
CREATE TABLE users ( user_id int64, first_name string(max), last_name string(max), ) PRIMARY KEY (user_id) |
Beberapa bagian kunci utama
Untuk Cassandra, bagian kunci utama pertama adalah "kunci partisi" dan bagian kunci utama berikutnya adalah "kunci pengurutan". Untuk Spanner, tidak ada kunci partisi terpisah. Data disimpan dan diurutkan berdasarkan seluruh kunci utama komposit.
Cassandra | Spanner |
---|---|
CREATE TABLE user_items ( user_id bigint, item_id bigint, first_name text, last_name text, PRIMARY KEY (user_id, item_id) ) |
CREATE TABLE user_items ( user_id int64, item_id int64, first_name string(max), last_name string(max), ) PRIMARY KEY (user_id, item_id) |
Kunci partisi gabungan
Untuk Cassandra, kunci partisi dapat berupa gabungan. Tidak ada kunci partisi terpisah di Spanner. Data disimpan dan diurutkan berdasarkan seluruh kunci utama komposit.
Cassandra | Spanner |
---|---|
CREATE TABLE user_category_items ( user_id bigint, category_id bigint, item_id bigint, first_name text, last_name text, PRIMARY KEY ((user_id, category_id), item_id) ) |
CREATE TABLE user_category_items ( user_id int64, category_id int64, item_id int64, first_name string(max), last_name string(max), ) PRIMARY KEY (user_id, category_id, item_id) |
Jenis data
Bagian ini membandingkan jenis data Cassandra dan Spanner. Untuk mengetahui informasi selengkapnya tentang jenis Spanner, lihat Jenis data di GoogleSQL.
Cassandra | Spanner | |
---|---|---|
Jenis Numerik |
Bilangan bulat standar:bigint (bilangan bulat 64-bit yang telah ditandai)int (bilangan bulat 32-bit yang telah ditandai)smallint (bilangan bulat 16-bit yang telah ditandai)tinyint (bilangan bulat 8-bit yang telah ditandai)
|
int64 (Bilangan bulat 64-bit yang telah ditandai)Spanner mendukung satu jenis data lebar 64-bit untuk bilangan bulat yang telah ditandai. |
Floating point standar:double (floating point IEEE-754 64-bit)float (floating point IEEE-754 32-bit) |
float64 (floating point IEEE-754 64-bit)float32 (floating point IEEE-754 32-bit)
|
|
Angka presisi variabel:varint (bilangan bulat presisi variabel)decimal (desimal presisi variabel)
|
Untuk angka desimal presisi tetap, gunakan numeric (presisi 38 skala 9).
Jika tidak, gunakan string bersama dengan library bilangan bulat presisi variabel lapisan aplikasi.
|
|
Jenis String |
text varchar
|
string(max) text dan varchar menyimpan serta memvalidasi string UTF-8. Di Spanner, kolom string harus menentukan panjang maksimumnya (tidak ada dampak pada penyimpanan; ini untuk tujuan validasi).
|
blob |
bytes(max) Untuk menyimpan data biner, gunakan jenis data bytes .
|
|
Jenis Tanggal dan Waktu | date |
date |
duration |
int64 Spanner tidak mendukung jenis data durasi khusus. Gunakan int64 untuk menyimpan
durasi nanodetik.
|
|
time |
int64 Spanner tidak mendukung jenis data waktu dalam hari khusus. Gunakan int64 untuk
menyimpan offset nanosekon dalam sehari.
|
|
timestamp |
timestamp |
|
Jenis Penampung | Jenis yang ditentukan pengguna | json atau proto |
list |
array Gunakan array untuk menyimpan daftar objek yang diketik.
|
|
map |
json atau proto Spanner tidak mendukung jenis peta khusus. Gunakan kolom json atau proto untuk mewakili peta. Untuk informasi selengkapnya, lihat Menyimpan peta besar sebagai tabel yang diselingi.
|
|
set |
array Spanner tidak mendukung jenis set khusus. Gunakan kolom array untuk mewakili
set , dengan aplikasi yang mengelola keunikan yang ditetapkan. Untuk mengetahui informasi selengkapnya, lihat Menyimpan peta besar sebagai tabel yang diselingi, yang juga dapat digunakan untuk menyimpan set besar.
|
Pola penggunaan dasar
Contoh kode berikut menunjukkan perbedaan antara kode klien Cassandra dan Spanner di Go. Untuk informasi selengkapnya, lihat Library klien Spanner.
Inisialisasi klien
Di klien Cassandra, Anda membuat objek cluster yang mewakili cluster Cassandra yang mendasarinya, membuat instance objek sesi yang memisahkan koneksi ke cluster, dan mengeluarkan kueri pada sesi. Di Spanner, Anda membuat objek klien yang terikat ke database tertentu, dan mengeluarkan permintaan database pada objek klien.
Contoh Cassandra
Go
import "github.com/gocql/gocql" ... cluster := gocql.NewCluster("<address>") cluster.Keyspace = "<keyspace>" session, err := cluster.CreateSession() if err != nil { return err } defer session.Close() // session.Query(...)
Contoh Spanner
Go
import "cloud.google.com/go/spanner" ... client, err := spanner.NewClient(ctx, fmt.Sprintf("projects/%s/instances/%s/databases/%s", project, instance, database)) defer client.Close() // client.Apply(...)
Membaca data
Operasi baca di Spanner dapat dilakukan melalui API gaya nilai kunci dan API kueri. Sebagai pengguna Cassandra, Anda mungkin merasa lebih akrab dengan API kueri. Perbedaan
utama dalam API kueri adalah Spanner memerlukan
argumen bernama (tidak seperti argumen posisional ?
di Cassandra). Nama argumen dalam kueri Spanner harus diawali dengan @
.
Contoh Cassandra
Go
stmt := `SELECT user_id, first_name, last_name FROM users WHERE user_id = ?` var ( userID int firstName string lastName string ) err := session.Query(stmt, 1).Scan(&userID, &firstName, &lastName)
Contoh Spanner
Go
stmt := spanner.Statement{ SQL: `SELECT user_id, first_name, last_name FROM users WHERE user_id = @user_id`, Params: map[string]any{"user_id": 1}, } var ( userID int64 firstName string lastName string ) err := client.Single().Query(ctx, stmt).Do(func(row *spanner.Row) error { return row.Columns(&userID, &firstName, &lastName) })
Masukkan data
INSERT
Cassandra setara dengan INSERT OR UPDATE
Spanner.
Anda harus menentukan kunci utama lengkap untuk penyisipan. Spanner mendukung DML dan API mutasi gaya nilai kunci. API mutasi gaya nilai kunci
direkomendasikan untuk penulisan yang tidak penting karena latensi yang lebih rendah.
Spanner DML API memiliki lebih banyak fitur karena mendukung platform SQL lengkap (termasuk
penggunaan ekspresi dalam pernyataan DML).
Contoh Cassandra
Go
stmt := `INSERT INTO users (user_id, first_name, last_name) VALUES (?, ?, ?)` err := session.Query(stmt, 1, "John", "Doe").Exec()
Contoh Spanner
Go
_, err := client.Apply(ctx, []*spanner.Mutation{ spanner.InsertOrUpdateMap( "users", map[string]any{ "user_id": 1, "first_name": "John", "last_name": "Doe", } )})
Menyisipkan data secara batch
Di Cassandra, Anda dapat menyisipkan beberapa baris menggunakan pernyataan batch. Di Spanner, operasi commit dapat berisi beberapa mutasi. Spanner menyisipkan mutasi ini ke database secara atomik.
Contoh Cassandra
Go
stmt := `INSERT INTO users (user_id, first_name, last_name) VALUES (?, ?, ?)` b := session.NewBatch(gocql.UnloggedBatch) b.Entries = []gocql.BatchEntry{ {Stmt: stmt, Args: []any{1, "John", "Doe"}}, {Stmt: stmt, Args: []any{2, "Mary", "Poppins"}}, } err = session.ExecuteBatch(b)
Contoh Spanner
Go
_, err := client.Apply(ctx, []*spanner.Mutation{ spanner.InsertOrUpdateMap( "users", map[string]any{ "user_id": 1, "first_name": "John", "last_name": "Doe" }, ), spanner.InsertOrUpdateMap( "users", map[string]any{ "user_id": 2, "first_name": "Mary", "last_name": "Poppins", }, ), })
Menghapus data
Penghapusan Cassandra memerlukan penentuan kunci utama baris yang akan dihapus.
Hal ini mirip dengan mutasi DELETE
di Spanner.
Contoh Cassandra
Go
stmt := `DELETE FROM users WHERE user_id = ?` err := session.Query(stmt, 1).Exec()
Contoh Spanner
Go
_, err := client.Apply(ctx, []*spanner.Mutation{ spanner.Delete("users", spanner.Key{1}), })
Topik lanjutan
Bagian ini berisi informasi tentang cara menggunakan fitur Cassandra yang lebih canggih di Spanner.
Menulis stempel waktu
Cassandra memungkinkan mutasi menentukan stempel waktu tulis secara eksplisit untuk
sel tertentu menggunakan klausa USING TIMESTAMP
. Biasanya, fitur ini
digunakan untuk memanipulasi semantik last-writer-wins Cassandra.
Spanner tidak mengizinkan klien menentukan stempel waktu setiap
penulisan. Setiap sel ditandai secara internal dengan stempel waktu TrueTime pada saat nilai sel di-commit. Karena Spanner menyediakan antarmuka yang sangat konsisten dan dapat diserialisasi secara ketat, sebagian besar aplikasi tidak memerlukan fungsi USING TIMESTAMP
.
Jika Anda mengandalkan USING TIMESTAMP
Cassandra untuk logika khusus aplikasi, Anda dapat menambahkan
kolom TIMESTAMP
tambahan ke skema Spanner, yang dapat melacak waktu perubahan di
tingkat aplikasi. Pembaruan pada baris kemudian dapat digabungkan dalam transaksi
baca-tulis. Contoh:
Contoh Cassandra
Go
stmt := `INSERT INTO users (user_id, first_name, last_name) VALUES (?, ?, ?) USING TIMESTAMP ?` err := session.Query(stmt, 1, "John", "Doe", ts).Exec()
Contoh Spanner
Buat skema dengan kolom stempel waktu pembaruan eksplisit.
GoogleSQL
CREATE TABLE users ( user_id INT64, first_name STRING(MAX), last_name STRING(MAX), update_ts TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true), ) PRIMARY KEY (user_id)
Sesuaikan logika untuk memperbarui baris dan menyertakan stempel waktu.
Go
func ShouldUpdateRow(ctx context.Context, txn *spanner.ReadWriteTransaction, updateTs time.Time) (bool, error) { // Read the existing commit timestamp. row, err := txn.ReadRow(ctx, "users", spanner.Key{1}, []string{"update_ts"}) // Treat non-existent row as NULL timestamp - the row should be updated. if spanner.ErrCode(err) == codes.NotFound { return true, nil } // Propagate unexpected errors. if err != nil { return false, err } // Check if the committed timestamp is newer than the update timestamp. var committedTs *time.Time err = row.Columns(&committedTs) if err != nil { return false, err } if committedTs != nil && committedTs.Before(updateTs) { return false, nil } // Committed timestamp is older than update timestamp - the row should be updated. return true, nil }
Periksa kondisi kustom sebelum memperbarui baris.
Go
_, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error { // Check if the row should be updated. ok, err := ShouldUpdateRow(ctx, txn, time.Now()) if err != nil { return err } if !ok { return nil } // Update the row. txn.BufferWrite([]*spanner.Mutation{ spanner.InsertOrUpdateMap("users", map[string]any{ "user_id": 1, "first_name": "John", "last_name": "Doe", "update_ts": spanner.CommitTimestamp, })}) return nil })
Mutasi bersyarat
Pernyataan INSERT ... IF EXISTS
di Cassandra setara dengan pernyataan INSERT
di Spanner. Dalam kedua kasus tersebut, penyisipan akan gagal jika baris
sudah ada.
Di Cassandra, Anda juga dapat membuat pernyataan DML yang menentukan kondisi, dan
pernyataan akan gagal jika kondisi bernilai salah. Di
Spanner, Anda dapat menggunakan mutasi UPDATE
kondisional dalam transaksi baca-tulis. Misalnya, untuk memperbarui baris hanya jika
kondisi tertentu ada:
Contoh Cassandra
Go
stmt := `UPDATE users SET last_name = ? WHERE user_id = ? IF first_name = ?` err := session.Query(stmt, 1, "Smith", "John").Exec()
Contoh Spanner
Sesuaikan logika untuk memperbarui baris dan menyertakan kondisi.
Go
func ShouldUpdateRow(ctx context.Context, txn *spanner.ReadWriteTransaction) (bool, error) { row, err := txn.ReadRow(ctx, "users", spanner.Key{1}, []string{"first_name"}) if err != nil { return false, err } var firstName *string err = row.Columns(&firstName) if err != nil { return false, err } if firstName != nil && firstName == "John" { return false, nil } return true, nil }
Periksa kondisi kustom sebelum memperbarui baris.
Go
_, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error { ok, err := ShouldUpdateRow(ctx, txn, time.Now()) if err != nil { return err } if !ok { return nil } txn.BufferWrite([]*spanner.Mutation{ spanner.InsertOrUpdateMap("users", map[string]any{ "user_id": 1, "last_name": "Smith", "update_ts": spanner.CommitTimestamp, })}) return nil })
TTL
Cassandra mendukung penetapan nilai time to live (TTL) di tingkat baris atau kolom. Di Spanner, TTL dikonfigurasi di tingkat baris, dan Anda menetapkan kolom bernama sebagai waktu habis masa berlaku untuk baris. Untuk mengetahui informasi selengkapnya, lihat Ringkasan waktu tunggu (TTL).
Contoh Cassandra
Go
stmt := `INSERT INTO users (user_id, first_name, last_name) VALUES (?, ?, ?) USING TTL 86400 ?` err := session.Query(stmt, 1, "John", "Doe", ts).Exec()
Contoh Spanner
Membuat skema dengan kolom stempel waktu pembaruan eksplisit
GoogleSQL
CREATE TABLE users ( user_id INT64, first_name STRING(MAX), last_name STRING(MAX), update_ts TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true), ) PRIMARY KEY (user_id), ROW DELETION POLICY (OLDER_THAN(update_ts, INTERVAL 1 DAY));
Sisipkan baris dengan stempel waktu commit.
Go
_, err := client.Apply(ctx, []*spanner.Mutation{ spanner.InsertOrUpdateMap("users", map[string]any{ "user_id": 1, "first_name": "John", "last_name": "Doe", "update_ts": spanner.CommitTimestamp}), })
Menyimpan peta besar sebagai tabel sisipan.
Cassandra mendukung jenis map
untuk menyimpan key-value pair yang diurutkan. Untuk menyimpan
jenis map
yang berisi data dalam jumlah kecil di Spanner, Anda
dapat menggunakan jenis JSON
atau PROTO
, yang memungkinkan Anda menyimpan data semi-terstruktur dan terstruktur.
Pembaruan pada kolom tersebut mengharuskan seluruh nilai kolom ditulis ulang. Jika Anda
memiliki kasus penggunaan dengan data dalam jumlah besar yang disimpan di map
Cassandra, dan
hanya sebagian kecil map
yang perlu diperbarui, menggunakan
tabel INTERLEAVED
mungkin cocok. Misalnya, untuk mengaitkan data nilai kunci dalam jumlah besar dengan pengguna tertentu:
Contoh Cassandra
CREATE TABLE users (
user_id bigint,
attachments map<string, string>,
PRIMARY KEY (user_id)
)
Contoh Spanner
CREATE TABLE users (
user_id INT64,
) PRIMARY KEY (user_id);
CREATE TABLE user_attachments (
user_id INT64,
attachment_key STRING(MAX),
attachment_val STRING(MAX),
) PRIMARY KEY (user_id, attachment_key);
Dalam hal ini, baris lampiran pengguna disimpan bersama dengan baris pengguna yang sesuai, dan dapat diambil serta diperbarui secara efisien bersama dengan baris pengguna. Anda dapat menggunakan API baca-tulis di Spanner untuk berinteraksi dengan tabel yang diselingi. Untuk mengetahui informasi selengkapnya tentang interleaving, lihat Membuat tabel induk dan turunan.
Pengalaman developer
Bagian ini membandingkan alat developer Spanner dan Cassandra.
Pengembangan lokal
Anda dapat menjalankan Cassandra secara lokal untuk pengembangan dan pengujian unit. Spanner menyediakan lingkungan yang serupa untuk pengembangan lokal melalui emulator Spanner. Emulator menyediakan lingkungan fidelitas tinggi untuk pengembangan interaktif dan pengujian unit. Untuk mengetahui informasi selengkapnya, lihat Mengemulasi Spanner secara lokal.
Command line
Spanner yang setara dengan nodetool
Cassandra adalah Google Cloud CLI. Anda dapat melakukan operasi bidang kontrol dan
bidang data menggunakan gcloud spanner
. Untuk mengetahui informasi selengkapnya, lihat
panduan referensi Spanner Google Cloud CLI.
Jika memerlukan antarmuka REPL untuk mengeluarkan kueri ke Spanner
yang mirip dengan cqlsh
, Anda dapat menggunakan alat spanner-cli
. Untuk menginstal dan menjalankan
spanner-cli
di Go:
go install github.com/cloudspannerecosystem/spanner-cli@latest
$(go env GOPATH)/bin/spanner-cli
Untuk mengetahui informasi selengkapnya, lihat repositori GitHub spanner-cli.