Kami memiliki basis data tingkat perusahaan berskala sangat besar. Sebagai bagian dari model bisnis kami, semua pengguna web menekan server web kami pada waktu yang sama setiap bulan yang pada gilirannya memalu kotak sql kami. Lalu lintas sangat padat dan terus bertambah semakin besar semakin besar perusahaan tumbuh. sql optimasi proc telah dilakukan dan perangkat keras telah ditingkatkan ke tingkat yang sangat tinggi.
Kami sedang mencari basis data sekarang untuk memastikan bahwa kami dapat menangani pertumbuhan perusahaan dan beban masa depan.
Kami telah memutuskan data apa yang harus dibagikan. Ini adalah bagian dari database kami yang sangat dimanfaatkan.
Namun, pertanyaan saya adalah mengenai data non-sharded yang umum / universal. Contoh data seperti ini dapat berupa tabel Persediaan misalnya atau mungkin tabel Karyawan, tabel pengguna dll.
Saya melihat dua opsi untuk menangani data umum / universal ini:
1) desain 1 - Tempatkan data umum / universal dalam basis data eksternal. Semua tulisan akan muncul di sini. Data ini kemudian akan direplikasi ke setiap beling yang memungkinkan setiap beling untuk membaca data ini dan bergabung dengan data ini dalam procs t-sql.
2) desain 2 - Berikan masing-masing pecahan salinannya sendiri dari semua data umum / universal. Biarkan setiap beling menulis secara lokal ke tabel ini dan menggunakan replikasi gabungan sql untuk memperbarui / menyinkronkan data ini pada semua pecahan lainnya.
kekhawatiran tentang desain # 1
1) Masalah transaksional: Jika Anda memiliki situasi di mana Anda harus menulis atau memperbarui data dalam beling dan kemudian menulis / memperbarui tabel umum / universal dalam 1 proc yang disimpan misalnya, Anda tidak akan lagi dapat melakukan ini dengan mudah. Data sekarang ada pada instans dan database sql terpisah. Anda mungkin perlu melibatkan MS DTS untuk melihat apakah Anda dapat membungkus tulisan-tulisan ini menjadi sebuah transaksi karena mereka berada dalam database yang terpisah. Kinerja menjadi perhatian di sini dan kemungkinan penulisan ulang mungkin dilibatkan untuk procs yang menulis ke data yang terbuang dan umum.
2) hilangnya integritas referensial. Tidak mungkin untuk melakukan integritas referensial pangkalan data.
3) Pengodean ulang area besar dari sistem sehingga ia tahu untuk menulis data umum ke database universal baru tetapi membaca data umum dari pecahan.
4). peningkatan perjalanan basis data. Seperti # 1 di atas, ketika Anda mengalami situasi di mana Anda harus memperbarui data yang terbengkalai dan data umum, Anda akan melakukan beberapa perjalanan bolak-balik untuk mencapai hal ini karena data sekarang dalam database terpisah. Beberapa latensi jaringan di sini tetapi saya tidak khawatir tentang masalah ini sebanyak 3 di atas.
kekhawatiran tentang desain # 2
Dalam desain # 2 setiap pecahan mendapatkan instance sendiri dari semua data umum / universal. Ini berarti bahwa semua kode yang bergabung atau memperbarui data umum terus bekerja / berjalan seperti sekarang. Sangat sedikit pengodean ulang / penulisan ulang yang diperlukan dari tim pengembangan. Namun, desain ini sepenuhnya bergantung pada replikasi gabungan untuk menjaga data tetap sinkron di semua pecahan. dbas sangat terampil dan sangat prihatin bahwa menggabungkan replikasi mungkin tidak dapat menangani ini dan harus menggabungkan replikasi gagal, bahwa pemulihan dari kegagalan ini tidak besar dan dapat berdampak sangat negatif terhadap kami.
Saya ingin tahu apakah ada yang menggunakan opsi desain # 2. Saya juga ingin tahu apakah saya menghadap ke opsi desain ke-3 atau ke-4 yang tidak saya lihat.
Terima kasih sebelumnya.
sumber
Jawaban:
Pertanyaan Anda terfokus pada ini:
Saat Anda melakukan sharding, dan Anda memiliki data yang perlu dilihat semua pecahan, Anda harus mengklasifikasikan data tersebut dengan beberapa atribut:
Apakah sering berubah? Dalam contoh Anda, Anda mencantumkan Inventaris, Karyawan, dan Pengguna. Biasanya inventaris berubah sangat cepat, tetapi Catatan Karyawan hanya berubah secara berkala (katakanlah, beberapa ratus pembaruan per hari).
Berapa banyak keterlambatan yang dapat ditoleransi setiap pecahan?Meskipun Inventaris dapat terus berubah, Anda biasanya dapat mentolerir sejumlah besar keterlambatan (menit atau bahkan jam) di atas meja seperti itu. Jika Anda menjual barang-barang unik dengan jumlah yang sangat terbatas sehingga Anda tidak dapat mengisi kembali (bayangkan karya seni asli), maka Anda tidak akan membuang data itu sama sekali - Anda hanya meminta basis data asli. Namun, di sebagian besar toko online, Anda tidak menjual setiap item setiap hari, dan Anda akan mengisi kembali barang dengan cepat, jadi Anda tidak benar-benar membutuhkan jumlah inventaris hingga milidetik. Faktanya, dalam kebanyakan kasus, Anda hanya perlu bendera In-Stock yang 0 atau 1, dan proses pusat memperbarui bendera itu. Dengan begitu, Anda tidak perlu mendorong setiap tonjolan item naik / turun ke setiap pecahan. Data karyawan atau Pengguna, di sisi lain,
Apakah Anda akan bergabung dari tabel sharded ke yang non-sharded? Idealnya, jawabannya di sini adalah tidak - Anda harus membuat dua pertanyaan terpisah untuk mendapatkan data, dan kemudian bergabung dengan mereka di sisi aplikasi. Ini menjadi jauh lebih sulit dari perspektif aplikasi, tetapi memberi Anda kemampuan untuk mendapatkan data terbaru dari setiap sumber.
Apakah ini data asli, atau disalin?Cara lain untuk memikirkan pertanyaan ini: apa yang perlu Anda cadangkan, dan seberapa sering? Biasanya di lingkungan sharding volume tinggi, Anda ingin cadangan secepat dan sekecil mungkin. (Bagaimanapun, Anda perlu melindungi setiap node, dan Anda ingin semua pecahan gagal ke DR pada saat yang sama - tidak memiliki beberapa pecahan dengan data yang lebih baru daripada yang lain.) Ini berarti data yang terbengkalai dan data yang terbengkalai harus dalam database yang sepenuhnya terpisah - bahkan jika mereka berada di server yang sama. Saya mungkin memerlukan backup log transaksi konstan untuk data saya yang asli (sharded), tetapi saya mungkin tidak perlu membuat cadangan data yang tidak shard sama sekali. Mungkin lebih mudah bagi saya untuk hanya me-refresh tabel Karyawan atau Pengguna saya dari satu sumber kebenaran daripada mencadangkannya di setiap beling. Jika semua data saya ada dalam satu basis data,
Sekarang, tentang kekhawatiran Anda:
"Masalah transaksional ... kamu tidak lagi bisa melakukan ini dengan mudah." Benar. Dalam skenario sharded, buang konsep transaksi keluar jendela. Itu menjadi lebih buruk, juga - untuk data yang terbengkalai, Anda dapat memiliki satu pecahan dan online, dan pecahan lain sementara untuk sementara karena kegagalan atau restart contoh cluster. Anda perlu merencanakan kegagalan setiap bagian dari sistem, kapan saja.
"Tidak mungkin melakukan integritas referensial basis data." Benar. Ketika Anda membagi satu tabel di beberapa server, Anda menempatkan celana besar Anda dan memberitahu server database bahwa Anda mengambil alih untuk tugas-tugas sulit seperti backup point-in-time, hubungan antar tabel, dan menggabungkan data dari berbagai sumber. Ada pada Anda dan kode Anda sekarang.
"Mengode ulang area besar dari sistem sehingga ia tahu untuk menulis data umum ke database universal yang baru tetapi membaca data umum dari pecahan." Perbaiki di sini juga. Tidak ada tombol yang mudah untuk ini, tetapi begitu Anda telah membangun ini ke dalam aplikasi, Anda dapat skala seperti orang gila. Saya berpendapat bahwa cara yang lebih mudah untuk melakukan ini adalah dengan membagi koneksi aplikasi dengan membaca .
"peningkatan perjalanan basis data." - Ya, jika Anda memecah data menjadi beberapa server, aplikasi harus menjangkau lebih banyak ke jaringan. Kuncinya adalah mengimplementasikan caching juga sehingga beberapa data ini dapat disimpan dalam sistem yang lebih murah, throughput lebih tinggi, dan bebas kunci. Permintaan tercepat adalah yang Anda tidak pernah buat.
Saya juga telah meletakkan lebih banyak pro dan kontra untuk membagi basis data multi-penyewa di sini , seperti penyempurnaan kinerja pada pecahan individual, berbagai strategi cadangan / pemulihan per beling, dan tantangan penyebaran skema.
sumber
Pada level tinggi, cara tipikal untuk shard (atau partisi horizontal) data adalah dengan shard tabel transaksional dan mereplikasi tabel level master. Seperti kebanyakan solusi teknologi, ini tentu saja memecahkan satu set masalah dan menciptakan serangkaian masalah baru ... tapi kita semua sudah terbiasa dengan itu sekarang, bukan? ;-)
Saya akan mempertanyakan apakah SQLServer adalah solusi terbaik Anda untuk ini. Apakah beban kerjanya lebih seperti OLTP atau lebih seperti DW / BI?
Salam, Dave Sisk
sumber
Opsi ke-3 yang memungkinkan. Menggunakan sharding relasional (bukan sharding kotak hitam), Anda harus dapat shard dan mendistribusikan seluruh database Anda. Karena dibuat dari model data relasional tradisional, basis data mengetahui data apa yang disimpan pada server apa dan dengan demikian di mana menemukannya, sehingga semua data Anda dapat dianggap 'umum / universal'. Lihat dbShards sebagai kemungkinan untuk membuat seluruh proses sharding lebih mudah.
sumber