Basis data mana yang dapat menangani penyimpanan miliaran / trilyunan catatan?

75

Kami sedang mengembangkan alat untuk menangkap dan menganalisis data netflow, yang kami kumpulkan dalam jumlah besar. Setiap hari kami menangkap sekitar ~ 1,4 miliar catatan aliran yang akan terlihat seperti ini dalam format json:

{
   "tcp_flags": "0",
   "src_as": "54321",
   "nexthop": "1.2.3.4",
   "unix_secs": "1352234521",
   "src_mask": "23",
   "tos": "0",
   "prot": "6",
   "input": "105",
   "doctets": "186",
   "engine_type": "0",
   "exaddr": "2.3.4.5",
   "engine_id": "2",
   "srcaddr": "9.8.7.6",
   "dst_as": "12345",
   "unix_nsecs": "752265174",
   "sysuptime": "2943529544",
   "dst_mask": "24",
   "dstport": "80",
   "last": "2943523241",
   "srcport": "52672",
   "dpkts": "4",
   "output": "111",
   "dstaddr": "6.5.4.3",
   "first": "2943517993"
}

Kami ingin dapat melakukan pencarian cepat (kurang dari 10 detik) pada kumpulan data, kemungkinan besar lebih dari irisan waktu yang sempit (interval 10 - 30 menit). Kami juga ingin mengindeks sebagian besar titik data sehingga kami dapat melakukan pencarian pada masing-masing dengan cepat. Kami juga ingin memiliki tampilan data terkini ketika pencarian dieksekusi. Akan sangat bagus untuk tetap berada di dunia open source, tetapi kami tidak menentang untuk mencari solusi eksklusif untuk proyek ini.

Idenya adalah untuk menyimpan sekitar satu bulan data, yang akan ~ 43,2 miliar catatan. Perkiraan kasar bahwa setiap catatan akan berisi sekitar 480 byte data, akan sama dengan ~ 18,7 terabyte data dalam sebulan, dan mungkin tiga kali lipat dari indeks. Akhirnya kami ingin meningkatkan kapasitas sistem ini untuk menyimpan triliunan catatan.

Kami telah (pada dasarnya) mengevaluasi couchbase, cassandra, dan mongodb sejauh mungkin menjadi kandidat untuk proyek ini, namun masing-masing mengusulkan tantangan mereka sendiri. Dengan couchbase, pengindeksan dilakukan pada interval dan tidak selama penyisipan data sehingga pandangan tidak up to date, indeks sekunder cassandra tidak sangat efisien dalam mengembalikan hasil karena mereka biasanya memerlukan pemindaian seluruh cluster untuk hasil, dan mongodb terlihat menjanjikan tetapi tampaknya jauh lebih sulit untuk skala karena master / slave / sharded. Beberapa kandidat lain yang kami rencanakan untuk dievaluasi adalah elasticsearch, mysql (tidak yakin apakah ini dapat diterapkan), dan beberapa basis data relasional yang berorientasi pada kolom. Setiap saran atau pengalaman dunia nyata akan dihargai.

seseorang yang mirip
sumber
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Paul White

Jawaban:

57

Di sebuah perusahaan tempat saya bekerja, kita berurusan dengan jumlah data yang serupa (sekitar 10 TB dari data yang dapat dicari secara realtime). Kami menyelesaikan ini dengan Cassandra dan saya ingin menyebutkan beberapa ide yang memungkinkan Anda melakukan pencarian O (1) pada basis data multi TB. Ini tidak spesifik untuk Cassandra db, Anda dapat menggunakannya dengan db lain juga.

Teori

  • Shard data Anda. Tidak ada satu server pun yang dapat dipercaya dan realistis menyimpan volume data seperti itu.
  • Bersiaplah untuk kesalahan perangkat keras dan kegagalan seluruh simpul, duplikat data.
  • Mulai gunakan banyak server back-end dari awal.
  • Gunakan banyak server komoditas yang lebih murah, dibandingkan dengan server berkinerja tinggi top-end.
  • Pastikan data didistribusikan secara merata di seluruh pecahan.
  • Habiskan banyak waktu merencanakan kueri Anda. Turunkan API dari kueri dan kemudian desain tabel dengan cermat. Ini adalah tugas yang paling penting dan berkepanjangan.
  • Di Cassandra, Anda bisa mendesain kunci kolom komposit dan mendapatkan akses ke kunci itu di O (1). Luangkan waktu untuk mengerjakannya. Ini akan digunakan untuk mengakses catatan yang dicari bukan indeks sekunder.
  • Manfaatkan baris lebar. Mereka berguna untuk menyimpan acara yang dicap waktu.
  • Jangan pernah melakukan pemindaian penuh atau bahkan operasi apa pun lebih dari O (Log N) pada volume tersebut. Jika Anda memerlukan sesuatu yang lebih dari O (Log N), bongkar operasi seperti itu ke algoritma Map-Reduce.

Praktek

  • Jangan menghabiskan waktu membangun gambar OS atau menginstal server pada mesin fisik. Gunakan penyedia berbasis cloud untuk prototyping cepat. Saya bekerja dengan Amazon EC2 dan sangat merekomendasikannya untuk kesederhanaan, keandalan, dan kecepatan pembuatan prototipe.
  • Mesin Windows cenderung lebih lambat selama waktu boot dan mengambil lebih banyak sumber daya dalam keadaan Idle. Pertimbangkan untuk menggunakan OS berbasis Unix. Secara pribadi, saya menemukan server Ubuntu menjadi OS yang andal, tetapi juga ada komunitas yang cukup bagus di askubuntu
  • Pikirkan tentang jaringan, node idealnya harus dekat satu sama lain untuk memungkinkan gosip cepat dan pertukaran meta-data.
  • Jangan masuk ke kasus ekstrim: baris kolom sangat lebar atau keluarga kolom sangat panjang (tabel). Kinerja terbaik dicapai dalam batas-batas yang wajar - jika db mendukung banyak baris N menurut desain, itu tidak berarti kinerjanya baik.
  • Pencarian kami memakan waktu sekitar 3-5 detik, sebagian besar disebabkan oleh node perantara antara UI dan database. Pertimbangkan cara mendekatkan permintaan ke basis data.
  • Gunakan penyeimbang beban jaringan. Pilih yang mapan. Kami menggunakan HAProxy, yang sederhana, tetapi cepat mati. Tidak pernah punya masalah dengan itu.
  • Lebih suka kesederhanaan daripada solusi kompleks.
  • Cari solusi open-source gratis, kecuali jika Anda didukung oleh anggaran ukuran korporasi. Setelah Anda menggunakan lebih dari beberapa server, biaya infrastruktur mungkin akan sangat tinggi.

Saya tidak bekerja untuk Amazon dan tidak memiliki hubungan dengan tim HAProxy dan Ubuntu. Ini adalah pendapat pribadi daripada promosi apa pun.

oleksii
sumber
5
Saya cukup yakin pencarian O (1) tidak mungkin selain dari kasus yang sangat sepele / tidak berguna.
Fitzsimmons
2
Tolong jangan tersinggung, tapi katakan itu ke Google. O (1) pencarian dimungkinkan pada skala PB dengan desain yang cermat.
oleksii
9
@oleksii Miliaran dolar anggaran Google bukan perbandingan yang wajar untuk menggambar.
Mark Storey-Smith
4
Saya dapat menghubungkan 3 komentar sebelumnya denganO(1) search <=> unbounded storage space <=> unlimited supply of cash
ypercubeᵀᴹ
3
O (1) pencarian untuk satu rekaman dapat dilakukan dengan tabel hash linier. . Namun, ini tidak memberi Anda efisiensi dalam pencarian berurutan (untuk rentang). Untuk ini, Anda memerlukan beberapa varian struktur BTree, yaitu O (log n) untuk satu item.
ConcernedOfTunbridgeWells
41

Jika saya akan memasukkan ini ke dalam SQL Server, saya akan menyarankan tabel seperti:

CREATE TABLE tcp_traffic
(
    tcp_traffic_id bigint constraint PK_tcp_traffic primary key clustered IDENTITY(1,1)
    , tcp_flags smallint    /* at most 9 bits in TCP, so use SMALLINT */
    , src_as int        /* Since there are less than 2 billion A.S.'s possible, use INT */
    , netxhop bigint    /* use a big integer for the IP address instead of storing
                             it as dotted-decimal */
    , unix_secs bigint  
    , src_mask int      /* an assumption */
    , tos tinyint       /* values are 0-255, see RFC 791 */
    , prot tinyint      /* values are 0-255, see RFC 790 */
    , input int         /* an assumption */
    , doctets int       /* an assumption */
    , engine_type int   /* an assumption */
    , exaddr bigint     /* use a big integer for the IP address instead of storing
                             it as dotted-decimal */
    , engine_id int     /* an assumption */
    , srcaddr bigint    /* use a big integer for the IP address instead of storing
                             it as dotted-decimal */
    , dst_as int        /* Since there are less than 2 billion A.S.'s possible, use INT */
    , unix_nsecs bigint /* an assumption */
    , sysuptime bigint  /* an assumption */
    , dst_mask int      /* an assumption */
    , dstport smallint  /* ports can be in the range of 0 - 32767 */
    , [last] bigint     /* an assumption */
    , srcport smallint  /* ports can be in the range of 0 - 32767 */
    , dpkts int         /* an assumption */
    , output int        /* an assumption */
    , dstaddr bigint    /* use a big integer for the IP address instead of storing
                            it as dotted-decimal */
    , [first] bigint    /* an assumption */
);

Ini menghasilkan perkiraan total kebutuhan penyimpanan untuk tabel tunggal, tanpa indeks 5,5 TB lebih lanjut untuk 43,2 catatan beeellion (persyaratan yang Anda tentukan). Ini dihitung sebagai 130 byte untuk data itu sendiri, ditambah 7 byte per baris overhead, ditambah 96 byte per halaman overhead. SQL Server menyimpan data dalam halaman 8KB, memungkinkan untuk 59 baris per halaman. Ini sama dengan 732.203.390 halaman untuk satu bulan data.

SQL Server suka menulis ke disk dalam potongan 8-halaman (64KB), yang setara dengan 472 baris per I / O fisik. Dengan 16.203 catatan aliran yang dihasilkan setiap detik, Anda akan membutuhkan tingkat I / O minimum 34 IOps, dijamin setiap detik. Meskipun ini dengan sendirinya bukan jumlah yang besar, I / O lain dalam sistem (SQL Server dan lainnya) perlu untuk tidak pernah melanggar tingkat IOps yang diperlukan ini. Oleh karena itu, Anda perlu merancang sistem yang mampu setidaknya sekuens lebih besar IOps, atau 340 IOps berkelanjutan - Saya cenderung memperkirakan bahwa Anda membutuhkan 2 pesanan IOps lebih besar yang lebih berkelanjutan untuk menjamin throughput.

Anda akan melihat saya tidak menyimpan alamat IP dalam bentuk desimal bertitik. Ini menghemat sejumlah besar pada penyimpanan (7 byte per alamat), dan juga membuat pengindeksan, pengambilan, penyortiran, dan membandingkan alamat IP jauh, jauh lebih efisien. Kelemahannya di sini adalah Anda perlu mengubah IP desimal-desimal menjadi bilangan bulat 8-byte sebelum menyimpannya, dan kembali ke IP putus-putus-putus untuk ditampilkan. Kode untuk melakukannya adalah sepele, namun nilai baris Anda ini akan menambah jumlah overhead pemrosesan yang besar untuk setiap baris alur yang sedang diproses - Anda mungkin ingin melakukan proses konversi ini pada mesin yang secara fisik berbeda dari SQL Server.

Membahas indeks yang Anda butuhkan adalah masalah yang benar-benar terpisah karena Anda belum mencantumkan persyaratan khusus apa pun. Desain tabel ini akan menyimpan baris aliran dalam urutan fisik yang diterima oleh SQL Server, tcp_traffic_idbidang ini unik untuk setiap catatan, dan memungkinkan baris penyortiran menurut urutan rekamannya (dalam hal ini kemungkinan besar terkait satu-ke-satu hingga saat acara mengalir).

Max Vernon
sumber
4
Saya mungkin akan menggunakan binary(4)atau binary(16), masing-masing. 4 byte / baris menambah banyak penyimpanan saat dikalikan 1.000.000.000.000.
Jon Seigel
2
Dan nomor port memiliki rentang 0-65535, sehingga Anda dapat menggunakan SMALLINTtetapi harus ada rutin konversi di sana juga.
ypercubeᵀᴹ
7
@ Mr, Saya tidak setuju. Untuk melakukannya di SQL Server hanya mahal jika Anda membutuhkan HA atau hal-hal failover besar. Untuk penyimpanan data yang solid, sangat mudah untuk digunakan, SQL Server sangat bagus untuk ini. Semua sistem menjadi sangat mahal (dan rumit) jika HA diperlukan.
samsmith
2
IMO, SQL Server pasti dapat menyimpan data; Saya masih tidak yakin apakah itu solusi yang tepat untuk menyelesaikan bagian analitik proyek, terutama karena saya tidak cukup akrab dengan sistem lain yang dipertimbangkan.
Jon Seigel
3
@ MrTelly Ada dua biaya: a) Penyimpanan disk (untuk 5-8 tb, tergantung pada ruang yang digunakan oleh indeks) b) RAM (untuk mendukung permintaan, caching indeks). Untuk melakukan ini secara monolitis biasanya akan dilakukan dengan array RAID10 besar atau SAN. Namun, perhatikan bahwa sharding tentu saja dapat dilakukan, dan dapat memungkinkan Anda menggunakan logika level aplikasi untuk membuang beban kerja melalui beberapa SQL Server. Ini dapat memungkinkan Anda untuk menggunakan server murah, masing-masing dengan 0,5-2tb, dan bahkan mungkin menggunakan edisi SQL Server gratis. (Perhatikan bahwa sharding adalah konsep umum, sering dilakukan pada tingkat aplikasi, dan berlaku untuk metode kegigihan apa pun)
samsmith
5

Saya akan merekomendasikan HBase . Anda dapat menyimpan semua data mentah dalam satu atau beberapa tabel HBase, tergantung pada apa yang Anda butuhkan untuk kueri. HBase dapat menangani kumpulan data besar dan melakukan sharding otomatis melalui pemisahan wilayah.

Selain itu, jika Anda mendesain kunci baris dengan baik, Anda bisa mendapatkan sangat cepat, bahkan O (1) permintaan. Perhatikan bahwa jika Anda mengambil kumpulan data besar, itu masih akan lambat karena mengambil data adalah operasi O (n).

Karena Anda ingin melakukan kueri di setiap bidang, saya akan merekomendasikan membuat tabel unik untuk masing-masing bidang. Contoh untuk data src_address, memiliki tabel yang terlihat seperti ini:

1.2.3.4_timestamp1 : { data }
1.2.3.4_timestamp2 : { data }

Jadi, jika Anda ingin meminta semua data di 1.2.3.4 mulai dari 27 Maret 12:00 hingga 27 Maret 12:01, Anda dapat melakukan pemindaian rentang dengan baris mulai dan berhenti yang ditentukan.

IMHO, desain kunci baris adalah bagian paling penting dalam menggunakan HBase - jika Anda mendesainnya dengan baik, Anda akan dapat melakukan kueri cepat DAN menyimpan data dalam volume besar.

Suman
sumber
3

Mengatakan ini:

... kami tidak menentang mencari solusi eksklusif untuk proyek ini

Saya sarankan mempertimbangkan IBM Informix database yang + Timeseries datablade. Berlawanan dengan apa yang dikatakan beberapa orang, Informix hidup dan berjalan dengan sangat baik. Versi terakhir dirilis bulan lalu (Maret / 2013, versi 12.10).

TimeSeries seperti "plugin" (tanpa biaya) yang mampu menangani situasi seperti milik Anda.
Dan Anda dapat menggunakannya dalam produksi dengan versi gratis dari basis data Informix ( edisi Innovator-C ). (tentu saja, hanya untuk mengevaluasi bagian teknis karena versi gratis memiliki banyak sumber daya terbatas)

Di sini Anda dapat memeriksa PDF tolok ukur apa yang dapat digunakan sebagai referensi. Berikut dua presentasi dengan lebih banyak contoh teknis: panduan boneka dan tips lainnya

Saya tidak punya pengalaman pribadi dengan TimeSeries , jadi saya tidak bisa setuju itu akan menjadi "solusi", hanya saran untuk mengevaluasi.

ceinmart
sumber
2

Saya merekomendasikan kedua untuk melihat Informix TimeSeries. Literatur IBM mengklaim TimeSeries dapat menyimpan informasi semacam ini di 1/5 ruang dan melakukan 5 kali lebih cepat dari tabel relasional tradisional.

Manfaat tambahan adalah Virtual Table Interface yang dapat membuat data TimeSeries tampak seperti tabel relasional tradisional kepada pengguna akhir (menyederhanakan pengembangan aplikasi sambil tetap mendapatkan manfaat TimeSeries), HA sederhana dengan node HDR yang sekarang mendukung data TimeSeries dalam versi 12.1 dan integrasi data TimeSeries ke dalam Accelerator Gudang Informix yang dapat digunakan untuk mempercepat laporan gudang data yang rumit dan kemampuan untuk membuat prototipe solusi TimeSeries di Informix menggunakan Informix Developer atau edisi Innovator-C yang gratis.

Andrew
sumber