Zaman serisi verilerini saklama, ilişkisel veya ilişkisiz?


185

SNMP kullanarak (muhtemelen) 5 dakikalık aralıklarla CPU kullanımı, disk kullanımı, sıcaklık vb. Gibi çeşitli metriklerle ilgili verileri toplayan bir sistem oluşturuyorum. Nihai amaç, sistemin bir kullanıcısına zaman serisi grafikleri şeklinde görselleştirmeler sağlamaktır.

Geçmişte RRDTool kullanmaya baktım, ancak yakalanan verileri süresiz olarak saklamanın projem için önemli olduğu için reddedildim ve yakalanan verilere daha yüksek seviye ve daha esnek erişim istiyorum. Yani sorum gerçekten:

Daha da iyisi, grafik için verileri sorgularken performansla ilgili bir ilişkisel veritabanı (MySQL veya PostgreSQL gibi) veya ilişkisel olmayan veya NoSQL veritabanı (MongoDB veya Redis gibi).

ilişkisel

İlişkisel bir veritabanı göz önüne alındığında, data_instancestüm cihazlar için ölçülen her metrik için yakalanan her veri örneğini, aşağıdaki alanlarla depolanacak bir tablo kullanacağım :

Alanlar: id fk_to_device fk_to_metric metric_value timestamp

Belirli bir cihazda belirli bir metrik için bir grafik çizmek istediğimde , diğer cihazları filtreleyen bu tekil tabloyu ve bu cihaz için analiz edilen diğer metrikleri sorgulamalıyım :

SELECT metric_value, timestamp FROM data_instances
    WHERE fk_to_device=1 AND fk_to_metric=2

Bu tablodaki satır sayısı:

d * m_d * f * t

burada dsayısıdır cihazlar , m_dbiriktiricidir metrik değerlerin sayısı , tüm cihazlar için kaydedilen fbir frekans veri için sıralı olarak çağırıldığında ve edildiği ttoplam miktarı zaman , sistem verilerini toplamak olmuştur.

Bir yıl boyunca her 5 dakikada bir 3 cihaz için 10 ölçüm kaydeden bir kullanıcı için 5 milyonun biraz altında kayıt olurdu .

endeksleri

Dizinler olmadan fk_to_deviceve fk_to_metricsürekli olarak genişleyen bu tablo çok fazla zaman alacaktır. Bu nedenle, yukarıda belirtilen alanların endekslenmesi ve ayrıca timestamp(yerelleştirilmiş periyotlarla grafikler oluşturmak için) bir gerekliliktir.

İlişkisel Olmayan (NoSQL)

MongoDB bir koleksiyon kavramına sahiptir, tabloların aksine bunlar kurulum olmadan programlı olarak oluşturulabilir. Bunlarla, her bir cihaz için veri depolamasını, hatta her cihaz için kaydedilen her bir metriği bölümlere ayırabilirim.

NoSQL ile hiçbir deneyime sahip ve indeksleme gibi herhangi bir sorgu performans artırıcı özellikler sağlayıp sağlamadıklarını bilmiyorum, ancak önceki paragraf, verilerin NoSQL altında depolandığı yapıda geleneksel ilişkisel sorgu çalışmalarının çoğunu yapmayı öneriyor.

Kararsız

Doğru endekslemeye sahip ilişkisel bir çözüm, yıl içinde taramayı azaltır mı? Yoksa NoSQL yaklaşımlarının koleksiyon tabanlı yapısı (saklanan verilerdeki zihinsel modelimle eşleşen) fark edilir bir fayda sağlıyor mu?


1
Çok geçerli bir soru, ben kendimi ilişkisel DB aslında hiyerarşik (SNMP yapısı) bir veri yapısı depolamak için doğru yolu olup olmadığını düşündüm. Bazen önemsiz verileri bile almak için bir sorgu yazdığımda, sorgu aşırı karmaşık, verilerin kendi olmayan bir forma karıştırılması gerektiğini hissettim. Örneğin, ifnames ve indekslerini eşleştirmek, her ikisi de aynı ebeveyn yağının çocukları olmak üzere, önemsiz bir görevdir. Ancak ilişkisel DB'de depolanma şekli, orijinal yapısı ile ilgili değildir ve hiyerarşik bir şekilde saklamanın daha verimli olduğunu hissediyorum.
Benny

"Bir yıl boyunca her 5 dakikada bir 3 cihaz için 10 ölçüm kaydeden bir kullanıcı için 5 milyonun biraz altında kayıt olurdu." 10 * 3 * 365 * 24 * 12 sadece 3 milyona eşit değil, sadece 5 milyonun altında değil mi?
Mathieu Borderé

Yanıtlar:


152

Kesinlikle İlişkisel. Sınırsız esneklik ve genişleme.

Hem konsept hem de uygulamada iki düzeltme, ardından bir yükseklik.

Düzeltme

  1. "Gereksiz verileri filtrelemek" değildir; o olduğu tek seçerek gereken verileri. Evet, elbette, WHERE yan tümcesinde belirtilen sütunları destekleyen bir Dizininiz varsa, çok hızlıdır ve sorgu tablonun boyutuna bağlı değildir (16 milyar satırlık bir tablodan 1.000 satır yakalamak anlıktır) .

  2. Tablonuzda ciddi bir engel var. Açıklamanız göz önüne alındığında, gerçek PK (Cihaz, Metrik, DateTime). (Lütfen TimeStamp demeyin, bu başka bir şey anlamına gelir, ancak bu küçük bir konudur.) Satırın benzersizliği şu şekilde tanımlanır:

       (Device, Metric, DateTime)
    
    • IdSütun, hiçbir şey yapmaz tamamen ve tamamen gereksiz olduğunu.

      • Bir Idsütun hiçbir zaman Anahtar değildir (İlişkisel veritabanında yasaklanan yinelenen satırlar başka yollarla engellenmelidir).
      • IdSütun besbelli hızını engelleyen ek Index gerektirir INSERT/DELETEve kullanılan disk alanı ekler.

      • Bundan kurtulabilirsiniz. Lütfen.

Yükseklik

  1. Şimdi engeli kaldırdığınıza göre, onu tanımamış olabilirsiniz, ancak tablonuz Altıncı Normal Formdadır. PK'de sadece bir Endeks ile çok yüksek hız. Anlamak için, okumak bu cevabı gelen Altıncı Normal Form nedir? ilerliyoruz.

    • (Ben sadece bir dizin var, üç değil; SQL olmayanlar üzerinde üç endekse ihtiyacınız olabilir).

    • IdTabii ki aynı tablo var ( "anahtar" olmadan ). Ek bir sütunum var Server. Birden fazla müşteriyi uzaktan destekliyorum.

      (Server, Device, Metric, DateTime)

    Tablo, tam olarak aynı SQL kodunu (evet, hücreleri değiştir) kullanarak verileri Pivotlamak için kullanılabilir (yani Devicesüstte ve Metricsaltta veya döndürülebilir). Tabloyu müşterilerin sunucu performansları için sınırsız çeşitlilikte grafikler ve çizelgeler oluşturmak için kullanıyorum.

    • İstatistik Veri Modelini izleyin .
      (Satır içi için çok büyük; bazı tarayıcılar satır içi yükleyemez; bağlantıyı tıklayın. Ayrıca eski demo sürümü, açık nedenlerden dolayı size ticari ürün DM'sini gösteremiyorum.)

    • Tek bir SELECT komutu kullanarak müşteriden bir ham izleme istatistikleri dosyası aldıktan sonra altı tuş vuruşunu Bu gibi Grafikler üretmeme izin veriyor . Karıştır ve eşleştir; OS ve sunucu aynı grafikte; çeşitli Pivotlar. Tabii ki, istatistik matrisleri ve dolayısıyla grafikler için bir sınır yoktur. (Müşterinin tür izniyle kullanılır.)

    • İlişkisel Veritabanlarını Modelleme Standardına aşina olmayan okuyucular, IDEF1X Notasyonu yararlı.

Bir şey daha

Son olarak, SQL bir IEC / ISO / ANSI Standardıdır. Ücretsiz aslında SQL olmayan; Standardı sağlamazlarsa SQL terimini kullanmak hilelidir. "Ekstralar" sağlayabilirler, ancak temelleri yoktur.


1
@PerformanceDBA, önerilen şemayı 1 dakikalık sıklıkta ~ 3 milyon önlemi işlemek için kullanır mısınız? PK'yi böyle bir masa için nasıl sipariş edersiniz? Device, Metric, DateTime parçalanma oluşturmaz ve RDBMS'yi birçok sayfa bölünmesine zorlamaz mı? Bunun yerine DateTime'ı ilk sıraya koymak parçalanmayı azaltacaktır (sipariş edilen zaman eklerini varsayıyorum) ama okumaları daha da kötüleştirir.
marcob

1
@Buchi. Sybase ASE kullanıyorum. Ancak bu bir platform sorunu değil (yüksek platformlar, büyüklük sıralarının alt uçtan daha iyi olduğu performansı sağlar; üç büyüklük sırası Oracle'dan daha iyi, ancak mesele bu değil), grafiğin tablodan kurulması " herhangi bir platformda çalışır. İş için doğru aracı kullanın. RDBMS bir grafik aracı değil, bir veritabanı aracıdır. gnuplot, Apple Numbers (ya da on kat daha fazla ödeme yapmak istiyorsanız, yarı yarıya, MS Excel) veritabanı araçları değil grafik araçlarıdır. Bugünlerde sonuç üretmek için araç katmanları kullanıyoruz, monolit bir dinozor.
PerformanceDBA

1
@marcob. Sorunuz iyi bir soru, ancak yorumlarda doğru cevaplanamıyor. Yeni bir soru açar ve bana e-posta gönderirseniz (profile git), ben cevaplayacağım. Burada hızlı cevap için. (1) ~ 3 milyon Metrik. Harika, ne kadar fazla olursa, INSERT puanlarını güzelce yayarsa, sizinki de son sayfadaki çakışmaları garanti eder. Sunucu çok iş parçacıklı, değil mi? Tabloyu bölümlere ayırın. FILLFACTOR kullanın ve kesici uçlar için boşluk bırakın ve sayfa bölünmelerini önleyin. (2) ~ 3 Frez, Metriklerin Normalleştirilmediğini belirtir, eğer bunu düzeltirseniz daha da hızlı olacaktır.
PerformanceDBA

1
@marcob. (3) Verilen indeksi hassas bir şekilde uçları yük altında yaymak için kullanıyorum, bu da çatışma olmaması. (4) Bu nedenle, yöntemim SELECT'lerde çakışma ve yüksek performans olmadan her iki eki de elde ediyor .
PerformanceDBA

2
@Loic. Neden bir SQL platformuna yatırım yapan (veri; kod), zaman serisi verilerini kolayca ve çok yüksek performansla (yanıtta ayrıntılandırıldığı gibi) işleyen herkes, SQL olmadan bir TSDB'ye geçecektir; zaman serisi verileri dışında herhangi bir şey için bilinmeyen hız? Neden aşan bir gereklilik olan herkes zaman serisi-verileri okunur olurdu değil bir SQL platformu kullanmak? Zihin şaşkına döner. TSDB hızlı İlişkisel daha sadece veri bir db depolanan ancak zaman üzgün durumda değil ilişkisel olarak normalize. Örneğin. ne zaman Idsütunlar "tuşları" olarak, kullanılan bulunmaktadır. "Teorisyenler" tarafından tavsiye edildiği gibi.
PerformanceDBA

21

Yukarıdaki cevapları çok ilginç buldum. Burada birkaç nokta daha eklemeye çalışıyorum.

1) Veri yaşlanması

Zaman serisi yönetiminin genellikle yaşlanma politikaları oluşturması gerekir. Tipik bir senaryo (örn. Sunucu CPU'sunu izleme) aşağıdakilerin saklanmasını gerektirir:

  • Kısa süreli 1 sn ham numuneler (örneğin 24 saat)

  • 5 dakikalık detay agrega örnekleri orta bir süre (örn. 1 hafta)

  • Bununla ilgili 1 saatlik ayrıntı (ör. 1 yıla kadar)

İlişkisel modeller, uygun şekilde yönetilmesini mümkün kılsa da (şirketim on binlerce veri serisine sahip bazı büyük müşteriler için büyük merkezi veritabanları uyguladı), yeni veri depoları türü, keşfedilecek ilginç işlevler ekliyor:

  • otomatik veri temizleme (bkz. Redis 'EXPIRE komutu)

  • çok boyutlu toplamalar (örneğin, harita azaltma işleri a-la-Splunk)

2) Gerçek zamanlı koleksiyon

Daha da önemlisi, bazı ilişkisel olmayan veri depoları doğası gereği dağıtılır ve etkin noktaların oluşturulması sırasında RDBMS ile ilgili bir sorun olabilecek çok daha verimli bir gerçek zamanlı (veya gerçek zamanlıya yakın) veri toplanmasına izin verir (ekleme sırasında dizin oluşturmayı yönetme) tek bir tablo). RDBMS alanındaki bu sorun genellikle toplu içe aktarma prosedürlerine (geçmişte bu şekilde yönettik) geri dönerken, sql teknolojileri büyük gerçek zamanlı toplama ve toplamada başarılı olmuştur (örneğin önceki cevaplarda bahsedilen Splunk'a bakınız) .


7

Tablonuzda tek bir tabloda veri var. Dolayısıyla ilişkisel ve ilişkisel olmayan bir soru söz konusu değildir. Temel olarak çok sayıda ardışık veri okumalısınız. Şimdi bir yıllık değeri depolamak için yeterli RAM'iniz varsa Redis / MongoDB vb.

Çoğunlukla NoSQL veritabanları, birden fazla disk erişiminden kaçınmak için verilerinizi diskte aynı konumda ve sıkıştırılmış biçimde depolar.

NoSQL, cihaz kimliği ve metrik kimliği üzerinde endeksi oluşturmakla aynı şeyi yapar, ancak kendi yolunda. Veritabanında bunu yapsanız bile dizin ve veriler farklı yerlerde olabilir ve çok fazla disk G / Ç olacaktır.

Splunk gibi araçlar, zaman serisi verilerini depolamak için NoSQL arka uçlarını kullanıyor ve daha sonra toplama oluşturmak için harita azaltma özelliğini kullanıyor (daha sonra istediğiniz şey olabilir). Bence insanlar benzer kullanım durumları için zaten denedikleri için NoSQL kullanmak bir seçenektir. Ancak bir milyon satır veritabanını taramaya getirecek (belki de iyi donanım ve uygun yapılandırmalarla değil).


1
Tablonun nasıl "normalleştirilmediğini" açıklayabilir misiniz? Marcus tabloda bir hata var, ancak bu bir normalleştirme hatası değil.
PerformanceDBA

kendimi düzeltirim, tablolar geleneksel anlamda normalleştirilir. Kullanım durumunun tüm verileri burada tek bir tabloda tutması anlamında normalleştirmeyi kastetmiştim.
Ravindra

4

Bir dosya oluşturun, 1_2.data olarak adlandırın. fikir mi? ne elde edersiniz:

  • Her veri noktası için fk_to_device ve fk_to_metric değerini tekrarlamanız gerekmediğinden% 50'ye kadar alan tasarrufu sağlarsınız.
  • Daha fazla yer kazanırsınız çünkü herhangi bir endekse ihtiyacınız yoktur.
  • Verileri ekleyerek (timestamp, metric_value) çiftlerini dosyaya kaydedin, böylece zaman damgasına göre ücretsiz bir sipariş alabilirsiniz. (kaynaklarınızın bir cihaz için sıra dışı veri göndermediğini varsayarak)

=> Zaman damgasına göre sorgular inanılmaz hızlı çalışır çünkü dosyada okunacak doğru yeri bulmak için ikili aramayı kullanabilirsiniz.

daha da optimize isterseniz dosyalarınızı böyle bölmeyi düşünmeye başlayın;

  • 1_2_january2014.data
  • 1_2_february2014.data
  • 1_2_march2014.data

veya http://kx.com adresinden kdb + kullanın çünkü tüm bunları sizin için yapıyorlar :) sütun odaklı size yardımcı olabilir.

Bulut tabanlı sütun odaklı bir çözüm ortaya çıkıyor, bu yüzden şuna bir göz atmak isteyebilirsiniz: http://timeseries.guru


Konuyla ilgili bir blog yazısı yazdım. google translate ile yararlı bulabilirsiniz: blog.michaelwittig.info/die-spaltenorientierte-datenbank-kdb
hellomichibye

3

GPL paketlerine bakıyorsanız, RRDTool bakmak için iyi bir pakettir . Zaman serisi verilerinin saklanması, çıkarılması ve grafiklerinin oluşturulması için iyi bir araçtır. Kullanım durumunuz tam olarak zaman serisi verilerine benziyor.


2

Bu ApiAxle'de çözmemiz gereken bir problem. Biz bir blog yazısı yazdı bunu REDIS kullanarak nasıl yaptığını üzerinde. Çok uzun zamandır dışarıda değil ama etkili olduğunu kanıtlıyor.

Ben de mükemmel başka bir proje için RRDTool kullandım .


2

Bu tür bir sorunun cevabının temel olarak Veritabanınızın depolama alanını kullanma şekli hakkında dönmesi gerektiğini düşünüyorum. Bazı Veritabanı sunucuları RAM ve Disk kullanır, bazıları sadece RAM kullanır (isteğe bağlı olarak kalıcılık için Disk), vb. fiziksel konum). Zaman çizelgeleri depoları için, çoğu durumda iş yükü şöyledir: Okumalar sütun tabanlıyken (çoğu durumda belirli bir sütundan bir metriği temsil eden bir dizi veri okumak istiyorsunuz)

Columnar Databases buldum (google, bulacaksınız MonetDB, InfoBright, parAccel, vb) zaman serisi için müthiş bir iş yapıyor.

Kişisel olarak biraz geçersiz olduğunu düşündüğünüz soruya gelince (NoSQL - IMO hata terimini kullanan tüm tartışmalar gibi): Bir yandan SQL konuşabilen bir veritabanı sunucusu kullanabilirsiniz, böylece herkes birçok kişi için SQL'i bilir. yıllar ve bu dil veri sorguları için tekrar tekrar mükemmelleştirilmiştir; ancak yine de RAM, CPU Önbelleği ve Diski Sütun odaklı bir şekilde kullanır, bu da çözümünüzü en uygun Time Serisi yapar


2

5 Milyonlarca satır, günümüzün sağanak verileri için bir şey değildir. Verilerin sadece birkaç ay içinde TB veya PB'de olmasını bekleyin. Bu noktada RDBMS göreve ölçeklenmez ve NoSql veritabanlarının doğrusal ölçeklenebilirliğine ihtiyacımız vardır. Performansı artırmak için daha fazla sütun ve daha az satır kavramı ekleyerek, verileri depolamak için kullanılan sütunsal bölüm için performans elde edilir. HBASE veya MapR_DB vb. Üzerinde yapılan Açık TSDB çalışmasından yararlanın.


"RDBMS göreve ölçeklenmiyor" - neden olmasın? code.facebook.com/posts/190251048047090/…
Zathrus Writer

1

Benzer gereksinimlerle düzenli olarak karşılaşıyorum ve son zamanlarda bu tür verileri toplamak ve depolamak için Zabbix'i kullanmaya başladım. Zabbix'in kendi grafik yeteneği vardır, ancak verileri Zabbix'in veritabanından ayıklamak ve istediğiniz gibi işlemek kolaydır. Zabbix'i daha önce kontrol etmediyseniz, bunu yapmaya zaman ayırmaya değer olabilir.


Evet, Zabbix güzel ve zaten SNMP izleme ile entegre oluyor. Zabbix, MySQL veya PostgreSQL kullanabilir ve Ubuntu'daki kutudan az çok çalışır.
Dirk Eddelbuettel

Teşekkürler, Zabbix ve diğer birçok SNMP aracı hakkında bilgim var. Ancak bu projeyi eğitim süreci olarak, burada tartışılan konuda ve diğer birçok konuda geliştiriyorum. Gerçi iyi bir nokta!
Marcus Whybrow

0

Zaman serisi veritabanına bakmalısınız . Bu amaçla yaratıldı.

Bir zaman serisi veritabanı (TSDB), zaman serisi verilerini, zamana göre endekslenen sayı dizilerini (tarih / saat veya tarih aralığı) işlemek için optimize edilmiş bir yazılım sistemidir.

Popüler zaman serisi veritabanı InfluxDB örneği


Şimdi bu listeye timescaledb ekle
PirateApp
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.