Topik ini menjelaskan kluster sharded MongoDB yang digunakan untuk menyimpan data dalam jumlah sangat besar.
Kapan harus menggunakan kluster sharded?
Gunakan kluster sharded untuk mengatasi permasalahan berikut:
Kapasitas penyimpanan dibatasi oleh satu host, sehingga menimbulkan bottleneck pada ruang disk.
Kinerja baca dan tulis dibatasi oleh satu host. Keterbatasan ini dapat disebabkan oleh bottleneck sumber daya pada CPU, memori, atau network interface controller (NIC), yang menghambat skalabilitas kinerja.
Bagaimana menentukan jumlah shard dan mongos?
Anda dapat menentukan jumlah node shard dan mongos sebagai berikut:
Kluster sharded hanya digunakan untuk menyimpan data dalam jumlah besar dengan volume akses rendah. Misalnya, jika satu shard dapat menyimpan data sebesar M dan total kapasitas penyimpanan yang dibutuhkan adalah N, Anda dapat menghitung jumlah shard dan node mongos yang diperlukan menggunakan rumus berikut:
numberOfShards = N/M/0,75 (mengasumsikan watermark kapasitas penyimpanan sebesar 75%)
numberOfMongos = 2+ (untuk kebutuhan akses rendah, deploy minimal dua node mongos untuk high availability)
Kluster sharded digunakan untuk menangani operasi baca atau tulis dengan konkurensi tinggi, tetapi volume data totalnya kecil. Node shard dan mongos harus memenuhi persyaratan kinerja baca dan tulis. Misalnya, jika QPS maksimum dari satu shard adalah M, QPS maksimum dari satu mongos adalah Ms, dan total QPS yang dibutuhkan adalah Q, Anda dapat menghitung jumlah shard dan node mongos yang diperlukan menggunakan rumus berikut:
numberOfShards = Q/M/0,75 (mengasumsikan watermark beban sebesar 75%)
numberOfMongos = Q/Ms/0,75
CatatanJika kluster sharded harus mengatasi kedua permasalahan tersebut, Anda dapat memperkirakan jumlah node berdasarkan kebutuhan yang lebih tinggi.
Rumus-rumus ini memberikan perkiraan dalam skenario ideal di mana data dan permintaan terdistribusi secara merata. Dalam praktiknya, distribusi mungkin tidak merata. Untuk menyeimbangkan beban sistem seoptimal mungkin, Anda harus memilih kunci shard yang sesuai.
Kemampuan layanan mongos dan mongod harus diukur berdasarkan pola akses spesifik Anda.
Pemilihan kunci shard
Strategi sharding yang didukung oleh kluster sharded MongoDB
Range sharding mendukung kueri rentang berdasarkan kunci shard.
Hash sharding mendistribusikan operasi tulis secara merata ke seluruh shard.
Tag aware sharding memungkinkan Anda menyesuaikan aturan distribusi chunk.
CatatanCara kerjanya
Gunakan
sh.addShardTag()untuk menetapkan Tag A pada sebuah shard.Gunakan
sh.addTagRange()untuk menetapkan Tag A pada rentang chunk suatu koleksi. MongoDB kemudian memastikan bahwa rentang chunk dengan Tag A, atau superset dari rentang tersebut, didistribusikan ke shard yang memiliki Tag A.
Skenario
Anda dapat menetapkan tag data center pada shard yang dideploy di data center berbeda. Hal ini mendistribusikan data dari rentang chunk berbeda ke data center yang ditentukan.
Anda dapat menetapkan tag tingkat layanan pada shard dengan kemampuan layanan berbeda. Hal ini mendistribusikan lebih banyak chunk ke shard dengan kemampuan lebih tinggi.
Catatan
ApsaraDB for MongoDB tidak dapat langsung mendistribusikan chunk ke node shard yang diberi label tag tertentu. Chunk didistribusikan secara bertahap seiring pemisahan dan migrasi chunk yang sering dipicu oleh operasi insert dan update. Pastikan balancer diaktifkan selama proses distribusi. Setelah tag ditambahkan ke rentang chunk, data yang ditulis mungkin tidak didistribusikan ke node shard yang memiliki tag yang sama dengan rentang chunk tersebut.
Permasalahan yang tidak dapat diselesaikan oleh range dan hash sharding
Rentang nilai kunci shard terlalu kecil. Misalnya, jika Anda menggunakan data center sebagai kunci shard, sharding tidak efektif karena biasanya hanya ada sedikit data center.
Nilai kunci shard tertentu muncul di terlalu banyak dokumen. Hal ini dapat menyebabkan satu chunk berukuran sangat besar, yang dikenal sebagai jumbo chunk, sehingga memengaruhi migrasi chunk dan load balancing.
Kueri dan pembaruan berdasarkan bidang non-kunci shard menjadi kueri scatter-gather, yang tidak efisien.
Karakteristik kunci shard yang baik
Kardinalitas yang cukup
Distribusi operasi tulis yang merata
Menghindari kueri scatter-gather (baca terarah).
Contoh:
Aplikasi IoT menggunakan instans kluster sharded untuk menyimpan log dari jutaan perangkat. Setiap perangkat mengirim log ke instans kluster sharded setiap 10 detik. Log tersebut berisi informasi seperti ID perangkat dan timestamp. Log yang dihasilkan oleh perangkat tertentu dalam rentang waktu tertentu sering dikueri.
Permintaan kueri: Mengambil log untuk perangkat tertentu dalam rentang waktu tertentu.
(Direkomendasikan) Metode 1: Gunakan kunci shard gabungan berupa ID perangkat dan timestamp dengan range sharding.
Operasi tulis didistribusikan secara merata ke beberapa shard.
Data untuk ID perangkat yang sama selanjutnya didistribusikan ke beberapa chunk berdasarkan timestamp.
Kueri untuk rentang waktu berdasarkan ID perangkat dapat diselesaikan langsung menggunakan indeks gabungan (deviceId, timestamp).
Metode 2: Gunakan timestamp sebagai kunci shard dengan range sharding.
Tulisan baru memiliki timestamp berurutan dan semuanya dikirim ke shard yang sama, menyebabkan distribusi tulis tidak merata.
Kueri berdasarkan ID perangkat tersebar ke semua shard, sehingga tidak efisien.
Metode 3: Gunakan timestamp sebagai kunci shard dengan hash sharding.
Operasi tulis didistribusikan secara merata ke beberapa shard.
Kueri berdasarkan ID perangkat tersebar ke semua shard, sehingga tidak efisien.
Metode 4: Gunakan ID perangkat sebagai kunci shard dengan hash sharding.
CatatanJika ID perangkat tidak memiliki pola yang jelas, Anda dapat menggunakan range sharding.
Operasi tulis didistribusikan secara merata ke beberapa shard.
Data untuk ID perangkat yang sama tidak dapat dibagi lagi dan hanya didistribusikan ke satu chunk. Hal ini menyebabkan jumbo chunk. Kueri berdasarkan ID perangkat dikirim ke satu shard. Setelah permintaan diarahkan ke shard tersebut, kueri rentang berdasarkan timestamp memerlukan pemindaian tabel penuh dan pengurutan.
Jumbo chunk dan ukuran per chunk
Ukuran default per chunk dalam instans kluster sharded adalah 64 MB. Jika ukuran chunk melebihi 64 MB dan chunk tersebut tidak dapat dipisah, chunk tersebut diberi label sebagai jumbo chunk. Misalnya, jika semua dokumen memiliki nilai kunci shard yang sama, dokumen-dokumen tersebut disimpan dalam chunk yang sama dan tidak dapat dipisah. Balancer tidak dapat memigrasi jumbo chunk, yang dapat menyebabkan ketidakseimbangan beban. Kami merekomendasikan agar Anda mencegah terbentuknya jumbo chunk.
Jika jumbo chunk muncul dan Anda tidak memiliki persyaratan tinggi terhadap load balancing, hal ini tidak akan memengaruhi operasi baca dan tulis data. Anda dapat menggunakan salah satu metode berikut untuk menanganinya:
Anda dapat memisahkan jumbo chunk tersebut. Setelah pemisahan berhasil, mongos secara otomatis menghapus flag jumbo.
Untuk chunk yang tidak dapat dipisah, jika chunk tersebut tidak lagi termasuk jumbo chunk, Anda dapat mencoba menghapus flag jumbo secara manual.
CatatanSebelum melakukan purge, Anda harus melakukan backup database `config` untuk mencegah kerusakan akibat kesalahan operasional.
Anda dapat menambah ukuran chunk. Ketika ukuran chunk tidak lagi lebih kecil dari ukuran chunk yang dikonfigurasi, flag jumbo pada akhirnya akan dihapus. Namun, jumbo chunk masih dapat muncul seiring penulisan data. Solusi mendasar adalah merencanakan kunci shard dengan tepat.
Skema penggunaan untuk menyesuaikan ukuran chunk (rentang nilai: 1 hingga 1.024 MB):
Jika beban I/O terlalu tinggi selama migrasi, Anda dapat mencoba menetapkan ukuran chunk yang lebih kecil.
Saat pengujian, Anda dapat menetapkan ukuran chunk yang lebih kecil agar hasilnya lebih mudah diverifikasi.
Jika pengaturan ukuran chunk awal tidak optimal dan menghasilkan banyak jumbo chunk yang mengganggu load balancing, Anda dapat mencoba menambah ukuran chunk tersebut.
Saat mengonversi koleksi tanpa sharding menjadi koleksi dengan sharding, Anda mungkin perlu menambah ukuran chunk jika koleksi tersebut sangat besar—terutama pada volume data dalam skala terabyte—agar konversi berhasil. Untuk informasi lebih lanjut, lihat Sharding Existing Collection Data Size.
Tentang load balancing
Load balancing otomatis dalam instans kluster sharded diimplementasikan oleh thread latar belakang yang berjalan pada node mongos instans tersebut. Hanya satu tugas migrasi yang dapat dijalankan untuk setiap koleksi pada waktu tertentu. Load balancing dipicu berdasarkan jumlah chunk per koleksi pada setiap node shard. Jika selisih antara jumlah chunk suatu koleksi pada sebuah node shard dan jumlah total chunk koleksi tersebut mencapai ambang batas yang ditentukan, ApsaraDB for MongoDB akan mulai memigrasikan chunk koleksi tersebut dari node shard ke node shard lainnya. Anda harus menentukan ambang batas berdasarkan jumlah total chunk.
Load balancing diaktifkan secara default. Untuk mencegah migrasi chunk memengaruhi layanan online, Anda dapat menetapkan jendela migrasi. Misalnya, Anda dapat mengizinkan migrasi hanya antara pukul 02.00 hingga 06.00.
use config
db.settings.update(
{ _id: "balancer" },
{ $set: { activeWindow : { start : "02:00", stop : "06:00" } } },
{ upsert: true }
)
Saat Anda melakukan backup kluster sharded, baik melalui mongos maupun dengan melakukan backup Configserver dan semua shard secara terpisah, Anda harus menjalankan perintah berikut untuk menghentikan balancer. Hal ini mencegah ketidakkonsistenan status pada data backup.
sh.stopBalancer() Pengaturan arsip dalam perintah moveChunk
Jika instans kluster sharded menjalankan MongoDB 3.0 atau versi sebelumnya, penggunaan disk space dalam katalog data dapat terus meningkat meskipun penulisan data telah dihentikan.
Permasalahan ini disebabkan oleh item konfigurasi sharding.archiveMovedChunks, yang secara default bernilai true pada MongoDB 3.0 dan versi sebelumnya. Pengaturan ini berarti bahwa selama operasi moveChunk, shard sumber mengarsipkan data chunk yang dimigrasikan untuk tujuan pemulihan. Akibatnya, saat chunk dimigrasikan, disk space pada node sumber tidak dilepaskan, sedangkan node tujuan menggunakan disk space baru.
Pada MongoDB 3.2, nilai default untuk item konfigurasi ini adalah false. Secara default, data dari operasi moveChunk tidak diarsipkan pada shard sumber.