Mysql: Bekerja Dengan 192 Triliun Rekaman ... (Ya, 192 Triliun)

39

Inilah pertanyaannya ...

Mempertimbangkan 192 triliun catatan, apa yang harus saya pertimbangkan?

Perhatian utama saya adalah kecepatan.

Ini meja ...

    CREATE TABLE `ref` (
  `id` INTEGER(13) AUTO_INCREMENT DEFAULT NOT NULL,
  `rel_id` INTEGER(13) NOT NULL,
  `p1` INTEGER(13) NOT NULL,
  `p2` INTEGER(13) DEFAULT NULL,
  `p3` INTEGER(13) DEFAULT NULL,
  `s` INTEGER(13) NOT NULL,
  `p4` INTEGER(13) DEFAULT NULL,
  `p5` INTEGER(13) DEFAULT NULL,
  `p6` INTEGER(13) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY (`s`),
  KEY (`rel_id`),
  KEY (`p3`),
  KEY (`p4`)
    );

Inilah pertanyaannya ...

SELECT id, s FROM ref WHERE red_id="$rel_id" AND p3="$p3" AND p4="$p4"

SELECT rel_id, p1, p2, p3, p4, p5, p6 FROM ref WHERE id="$id"

INSERT INTO rel (rel_id, p1, p2, p3, s, p4, p5, p6)
VALUES ("$rel_id", "$p1", "$p2", "$p3", "$s", "$p4", "$p5", "$p6")

Ini beberapa catatan ...

  • SELECT akan dilakukan lebih sering daripada INSERT. Namun, kadang-kadang saya ingin menambahkan beberapa ratus catatan sekaligus.
  • Dari segi muatan, tidak akan ada apa pun selama berjam-jam maka mungkin beberapa ribu pertanyaan sekaligus.
  • Jangan pikir saya bisa menormalkan lagi (perlu nilai p dalam kombinasi)
  • Basis data secara keseluruhan sangat relasional.
  • Ini akan menjadi meja terbesar sejauh ini (terbesar berikutnya sekitar 900k)

UPDATE (08/11/2010)

Menariknya, saya telah diberi opsi kedua ...

Alih-alih 192 triliun saya bisa menyimpan 2,6 * 10 ^ 16 (15 nol, artinya 26 Quadrillion) ...

Tetapi dalam opsi kedua ini saya hanya perlu menyimpan satu bigint (18) sebagai indeks dalam sebuah tabel. Itu dia - hanya satu kolom. Jadi saya hanya akan memeriksa keberadaan suatu nilai. Terkadang menambahkan catatan, jangan pernah menghapusnya.

Sehingga membuat saya berpikir harus ada solusi yang lebih baik maka mysql untuk sekadar menyimpan angka ...

Diberi pilihan kedua ini, haruskah saya mengambilnya atau tetap dengan yang pertama ...

[sunting] Baru saja mendapat kabar tentang beberapa pengujian yang telah dilakukan - 100 juta baris dengan pengaturan ini mengembalikan kueri dalam 0,0004 detik [/ edit]

Sarah
sumber
7
Bagaimana Anda menggunakan MySQL untuk hal ini? Bisakah Anda diyakinkan untuk beralih ke dbms yang berbeda jika seseorang memberikan argumen yang kuat untuk melakukannya?
WheresAlice
3
Triliun seperti pada 10 ^ 12 atau pada 10 ^ 18?
andol
15
Pada catatan 192 Triliun Anda harus memiliki anggaran yang memungkinkan Anda untuk mengajukan pertanyaan kepada pengendara MySQL, bukan ke forum diskusi.
Remus Rusanu
5
Dengan database sebesar ini (dan tentu saja anggaran yang layak) mengapa tidak pergi dengan dan solusi oracle atau sql yang telah terbukti dengan mudah menangani DB besar?
Jim B
5
Pastikan untuk selalu memperbarui kami ketika Anda menerapkan ini. Saya pasti akan tertarik. Anda mungkin juga ingin menuliskannya untuk highscalability.com
Tom O'Connor

Jawaban:

30

Perkiraan pQd tentang 7PB tampaknya masuk akal, dan itu banyak data untuk RDBMS. Saya tidak yakin pernah mendengar seseorang melakukan 7PB dengan sistem disk bersama, apalagi MySQL. Meminta volume data ini dengan sistem disk bersama apa pun akan menjadi sangat lambat. Perangkat keras SAN tercepat mencapai kecepatan 20GB / detik bahkan saat disetel untuk kueri streaming yang besar. Jika Anda dapat membeli perangkat keras SAN dari spesifikasi ini, Anda dapat menggunakan sesuatu yang lebih cocok untuk pekerjaan daripada MySQL.

Bahkan, saya berjuang untuk memahami skenario di mana Anda bisa memiliki anggaran untuk subsistem disk dari spesifikasi ini tetapi tidak untuk platform DBMS yang lebih baik. Bahkan menggunakan 600GB disk (drive 'perusahaan' 15K terbesar saat ini di pasaran) Anda siap untuk sekitar 12.000 drive disk fisik untuk menyimpan 7PB. Disk SATA akan lebih murah (dan dengan disk 2TB Anda akan membutuhkan sekitar 1/3 dari jumlahnya), tetapi sedikit lebih lambat.

SAN dari spesifikasi ini dari vendor besar seperti EMC atau Hitachi akan mencapai jutaan dolar. Terakhir kali saya bekerja dengan peralatan SAN dari vendor besar, biaya transfer ruang pada IBM DS8000 lebih dari £ 10rb / TB, tidak termasuk tunjangan modal apa pun untuk pengontrol.

Anda benar-benar membutuhkan sistem apa pun yang dibagikan seperti Teradata atau Netezza untuk data sebanyak ini. Mengosongkan database MySQL mungkin berhasil, tetapi saya akan merekomendasikan platform VLDB yang dibangun khusus. Sistem apa-apa yang dibagikan juga memungkinkan Anda menggunakan disk attach-langsung yang jauh lebih murah pada node - lihat platform Sun X4550 (thumper) untuk satu kemungkinan.

Anda juga perlu memikirkan persyaratan kinerja Anda.

  • Apa waktu berjalan yang dapat diterima untuk kueri?
  • Seberapa sering Anda akan menanyakan dataset Anda?
  • Bisakah sebagian besar pertanyaan diselesaikan dengan menggunakan indeks (yaitu apakah mereka akan melihat sebagian kecil - katakan: kurang dari 1% - dari data), atau apakah mereka perlu melakukan pemindaian tabel penuh?
  • Seberapa cepat data akan dimuat ke dalam database?
  • Apakah pertanyaan Anda memerlukan data terbaru atau dapatkah Anda hidup dengan tabel pelaporan yang diperbarui secara berkala?

Singkatnya, argumen terkuat terhadap MySQL adalah bahwa Anda akan melakukan backflips untuk mendapatkan kinerja kueri yang layak atas 7PB data, jika mungkin sama sekali. Volume data ini benar-benar menempatkan Anda ke dalam wilayah tanpa-berbagi untuk membuat sesuatu yang akan menanyakannya dengan cukup cepat, dan Anda mungkin akan membutuhkan platform yang dirancang untuk operasi tanpa-berbagi sejak awal. Disk sendiri akan mengurangi biaya platform DBMS yang masuk akal.

Catatan: Jika Anda membagi basis data operasional dan pelaporan, Anda tidak harus menggunakan platform DBMS yang sama untuk keduanya. Mendapatkan sisipan cepat dan laporan sub-detik dari tabel 7PB yang sama setidaknya akan menjadi tantangan teknis.

Diberikan dari komentar Anda bahwa Anda dapat hidup dengan beberapa latensi dalam pelaporan, Anda dapat mempertimbangkan sistem penangkapan dan pelaporan terpisah, dan Anda mungkin tidak perlu menyimpan semua 7PB data dalam sistem penangkapan operasional Anda. Pertimbangkan platform operasional seperti Oracle (MySQL dapat melakukan ini dengan InnoDB) untuk pengambilan data (sekali lagi, biaya disk saja akan mengurangi biaya DBMS kecuali Anda memiliki banyak pengguna) dan platform VLDB seperti Teradata, Sybase IQ, RedBrick, Netezza (catatan: perangkat keras berpemilik) atau Greenplum untuk pelaporan

ConcernedOfTunbridgeWells
sumber
1
@ConcernedOfTunbridgeW - mereka selalu bisa seperti ini: blog.backblaze.com/2009/09/01/... - jauh lebih menyenangkan daripada SAN, hanya ~ 120-130 4U kotak diperlukan ... tapi saya tidak yakin apakah itu bisnis 'akan bahagia ....
pQd
Pada dasarnya Sun Thumper pada anggaran dan benar-benar contoh dari opsi untuk sebuah node dalam sistem shared-nothing. Saya yakin saya telah melihat opsi lain untuk ini juga, tetapi saya tidak bisa memikirkan di mana. Pertanyaannya bukan hardware apa tapi platform database apa.
ConcernedOfTunbridgeWells
Namun, pengamat yang tajam akan mencatat bahwa segala jenis kotak berbasis pemasangan langsung seperti ini jauh, jauh lebih murah per TB daripada apa pun yang didasarkan pada SAN, yang merupakan setidaknya satu argumen signifikan yang mendukung sesuatu yang dirancang untuk bekerja pada platform berbagi-apa-apa .
ConcernedOfTunbridgeWells
@ConcernedOfTunbridgeWells dan Anda dapat menjalankan semua kueri / pemeliharaan itu dan apa pun secara paralel pada beberapa kotak [jika tidak, haus daya].
pQd
1
@ConcernedOfTunbridgeWells - untuk menjawab pertanyaan Anda ... Saya perlu sekitar 500 pertanyaan untuk kembali dalam waktu kurang dari satu detik, jika mungkin. Saya akan melakukan ini hanya beberapa ratus kali sehari. Ketika kueri berjalan, tabel lengkap perlu dipindai. Juga INSERT adalah prioritas yang lebih rendah daripada SELECT, sehingga tidak harus mendekati instan. Saya bisa menunggu beberapa jam hingga data "baru" masuk ke database.
Sarah
16

beling itu. pada ukuran ini memiliki satu contoh besar adalah bunuh diri - pikirkan tentang kemungkinan pemulihan cadangan, kerusakan ruang tabel, menambahkan kolom baru atau proses 'pemeliharaan rumah' lainnya - semua itu tidak mungkin dilakukan dalam waktu yang wajar pada skala ini.

punggung sederhana dari perhitungan amplop - dengan asumsi bilangan bulat 32bit untuk semua kolom kecuali 64bit id; tidak ada indeks yang disertakan:

8 * 4B + 8B = 40B per baris [dan ini sangat optimis]

192 Triliun baris 40B masing-masing memberi kita hampir 7 PB

mungkin Anda dapat memikirkan kembali semuanya, meringkas informasi untuk pelaporan cepat, dan menyimpan catatan terkompresi untuk interval waktu tertentu ketika seseorang perlu menggali rincian yang lebih dalam.

pertanyaan untuk dijawab:

  • apa downtime yang dapat diterima jika sistem crash / reboot?
  • apa downtime yang dapat diakses ketika Anda perlu memulihkan cadangan atau mengeluarkan server dari produksi untuk pemeliharaan yang direncanakan.
  • seberapa sering dan di mana Anda ingin membuat cadangan?

tautan acak - kecepatan sisipan:

pQd
sumber
Saya setuju - 7PB cukup berat. Saya suka memikirkan kembali dan menemukan solusi yang lebih ringan, tetapi saya perlu menemukan keberadaan (atau tidak adanya) kombinasi tertentu dari bidang p. Memisahkan tabel terlintas di pikiran saya - ini lebih masuk akal, tapi kemudian itu berarti saya punya kueri setiap tabel secara bergantian. Karena ketertarikan, berapa banyak tabel yang akan Anda rekomendasikan untuk dibelah di sini?
Sarah
5
@ Sarah - saya tidak hanya akan merekomendasikan membelah menjadi tabel tetapi juga mesin. Anda dapat menjalankan kueri Anda secara paralel untuk mendapatkan kinerja [saya melakukannya dalam skala yang lebih kecil]. bagaimana dengan kerusakan sistem file atau bahkan pemeriksaan rutin setelah server reboot? Saya tidak yakin apa yang Anda maksud dengan menemukan kombinasi tertentu ... mungkin toko kunci-nilai sederhana akan membantu? ukuran tabel - tidak lebih dari beberapa puluh GB; data pada server tunggal - tidak lebih dari beberapa TB. lihat stackoverflow.com/questions/654594 untuk mengetahui sakit kepala seperti apa yang diharapkan pada skala yang jauh lebih kecil; gunakan innodb_file_per_table
pQd
8

Panggil Percona . Jangan lulus "Pergi". Jangan kumpulkan $ 200.

JustinShoffstall
sumber
2

Mungkin ada cara lain, daripada menyimpan empat angka jika semua yang ingin Anda lakukan adalah melihat apakah mereka ada di set. Filter Bloom adalah metode probabilistik, dengan hashing dalam berbagai cara. Juga, positif palsu dimungkinkan, tetapi negatif palsu tidak mungkin. (Jadi, bisa dikatakan nomornya ada di set - dan salah, tetapi tidak akan mengatakan itu tidak ada, jika benar-benar ada). Masih ada masalah banyaknya item untuk disimpan, tapi setidaknya itu bisa menurunkan ukuran dataset.

Alister Bulman
sumber
Kedengarannya menarik, meskipun saya bisa hidup dengan negatif palsu - tetapi bukan positif palsu :)
Sarah
2

Sunting: Sebenarnya jika itu hanya keberadaan atau tidak dari "catatan" di lokasi X dalam berbagai bilangan bulat, Anda dapat menghilangkan datastore dan hanya menggunakan bitmap ... Jadi, 10 atau lebih mesin dengan 100 TB ruang disk (sehingga Anda memiliki 10 salinan bitmap Anda untuk kinerja dan cadangan) dan jika Anda melakukan 128GB RAM per server, Anda dapat memasukkan indeks blockgroup tingkat tinggi resolusi tinggi dalam memori untuk melakukan pemeriksaan pertama sebelum memukul disk untuk bit X dari 26 Quadrillion .

Saya akan memilih opsi # 2 Jika Anda mengambil:

375 mesin dengan 64TB (32 drive 2TB) masing-masing (secara realistis 400 mesin untuk kegagalan) kemudian hanya memetakan catatan ke ZVOL yang masing-masing 2TB. Kemudian pada satu atau lebih server indeks, simpan dalam array Judy atau array critbit atau hanya bitmap, pemetaan jika Anda telah menambahkan catatan ke 1 dari 26 lokasi Quadrillion. Indeks akan berada di antara 50 dan 100TB dan Anda bahkan bisa memiliki indeks tingkat kedua yang muncul jika ada catatan yang ditulis ke blok alamat 64k tertentu yang akan cocok dengan kurang dari 64 GB RAM dan akan memberikan tingkat pemeriksaan awal yang cepat apakah "lingkungan" tertentu kosong atau tidak.

Kemudian untuk membaca catatan itu, Anda terlebih dahulu akan memeriksa apakah ada catatan untuk menemukan dengan melihat indeks. Jika ada, maka pergi ke mesin # (X) / ZOL # (Y) pada mesin itu / catat lokasi # (Z) dalam gumpalan 2TB tersebut berdasarkan pada perhitungan indeks sederhana. Single record look up akan sangat cepat dan Anda dapat menguji memuat beberapa bagian dari datastore ke dbs yang berbeda (saat Anda menggunakan datastore untuk pekerjaan nyata) dan melakukan pengujian kinerja untuk melihat apakah mereka mampu mendukung seluruh database Anda - atau tidak, cukup gunakan penyimpanan data seperti itu.

ZOL adalah hal ZFS yang dapat dianggap sebagai file yang jarang di sistem file lain, jadi hal serupa akan berlaku. Atau Anda bisa saja mengindeks ke nomor byte tertentu pada disk, tetapi ini menjadi rumit jika disk berukuran berbeda jika Anda tidak membatasi jumlah byte yang digunakan per disk pada tingkat yang bekerja untuk semua disk - yaitu 1,75TB per disk 2TB . Atau buat layanan metad yang berukuran tetap, dll.


sumber
Hai Sarah - tidak yakin apakah Anda masih mengerjakan ini, tetapi jika Anda membutuhkan bantuan, saya dapat membuat prototipe ide saya untuk Anda pada mesin 100TB dan juga bersedia menjadi tuan rumah (di pusat data utama AS) dan mengelola kluster produksi penuh 400-500 mesin sesuai kebutuhan. BTW, apakah Anda pernah bekerja di CNET di SF?
1

Selain menyetel params DB Anda seperti orang gila (gunakan mysqltuner untuk membantu) untuk mencoba dan menjaga cache SELECT Anda sebanyak mungkin secara manusiawi, satu hal yang mungkin Anda selidiki adalah MULAI TRANSAKSI / KOmITI (dengan asumsi InnoDB) ketika memasukkan beberapa ratus catatan Anda untuk menghindari baris demi baris mengunci overhead dan membawa waktu insert Anda turun dengan faktor besar. Saya juga akan membuat tabel sebagai MyISAM dan InnoDB dan menjalankan tes untuk melihat mana yang benar-benar lebih cepat setelah Anda mendapatkan caching diperketat - tidak selalu bahwa MyISAM akan lebih cepat untuk dibaca - lihat ini:

http://www.mysqlperformanceblog.com/2007/01/08/innodb-vs-myisam-vs-falcon-benchmarks-part-1/

Selama pengujian Anda, jumlah utas bersamaan juga harus bervariasi naik dan turun sampai Anda menemukan titik manis untuk berapa banyak RAM yang Anda mampu di server untuk mendedikasikan untuk menyetel cache; Anda mungkin menemukan bahwa sementara Anda dapat mendukung lebih banyak utas oleh matematika, DB itu sendiri sebenarnya dapat berkinerja lebih buruk jika jumlah utas terlalu tinggi.

Juga, jika Anda menggunakan file-per-tabel MyISAM dan / atau InnoDB, Anda dapat menyelidiki pembuatan titik mount sistem file yang berbeda untuk / var / lib / mysql yang disetel ke ukuran blok yang lebih kecil dan menyetel par-jenis fs - yaitu ext3 / ext4 / resiserfs Anda bisa menggunakan data = writeback untuk jurnal dan menonaktifkan pembaruan waktu akses pada sistem file untuk kecepatan I / O.

troyengel
sumber
1
myisam tampaknya tidak masuk akal karena persyaratan transaksi.
pQd
0

Untuk opsi kedua, berapa banyak angka yang kemungkinan ditempatkan?

Jika hanya akan ada satu dalam seribu, atau 10K, 100K, dll, maka menyimpan rentang angka yang digunakan (atau tidak terpakai) dapat menghemat triliunan entri. misalnya: menyimpan ('gratis', 0,100000), ('diambil', 100000,100003), ('gratis', 100004,584234) - memecah baris menjadi dua atau tiga baris sesuai kebutuhan, dan mengindeks pada nomor pertama, mencari x <= {jarum} untuk melihat apakah rentang yang mengandung nomor yang dicari diambil, atau gratis.

Anda bahkan mungkin tidak memerlukan kedua status. Simpan saja status apa pun yang paling tidak mungkin.

Alister Bulman
sumber