Latar Belakang :
Saya telah membuat aplikasi web yang ingin saya ukur dengan cukup baik. Saya tahu saya bukan Google atau Twitter, tetapi aplikasi saya menggunakan jumlah data yang cukup besar untuk setiap pengguna dan karenanya memiliki persyaratan data yang cukup tinggi. Saya ingin siap untuk mengukur dengan cukup baik tanpa harus merancang ulang semuanya nanti.
Saya menganggap diri saya seorang pengembang perangkat lunak, bukan ahli basis data. Itu sebabnya saya memposting di sini. Semoga seseorang dengan keahlian database yang lebih banyak dapat memberi saya saran.
Dengan jumlah pengguna yang relatif besar, tetapi tidak seperti angka Facebook, saya berharap memiliki DB yang terlihat seperti ini:
Satu "Big table":
- 250 juta catatan
- 20 kolom
- Sekitar 100 GB data
- Memiliki kunci asing bigint (20) yang diindeks
- Memiliki kolom string_id varchar (500) yang diindeks
- Memiliki kolom "nilai" int (11)
4 tabel lainnya:
- 10 juta catatan masing-masing
- Masing-masing sekitar 2 - 4 GB data
- masing-masing tabel ini memiliki 4 - 8 kolom
- satu kolom adalah datetime date_created
- satu kolom adalah kolom string_id varchar (500)
- satu atau dua kolom dari masing-masing tabel ini akan dipilih dalam gabungan
Salah satu tabel ini digunakan untuk menyimpan rata-rata - skemanya adalah bigint (20) id, varchar (20) string_id, datetime date_created, float average_value
Apa yang ingin saya lakukan - dua pertanyaan yang relatif mahal:
Hitung nilai rata-rata baru:
- Menggunakan kunci asing, pilih hingga beberapa juta catatan terpisah dari tabel besar.
- Hitung rata-rata baru, kelompokkan dengan string_id.
- Masukkan hasil ke dalam tabel rata-rata.
- Seperti yang saat ini dibangun, permintaan ini menggunakan dua gabungan.
Buat catatan yang tidak dinormalisasi dan hanya-baca untuk melayani pengguna:
- Gunakan kunci asing untuk memilih di mana saja dari 1.000-40.000 catatan dari tabel besar.
- Bergabung dengan masing-masing dari empat tabel lainnya pada catatan terbaru dengan kolom id string.
- Masukkan hasilnya ke dalam tabel yang tidak dinormalisasi.
- Catatan-catatan ini untuk digunakan oleh front-end untuk menampilkan informasi kepada pengguna.
- Saat ini dibangun, permintaan ini menggunakan empat bergabung.
Saya berencana untuk menjalankan masing-masing pertanyaan mahal ini pada database back-end batch yang akan mendorong hasilnya ke server DB front-end real-time yang menangani permintaan dari pengguna. Kueri ini akan dijalankan secara berkala. Saya belum memutuskan seberapa sering. Permintaan rata-rata dapat dilakukan mungkin sekali sehari. Permintaan de-normalisasi harus lebih sering - mungkin setiap beberapa menit.
Setiap pertanyaan ini saat ini berjalan dalam beberapa detik di MySQL pada mesin yang sangat low-end dengan dataset dengan catatan 100 ribu dalam "tabel besar." Saya prihatin dengan kemampuan saya untuk mengukur dan biaya penskalaan.
Pertanyaan :
- Apakah pendekatan ini terdengar masuk akal? Apakah ada yang salah dengan perspektif besar?
- Apakah RDBMS alat yang tepat, atau haruskah saya melihat solusi "data besar" lainnya seperti sesuatu dalam keluarga Hadoop? Kecenderungan saya adalah menggunakan RDBMS karena data terstruktur dan cocok dengan model relasional. Namun pada titik tertentu, menurut pemahaman saya bahwa saya mungkin tidak lagi dapat menggunakan RDBMS. Benarkah itu? Kapan saklar ini dibutuhkan?
- Apakah ini akan berhasil? Bisakah pertanyaan ini dijalankan dalam jumlah waktu yang wajar? Saya bisa menunggu beberapa jam untuk kueri # 1, tetapi kueri # 2 akan selesai dalam hitungan menit.
- Apa yang harus saya pertimbangkan dari perspektif perangkat keras? Seperti apa kemungkinan bottleneck RAM dan CPU saya? Saya menganggap menjaga indeks dalam RAM adalah penting. Apakah ada hal lain yang harus saya pertimbangkan?
- Pada titik tertentu saya mungkin harus mempartisi data saya dan menggunakan beberapa server. Apakah use case saya sepertinya sudah dalam kategori itu, atau akankah saya dapat mengukur satu mesin secara vertikal untuk sementara waktu? Apakah ini akan berfungsi dengan 10x data? 100x?
Jawaban:
Sudahkah Anda mencoba menumpuk lebih banyak data dan membandingkannya? Baris 100K tidak penting. Coba 250M atau 500M seperti yang Anda harapkan Anda harus menangani dan melihat di mana kemacetan.
RDBMS dapat melakukan banyak hal jika Anda memperhatikan dengan cermat keterbatasan dan mencoba dan bekerja dengan kekuatan sistem. Mereka sangat pandai dalam beberapa hal, dan mengerikan dalam hal-hal lain, jadi Anda perlu bereksperimen untuk memastikan itu pas.
Untuk beberapa pekerjaan pemrosesan batch, Anda benar-benar tidak dapat mengalahkan file datar, memuat data ke dalam RAM, menghancurkannya menggunakan serangkaian loop dan variabel sementara, dan membuang hasilnya. MySQL tidak akan pernah bisa menandingi kecepatan semacam itu, tetapi jika disetel dengan benar dan digunakan dengan benar, ia bisa mencapai urutan besarnya.
Apa yang ingin Anda lakukan adalah menyelidiki bagaimana data Anda dapat dipartisi. Apakah Anda memiliki satu set data besar dengan terlalu banyak jalur silang untuk dapat membaginya, atau adakah tempat alami untuk mempartisi itu? Jika Anda dapat mempartisi itu, Anda tidak akan memiliki satu tabel dengan setumpuk baris, tetapi berpotensi banyak yang secara signifikan lebih kecil. Tabel yang lebih kecil, dengan indeks yang jauh lebih kecil, cenderung berkinerja lebih baik.
Dari perspektif perangkat keras, Anda harus menguji untuk melihat kinerja platform Anda. Terkadang ingatan sangat penting. Lain kali itu disk I / O. Itu benar-benar tergantung pada apa yang Anda lakukan dengan data. Anda harus memperhatikan penggunaan CPU Anda dan mencari IO tingkat tinggi menunggu untuk mengetahui di mana masalahnya.
Kapan pun memungkinkan, bagi data Anda menjadi beberapa sistem. Anda dapat menggunakan MySQL Cluster jika Anda merasa berani, atau hanya memutar banyak contoh independen dari MySQL di mana masing-masing menyimpan bagian sewenang-wenang dari kumpulan data lengkap menggunakan beberapa skema partisi yang masuk akal.
sumber
Tabel Ringkasan.
Setiap hari, hitung informasi agregat untuk data hari itu. Taruh itu di tabel "ringkasan". Lakukan pertanyaan Anda terhadap mereka. Mudah 10 kali lebih cepat.
Untuk diskusi lebih lanjut, berikan
Beberapa hal yang jelas ...
"Lebih kecil -> lebih banyak cacheable -> lebih cepat
sumber
Untuk menyajikan data ujung depan Anda, kecuali ada sekumpulan dan sekumpulan sisipan sepanjang waktu, Anda benar-benar tidak dapat mengalahkan menggunakan pemicu untuk menyisipkan ke dalam tampilan material yang disimpan dalam sinkronisasi dengan ujung belakang tetapi dioptimalkan untuk melayani data. Tentu saja, Anda harus tetap bergabung, dll, dll, ke minimum pemicu ini. Salah satu strategi yang saya gunakan adalah memasukkan antrian sisipan / pembaruan ini ke tabel perantara dan kemudian mengirimkannya setiap menit atau lebih. Jauh lebih mudah untuk mengirim satu catatan dari 4 GB catatan. 4 GB data membutuhkan waktu lama untuk streaming bahkan jika Anda dapat menemukan catatan yang Anda cari dengan cepat.
Saya setuju dengan tadman. Yang terbaik adalah profil itu dengan jenis data yang Anda harapkan pada jenis sistem yang Anda inginkan.
sumber