Ultra hızlı bir veritabanında milyar satır tarama


9

Arka fon

Yerel bir veritabanı yaklaşık 1,3 milyar benzersiz satır içerir. Her satır dolaylı olarak belirli bir enlem ve boylam (konum) ile ilişkilidir. Her satırın bir tarih damgası vardır.

Kullanım Durumu

Sorun şu şekildedir:

  1. Kullanıcı bir başlangıç ​​/ bitiş tarihi ve bir değer aralığı belirler (örn. 100 ila 105).
  2. Sistem, konuma göre gruplandırılmış olarak verilen tarihe uyan tüm satırları toplar.
  3. Sistem, bu tarihlerde, verilen değer aralığına düşme olasılığına sahip olan yerleri belirler.
  4. Sistem kullanıcıya eşleşen tüm yerleri görüntüler.

Bu bir hız ve ölçek sorunudur.

Soru

Böyle bir sistemin beş saniyeden kısa sürede kullanıcılar için sonuç almasına izin vereceğini hayal edebileceğiniz en ucuz çözüm mimarisi nedir?

Mevcut sistem

Ortam şu anda:

  • PostgreSQL 8.4 (yükseltme mümkündür; veritabanlarını değiştirmek bir seçenek değildir)
  • R ve PL / R
  • XFS'in
  • WD VelociRaptor
  • 8 GB RAM (Corsair G.Skill; 1,3 GHz)
  • Dört çekirdekli GenuineIntel 7 (2,8 GHz)
  • Ubuntu 10.10

Donanım yükseltmeleri kabul edilebilir.

Güncelleme - Veritabanı Yapısı

Milyarlarca satır aşağıdakine benzer bir tablodadır:

id | taken | location_id | category | value1 | value2 | value3
  • id - Birincil anahtar
  • alınan - Satıra atanan tarih
  • location_id - Enlem / boylam referansı
  • kategori - Verilerin açıklaması
  • değer1 .. 3 - Kullanıcının sorgulayabileceği diğer değerler

takenSütun tipik başına ardışık tarihleri ise location_idbazen her yere 1800 yılından 2010 verilerine sahip, (her yeri aynı tarih aralığında verileri olduğu gibi 77000 hakkında tarihleri, bunların çoğu çoğaltılamaz).

Yedi kategori vardır ve tablolar zaten kategoriye göre ayrılmıştır (alt tablolar kullanılarak). Her kategori ~ 190 milyon satır içerir. Yakın gelecekte, kategori başına satır sayısı bir milyarı aşacaktır.

Yaklaşık 20.000 yer ve 70.000 şehir vardır. Mekanlar enlem ve boylam ile şehirle ilişkilendirilir. Her bir konumu belirli bir şehre atamak, şehrin sınırlarını bulmak anlamına gelir, ki bu önemsiz bir görev değildir.

fikirler

Sahip olduğum bazı fikirler:

  • Veritabanını barındırmak için bir bulut hizmeti bulun.
  • Bir SSD baskın şeridi oluşturun (harika video).
  • Tüm konumları şehre göre birleştiren bir tablo oluşturun (ön hesaplama).

Teşekkür ederim!


10
Çoğu veritabanını hemen hemen ortadan kaldıran "veritabanlarını değiştirmek bir seçenek değildir". iyi şanslar!
Steven A. Lowe

1
Bu kayıtlarla tam olarak ne yaptığınız hakkında daha fazla bilgi olmadan söylemek zor. Ayrıca, 5 saniye en kötü durum mu arıyorsunuz (muhtemelen incelenen her kayıt ve sıfır konumun eşleştiği anlamına gelir)?
Guy Sirton

2
@Dave: Mevcut sistem ne kadar zaman alıyor? Mevcut sistem PostGIS kullanıyor mu ? Mı location_idbir geographyya da geometryya da ikinci bir tabloya atıfta? Is location_idkolon endeksli?
rwong

1
@ Thorbjørn & @Darknight - Fikirler bölümünde, verileri günde bir kategoriye (kategori başına) düşürecek ön hesaplamayı listeliyorum. Hesaplama yıllık olarak, hatta aylık olarak tekrarlanabilir. Başka olasılıklar olmasaydı bu benim planımdı (hesaplamalar muhtemelen haftalar alacak).
Dave Jarvis

1
@Daha fazla olasılık var, ama soru sizin için önemli olan şey. Mevcut darboğazların henüz nerede olduğunu araştırdınız mı?

Yanıtlar:


12

En önemli şey, veritabanlarını değiştiremeyeceğiniz için darboğazın belirli bir sayıda temsilci isteği için nerede olduğu konusunda kesinlikle emin olmaktır.

Tam tablo taramaları yaparsanız, uygun dizinlere ihtiyacınız vardır.

G / Ç'de beklerseniz, önbellekleme için daha fazla belleğe ihtiyacınız vardır (Jeff Atwood yakın zamanda 24 Gb sistemlerin masaüstü sistemlerde erişilebilir olduğunu belirtti).

CPU'da beklerseniz, hesaplamalarınızın optimize edilip edilemeyeceğini görmeniz gerekir.

Bu sivri bir DBA şapkası ve bir İşletim Sistemi şapkası gerektirir, ancak doğru ağacı havladığınızdan emin olmanıza değer.


Nasıl dilimleyip dilimlersiniz - her satır sadece 100 bayt alsa bile, 1,3 milyar satır = 121 GB. Tüm endeksleriniz vb. İle bunun çok daha fazla olacağından eminim. Tek bir kutuda, SSD + Tonluk koç etrafında ciddi bir donanımınız yoksa yavaş olacaksınız. Daha ucuz yol, kutular arasında ölçeklendirmektir.
Subu Sankara Subramanian

4
@Subu, dağılmak ister misin? Şimdi iki sorununuz var ...

Heh - katılıyorum :) Ama daha ucuz!
Subu Sankara Subramanian

@ Thorbjørn: Zaman ayırdığınız ve tüm yardımlarınız için teşekkür ederim. Her kategori için 25 milyon satıra ayarlanan veriyi azaltacağımı ve ardından tarihte dizinler uygulayacağımı düşünüyorum. Bu, taramayı ~ 70000 satıra indirmelidir (günlük, aralık için iki hafta sınırı ile), bu da oldukça çabuk olmalıdır.
Dave Jarvis

@Dave, hala darboğazlarınızın nerede olduğunu bilmeniz gerekiyor. Eğer yok ise bunu öğrenin sahip üzere.

4

Tabloyu tarih damgasına göre farklı ana bilgisayarlarda bulunan birden fazla parçaya bölmeye ne dersiniz? Bu yatay olarak ölçeklenebilir ve yeterli sayıda kutunuz olduğu sürece, bu kurulumların üstüne küçük bir toplama motoru yazabilirsiniz.

Tarih damgasının çok fazla değiştiğini görürseniz, konumlara göre bölümlere ayırabilirsiniz - yine yatay olarak ölçeklenebilir. (Umarım daha fazla enlem / boylam eklemezler!)


fikirler için teşekkür ederiz. Potansiyel olarak 77.066 tarih vardır ve ileriye yeni tarihler eklenecektir. Tek bir makinem var. 20.000 konum var, ancak konuma göre bölmek yardımcı olmaz çünkü analiz edilecek veriler tüm konumlara yayılır.
Dave Jarvis

ve bulut kullanımı yukarıdaki çözümden nasıl farklıdır?
Chani

Ben de öyle düşünmüştüm. Aramanın tüm bölümlerde paralel olabilmesi için bir tür yatay bölüm.
davidk01

Güne bölünme muhtemelen en yararlı olacaktır, bu da 2562 ayrı tabloya (366 gün x 7 kategori) neden olur.
Dave Jarvis

4

En kötü senaryo, tarih aralığının veritabanınızdaki tüm tarihleri ​​kapsamasıdır.

1.3 milyar kaydı okumak ve her kayıtta, girilen değerlere kıyasla, bir fiziksel makinede 5 saniyeden daha kısa sürede bir çeşit analiz yapmak istiyorsunuz. Sonuç tüm konumlar veya hiçbiri olabilir - önceden hiçbir şey bilmiyorsunuz.

Bu parametreler göz önüne alındığında, muhtemelen imkansız olduğunu söyleyebilirim.

Sabit diskinize bakın: Maksimum Sürdürülen hız 150 MB / sn'den düşük. 1,3 milyar kayıt okumak 5 saniyeden fazla sürecek. CPU açısından, 5 saniyede 1,3 milyar kayıt üzerinde herhangi bir istatistiksel analiz yapamayacaksınız.

Tek umudunuz (tm :-)), kullanıcının girdiği, aramayı daraltacak (birkaç büyüklükte) değerlere dayanan bir çeşit arama işlevi bulmaktır . Bu arama işlevini çevrimdışı olarak hesaplayabilirsiniz. Tam eşleşme kriterleri hakkında daha fazla bilgi sahibi olmadan kimsenin bunu nasıl yapacağınızı söyleyebileceğini sanmıyorum, ancak bir örnek, değer aralığını belirli bir aralığa bölmek ve bu aralıktaki tüm kayıtları veren bir arama oluşturmak olacaktır. Aralık yeterince küçük olduğu sürece gerçek iş yapabilirsiniz, örneğin kullanıcının girdiği değerle uyuşmayan girişleri budamak. Temelde zaman için alan ticareti.

Bellekteki tüm kayıtları (veya en azından önemli kısmı) tutmak mümkün olabilir. Muhtemelen 8GB'da değil. Bellek bant genişliği bile 5 saniyede her şeyi taramak için yetersiz olsa da, bu en azından disk G / Ç bölümünü ortadan kaldıracaktır. Her halükarda, bu tür uygulamaları hızlandırmak için başka bir tekniktir (önceki önerim ile birleştirin).

Bir bulut hizmeti kullandığınızdan bahsediyorsunuz. Evet, yeterli CPU ve IO kasları için ödeme yaparsanız ve veritabanınızı birçok sunucu arasında paylaştırırsanız, zorla / bölebilir ve fethedebilirsiniz.


Cevap için teşekkür ederim. Listelediğim fikirlere göre donanım yükseltmeleri göz önünde bulunduruluyor. 750 USD'nin altında bir çözüm ideal olacaktır.
Dave Jarvis

2

İkinci rwong'un şu soruya yaptığı yorum: PostgreSQL, uygun veri indeksleri türleri ve araçları (GIST indeksleri, GIN indeksleri, Postgis, Geometrik tipler), jeodata ve datetime ile ilgili verilerin çok fazla sorun olmadan bu kriterler boyunca aranabileceği şekilde sunmaktadır.

Bu kriterler hakkındaki sorularınız saniyeler alırsa, muhtemelen bu tür dizinlerin kullanılmadığı anlamına gelir. Bunları uygun şekilde araştırdığınızı doğrulayabilir misiniz?


Teşekkür ederim. Yedi alt tablo konum, tarih ve kategoride bir ağaç ağacı kullanılarak kümelenir. Geçen yıl GIN indekslerini araştırdım ve hatırladığım gibi yardım etmediler (ya da etmediler).
Dave Jarvis

2
B-Ağacı'na dayalı dizin oluşturma konumu, aradığınız aramaların türü göz önüne alındığında en ufak bir yararlı değildir. Postgis durumunda genellikle GIST anlamına gelen, gerekli işleçlerle çalışan ters bir dizine ihtiyacınız vardır. Yavaş sorgulardan birkaçını vurgulamak isteyebilirsiniz ...
Denis de Bernardy

1

PostgreSQL ve enlem / boylam verilerini kullandığınız göz önüne alındığında, kesinlikle PostGIS'i de kullanmalısınız, böylece veritabanınızı hızlandırmak için veritabanınıza bir GiST uzamsal endeksi ekleyebilirsiniz.

Sizinkinden çok daha küçük bir konfigürasyona sahip (350k satırlı) böyle bir tablo var (2 çekirdek ve zar zor 2Gb RAM), ancak aramalar bir saniyeden az sürüyor.


0

Belki Essbase gibi OLAP mimarisi ile ilişkisel bir modeli kırabilirsiniz: Essbase Wikipedia

Demek istediğim, şehir başına bir tablo oluşturmak, böylece 1000'den fazla tablo ile bitiyor. Önerdiğiniz gibi bir tablo değil, birçok. Her tabloyu tarihe ve konuma göre dizin. Birçok tablo, birçok dizin -> daha hızlı.


Not için teşekkürler. 70.000'den fazla şehir var ve birçok farklı enlem / boylam değeri belirli bir şehir alanına düşüyor.
Dave Jarvis

@Dave: Şehirler için bir voronoi diyagramı oluşturabilir ve lat / lon değerlerini mozaiklere ayırabilir misiniz? (örneğin, gelişigüzel geliyorsa, bırakın.) Ardından, arama sırasında, mozaik sorgunun enlem / boylam aralıklarına dokunan tüm şehirleri arayacaksınız. Voronoi mozaik çok yavaşsa, kare kutular (örn. 5 derece lat x 5 derece lon) denemeye değer olabilir.
rwong

0

Veritabanını barındıracak bir bulut hizmeti bulma fikriniz kadar, henüz SimpleGeo ile karşılaştınız mı? Sadece "Konum verilerini gerçekten, gerçekten hızlı bir şekilde saklamak ve sorgulamak için ayarlanmış bir Depolama hizmetindeki şeridi kesmişler" - ancak milyardan fazla satıra depolama ve sorgulama maliyeti bu yaklaşımı olanaksız hale getirebilir.


-2

bir bisikletin otoyolda gitmesini bekliyorsunuz. Şu anda sadece bu sorunu çözmek için bir çözüm arıyor, eğer 2 milyar kayıt varsa ne problemi öngörmüyor? ölçeklenebilirlik ele alınmalıdır. cevap basit kullanım nesne veritabanları. Örneğin, sistemler arası önbellek

ve inan bana sen sistemler arası değilim ;-)

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.