Saya menulis aplikasi yang perlu menyimpan dan menganalisis sejumlah besar data listrik dan suhu.
Pada dasarnya saya perlu menyimpan sejumlah besar pengukuran penggunaan listrik per jam selama beberapa tahun terakhir dan selama bertahun-tahun yang akan datang untuk puluhan ribu lokasi dan kemudian menganalisis data dengan cara yang tidak terlalu rumit.
Informasi yang perlu saya simpan (untuk saat ini) adalah ID Lokasi, Stempel Waktu (Tanggal dan Waktu), Suhu dan Penggunaan Listrik.
Tentang jumlah data yang perlu disimpan, ini merupakan perkiraan, tetapi ada sesuatu di sepanjang garis itu:
20 000+ lokasi, 720 catatan per bulan (pengukuran per jam, sekitar 720 jam per bulan), 120 bulan (selama 10 tahun yang lalu) ) dan bertahun-tahun ke depan. Perhitungan sederhana menghasilkan hasil berikut:
20 000 lokasi x 720 catatan x 120 bulan (10 tahun yang lalu) = 1 728.000 catatan .
Ini adalah catatan yang lalu, catatan baru akan diimpor setiap bulan, jadi itu sekitar 20.000 x 720 = 14.400.000 catatan baru per bulan .
Total lokasi akan terus tumbuh juga.
Pada semua data itu, operasi berikut perlu dijalankan:
- Ambil data untuk tanggal dan periode waktu tertentu: semua catatan untuk ID Lokasi tertentu antara tanggal 01.01.2013 dan 01.01.2017 dan antara 07: 00-13: 00.
- Operasi matematika sederhana untuk tanggal dan rentang waktu tertentu, mis. MIN, MAX dan suhu AVG dan penggunaan listrik untuk ID Lokasi tertentu selama 5 tahun antara pukul 07: 00-13: 00.
Data akan ditulis setiap bulan, tetapi akan dibaca oleh ratusan pengguna (setidaknya) terus-menerus, sehingga kecepatan baca secara signifikan lebih penting.
Saya tidak punya pengalaman dengan database NoSQL tetapi dari apa yang saya kumpulkan, mereka adalah solusi terbaik untuk digunakan di sini. Saya sudah membaca di database NoSQL paling populer, tetapi karena mereka sangat berbeda dan juga memungkinkan untuk arsitektur tabel yang sangat berbeda, saya belum dapat memutuskan apa yang terbaik untuk digunakan database.
Pilihan utama saya adalah Cassandra dan MongoDB, tapi saya karena saya memiliki pengetahuan yang sangat terbatas dan tidak ada pengalaman nyata ketika datang ke data besar dan NoSQL saya tidak terlalu yakin. Saya juga membaca bahwa PostreSQL juga menangani jumlah data dengan baik.
Pertanyaan saya adalah sebagai berikut:
- Haruskah saya menggunakan database NoSQL untuk data dalam jumlah besar. Jika tidak, bisakah saya tetap menggunakan MySQL?
- Basis data apa yang harus saya gunakan?
- Haruskah saya menyimpan tanggal dan waktu dalam kolom terpisah, diindeks (jika mungkin) untuk mengambil dan memproses data dengan cepat untuk periode waktu dan tanggal tertentu, atau dapatkah ini dilakukan dengan menjaga stempel waktu dalam satu kolom?
- Apakah pendekatan pemodelan data deret waktu sesuai di sini, dan jika tidak, Anda bisa memberi saya petunjuk untuk desain tabel yang baik?
Terima kasih.
Jawaban:
Ini persis apa yang saya lakukan setiap hari, kecuali alih-alih menggunakan data per jam, saya menggunakan data 5 menit. Saya mengunduh sekitar 200 juta catatan setiap hari, jadi jumlah yang Anda bicarakan di sini tidak menjadi masalah. Data 5 menit berukuran sekitar 2 TB dan saya memiliki data cuaca selama 50 tahun pada tingkat per jam berdasarkan lokasi. Jadi izinkan saya menjawab pertanyaan Anda berdasarkan pengalaman saya:
Kiat umum: Saya menyimpan sebagian besar data di antara dua basis data, yang pertama adalah data deret waktu lurus dan dinormalisasi. Basis data kedua saya sangat tidak normal dan berisi data pra-agregat. Secepat sistem saya, saya tidak buta terhadap fakta bahwa pengguna bahkan tidak ingin menunggu 30 detik untuk memuat laporan - bahkan jika saya pribadi berpikir 30 detik untuk menggerogoti 2 TB data sangat cepat.
Untuk menguraikan mengapa saya merekomendasikan menyimpan jam terpisah dari tanggal, berikut adalah beberapa alasan mengapa saya melakukannya dengan cara itu:
DATETIME
kolom.Seperti yang saya katakan di atas, ini semua didasarkan pada pengalaman pribadi saya, dan biarkan saya memberi tahu Anda, sudah beberapa tahun yang sulit dan banyak perancangan ulang untuk sampai ke tempat saya sekarang. Jangan lakukan apa yang saya lakukan, belajar dari kesalahan saya dan pastikan Anda melibatkan pengguna akhir sistem Anda (atau pengembang, penulis laporan dll ...) ketika membuat keputusan tentang database Anda.
sumber
Indeks PostgreSQL dan BRIN
Uji sendiri. Ini bukan masalah pada laptop berusia 5 tahun dengan SSD.
Jadi butuh 22 menit untuk membuat tabel. Sebagian besar, karena meja adalah 97GB sederhana. Selanjutnya kita buat indeks,
Butuh waktu lama untuk membuat indeks juga. Meskipun karena mereka BRIN mereka hanya 2-3 MB dan mereka menyimpan dengan mudah di ram. Membaca 96 GB tidak instan, tetapi itu bukan masalah nyata untuk laptop saya di beban kerja Anda.
Sekarang kita query itu.
Perbarui dengan cap waktu
Di sini kita menghasilkan tabel dengan cap waktu yang berbeda untuk memenuhi permintaan untuk mengindeks dan mencari pada kolom cap waktu, pembuatannya membutuhkan waktu sedikit lebih lama karena
to_timestamp(int)
jauh lebih lambat daripadanow()
(yang di-cache untuk transaksi)Sekarang kita dapat menjalankan kueri pada nilai timestamp, sebagai gantinya,
Hasil:
Jadi dalam 83.321 ms kita bisa mengumpulkan 86.401 catatan dalam sebuah tabel dengan 1,7 Miliar baris. Itu harus masuk akal.
Jam berakhir
Menghitung akhir jam juga cukup mudah, pangkas stempel waktu, lalu tambahkan satu jam.
Penting untuk dicatat, bahwa itu tidak menggunakan indeks pada agregasi, meskipun bisa. Jika itu biasanya permintaan Anda, Anda mungkin ingin BRIN di
date_trunc('hour', tsin)
sana terletak masalah kecil yangdate_trunc
tidak dapat diubah sehingga Anda harus terlebih dahulu membungkusnya untuk membuatnya jadi.Partisi
Poin penting lain dari informasi tentang PostgreSQL adalah bahwa PG 10 membawa partisi DDL . Jadi, Anda dapat, misalnya, dengan mudah membuat partisi untuk setiap tahun. Memecah database sederhana Anda menjadi yang kecil yang kecil. Dengan demikian, Anda harus dapat menggunakan dan mempertahankan indeks btree daripada BRIN yang akan lebih cepat.
Atau terserah.
sumber
Saya kagum pada saya bahwa tidak ada orang di sini yang menyebutkan benchmarking - sampai @EvanCarroll datang dengan kontribusinya yang luar biasa!
Jika saya jadi Anda, saya akan meluangkan waktu (dan ya, saya tahu itu komoditas berharga!) Menyiapkan sistem, menjalankan apa yang Anda pikir akan (dapatkan input pengguna akhir di sini!), Katakanlah, 10 pertanyaan paling umum Anda.
Pikiran saya sendiri:
Solusi NoSQL dapat bekerja dengan sangat baik untuk kasus penggunaan tertentu tetapi seringkali tidak fleksibel untuk permintaan ad-hoc. Untuk penjelasan lucu tentang NoSQL oleh Brian Aker - mantan kepala arsitek MySQL, lihat di sini !
Saya setuju dengan @BrBrownstone bahwa data Anda sangat cocok untuk solusi relasional (dan pendapat ini telah dikonfirmasi oleh Evan Carroll )!
Jika saya berkomitmen untuk pengeluaran apa pun, itu akan menjadi teknologi disk saya! Saya akan menghabiskan uang yang saya miliki untuk NAS atau SAN atau mungkin beberapa disk SSD untuk menampung data agregat yang jarang saya tulis!
Pertama saya akan melihat apa yang saya miliki sekarang . Jalankan beberapa tes dan tunjukkan hasilnya kepada pembuat keputusan. Anda sudah memiliki proxy dalam bentuk karya EC ! Tapi, satu atau dua tes cepat dikocok bersama pada perangkat keras Anda sendiri akan lebih meyakinkan!
Kemudian pikirkan tentang pengeluaran uang! Jika Anda akan menghabiskan uang, lihat perangkat keras lebih dulu daripada perangkat lunak. AFAIK, Anda dapat menyewa teknologi disk untuk masa uji coba, atau lebih baik lagi, memutar beberapa konsep bukti di cloud.
Port of call pertama saya pribadi untuk sebuah proyek seperti ini adalah PostgreSQL. Itu bukan untuk mengatakan bahwa saya akan mengesampingkan solusi berpemilik, tetapi hukum fisika dan disk adalah sama untuk semua orang! "Yae cannae beet the law of 'Jim fisika" :-)
sumber
Jika Anda belum melakukannya, lihatlah DBMS deret waktu, karena ini dioptimalkan untuk menyimpan dan menanyakan data di mana fokus utama adalah jenis tanggal / waktu. Biasanya basis data seri waktu digunakan untuk merekam data dalam rentang menit / detik / sub-detik, jadi saya tidak yakin apakah itu masih sesuai untuk kenaikan per jam. Yang mengatakan, jenis DBMS ini tampaknya layak untuk dilihat. Saat ini InfluxDB tampaknya menjadi basis data time series yang paling mapan dan banyak digunakan.
sumber
Jelas ini bukan masalah NoSQL, tapi saya akan menyarankan bahwa sementara solusi RDBMS akan bekerja, saya pikir pendekatan OLAP akan jauh lebih baik dan mengingat rentang data yang sangat terbatas, saya akan sangat menyarankan menyelidiki penggunaan DB berbasis kolom ketimbang yang berbasis baris. Pikirkan seperti ini, Anda mungkin memiliki 1,7 miliar keping data, tetapi Anda hanya perlu 5 bit untuk mengindeks setiap nilai jam atau hari dalam sebulan.
Saya memiliki pengalaman dengan domain masalah serupa di mana Sybase IQ (sekarang SAP IQ) digunakan untuk menyimpan hingga 300 juta counter per jam data manajemen kinerja peralatan telekomunikasi, tetapi saya ragu apakah Anda memiliki anggaran untuk solusi semacam itu. Di arena open source, MariaDB ColumnStore adalah kandidat yang sangat menjanjikan, tetapi saya akan merekomendasikan juga menyelidiki MonetDB.
Karena kinerja kueri adalah penggerak utama bagi Anda, berikan pertimbangan tentang bagaimana kueri akan diungkapkan. Di sinilah OLAP dan RDBMS menunjukkan perbedaan terbesar mereka: - dengan OLAP Anda menormalkan kinerja permintaan, bukan untuk mengurangi pengulangan, mengurangi penyimpanan atau bahkan untuk menegakkan konsistensi. Jadi selain stempel waktu asli (Anda masih ingat untuk menangkap zona waktunya, saya harap?) Memiliki bidang terpisah untuk stempel waktu UTC, yang lain untuk tanggal dan waktu, dan lebih banyak lagi untuk tahun, bulan, hari, jam, menit dan offset UTC. Jika Anda memiliki informasi tambahan tentang lokasi, jangan ragu untuk menyimpannya di tabel lokasi terpisah yang dapat dilihat sesuai permintaan dan jangan ragu untuk menyimpan kunci ke tabel itu di catatan utama Anda tetapi simpan nama lokasi lengkap di tabel utama Anda sebagai baiklah, setelah semua,
Sebagai saran terakhir, gunakan tabel terpisah untuk data agregat populer dan gunakan pekerjaan batch untuk mengisinya, dengan cara itu Anda tidak harus mengulang latihan untuk masing-masing dan setiap laporan yang menggunakan nilai agregat dan membuat kueri yang membandingkan saat ini dengan historis atau historis hingga historis jauh lebih mudah dan lebih cepat.
sumber