2009-10-08 27 views
22

Potrzebuję struktury mapy opartej na dysku, która będzie używana w aplikacji Java. Musi posiadać następujące kryteria:Poleć szybką i skalowalną mapę trwałą - Java

  1. Zdolne do przechowywania miliony rekordów (nawet miliardy)
  2. Szybka Lookup - większość operacji na Mapie będzie po prostu sprawdzić, czy klucz już istnieje. To i 1 powyżej to najważniejsze kryteria. Powinien istnieć skuteczny mechanizm buforowania pamięci dla często używanych kluczy.
  3. Trwały, ale nie musi być transakcyjny, może żyć z pewną awarią. tzn. z przyjemnością synchronizuje się z dyskiem okresowo i nie musi być transakcyjne.
  4. Zdolne do przechowywania prostych typów pierwotnych - ale nie trzeba przechowywać serializowanych obiektów.
  5. Nie trzeba jej rozprowadzać, tzn. Uruchamiać wszystko na jednym komputerze.
  6. Prosty w konfiguracji & za darmo.
  7. Brak zapytań relacyjnych wymagane

Records klawisze będą ciągi lub tęskni. Jak opisano powyżej, odczyty będą znacznie częstsze niż zapisy, a większość odczytów będzie po prostu sprawdzać, czy klucz istnieje (tj. Nie będzie musiał czytać powiązanych danych kluczy). Każdy rekord będzie aktualizowany tylko jeden raz, a zapisy nie zostaną usunięte.

Obecnie używam Bdb JE, ale szukam innych opcji.


Aktualizacja

od tego czasu poprawy wydajności zapytań na mojego istniejącej konfiguracji BDB poprzez zmniejszenie uzależnienia od kluczy wtórnych. Niektóre zapytania wymagały sprzężenia na dwóch pomocniczych kluczach, a łącząc je w klucz złożony, usunąłem poziom pośredni w wyszukiwaniu, co przyspiesza ładowanie.

+0

Jedną z opcji, którą rozważam, jest zmiana sposobu korzystania z istniejącej implementacji BDB. Obecnie mam jedną dużą bazę danych dla wszystkich moich rekordów. Powinienem jednak móc podzielić dane na zestawy i mieć jedną bazę danych na zbiór - jeśli wiem, że w dowolnym momencie będę potrzebował tylko dostępu do niektórych zestawów, to mogę zamknąć te zestawy, których nie używam, co powinno pomóc mi bardziej efektywnie zarządzać danymi. – Joel

+0

użyłem bdb je. dla twoich kryteriów, to jest świetne dopasowanie. Byłem jednak bardzo rozczarowany jej kruchością i nie polecałem go do celów produkcyjnych. każda czkawka w procesie java spowodowała konieczność ponownego uruchomienia podsystemu bdb, blech! – james

+0

Nie jestem pewien, co masz na myśli przez "kruchość" BDB JE. BDB JE jest skalowalny dla Terabajtów danych i cały czas używam go w systemach produkcyjnych. To cudowny kawałek techniki. – jasonmp85

Odpowiedz

3

Najprawdopodobniej skorzystam z lokalnej bazy danych. Jak na przykład Bdb JE lub HSQLDB. Czy mogę zapytać, co jest nie tak z tym podejściem? Musisz mieć jakiś powód, by szukać alternatyw.

W odpowiedzi na komentarze: Jako wydajność problemu i myślę, że już używasz JDBC do obsługi tego, warto spróbować przetestować HSQLB i przeczytać rozdział o Memory and Disk Use.

+1

+1 zgadzam się. Chciałbym użyć zwykłego DB i napisać ładne API dla wymagań, aby backend można było łatwo zmienić. – flybywire

+0

Gdy Bdb osiąga granice tego, co może być buforowane w pamięci, stwierdzam, że spowalnia to niedopuszczalnie. Zdarza się to zazwyczaj po około 1 mm wkładkach. – Joel

+0

Co powiesz na HSQLDB? Zamierzam zgadnąć, że obaj są JDBC, więc powinieneś być w stanie wciągnąć go bez modyfikowania znacznej części istniejącego kodu. Warto przeczytać: http://hsqldb.org/doc/2.0/guide/deployment-chapt.html#deployment_mem_disk-sect –

0

Myślę, że może z łatwością spełnić wszystkie Twoje wymagania.

1

SQLite to robi. Napisałem opakowanie do używania go z Javy: http://zentus.com/sqlitejdbc

Jak wspomniałem w komentarzu, z powodzeniem użyłem SQLite z gigabajtami danych i tabelami setek milionów wierszy. Jeśli dobrze wymyślisz indeksowanie, jest to bardzo szybkie.

Jedynym problemem jest interfejs JDBC. W porównaniu z prostą mapą HashMap, jest niezgrabny. Często kończę pisanie JDBC-wrapper dla konkretnego projektu, który może dodać do wielu kodu na płycie głównej.

+0

Poważnie wątpię, że sqlite skaluje się do tak wielu rekordów. –

+1

Z powodzeniem wykorzystałem SQLite z gigabajtami danych i tabelami setek milionów wierszy. Jeśli dobrze wymyślisz indeksowanie, jest to bardzo szybkie. –

0

JBoss (tree) Cache to doskonała opcja. Możesz go używać samodzielnie od JBoss. Bardzo wytrzymały, wydajny i elastyczny.

+1

Czy jest trwały? –

1

Znalazłem Tokyo Cabinet jako proste uporczywe Hash/Map i szybkie do skonfigurowania i użycia.

Ta skrócona przykład wzięty z the docs, pokazuje, jak łatwo jest, aby zapisać i odzyskać dane z przetrwałym mapie:

// create the object 
    HDB hdb = new HDB(); 
    // open the database 
    hdb.open("casket.tch", HDB.OWRITER | HDB.OCREAT); 
    // add item 
    hdb.put("foo", "hop"); 
    hdb.close(); 
19

JDBM3 robi dokładnie to, czego szukasz. Jest to biblioteka map dyskowych z bardzo prostym API i wysoką wydajnością.

UPDATE

Ten projekt teraz przekształciła MapDB http://www.mapdb.org

6

Można spróbować Java Kroniki z http://openhft.net/products/chronicle-map/ Kronika mapa jest duża wydajność, off-kupie, klucz-wartość, w pamięci, trwało magazyn danych. Działa jak standardowa java map

+1

Podczas gdy ten link może odpowiedzieć na pytanie, lepiej umieścić tutaj istotne części odpowiedzi i podać link do odsyłacza. Odpowiedzi dotyczące linków mogą stać się nieprawidłowe, jeśli strona z linkami się zmieni. – Cyclonecode

+2

@krister - Myślę, że jest to przypadek, w którym mniej niż idealne pytanie wygenerowało odpowiedź, która naruszyła zasady SO (odpowiedź była dobrą odpowiedzią na pytanie). W tym przypadku jestem skłonny poruszać się przeciwko temu pytaniu. – jww

2

Na dzień dzisiejszy użyłbym albo MapDB (synchronizacja oparta na plikach/synchronizacja lub asynchronizacja) lub Hazelcast. W późniejszym czasie będziesz musiał zaimplementować własne uporanie, tj. Poparte przez RDBMS poprzez implementację interfejsu Java. OpenHFT kronika może być inną opcją. Nie jestem pewien, jak działa tam wytrwałość, odkąd nigdy jej nie użyłem, ale twierdzenie, że mam. OpenHFT jest całkowicie wyłączoną stertą i pozwala na częściowe aktualizacje obiektów (prymitywów) bez (de-) serializacji, co może być zaletą wydajności.

UWAGA: Jeśli potrzebujesz dysku mapowego opartego na problemach z pamięcią, najłatwiejszą opcją jest MapDB. Hazelcast może być wykorzystywany jako pamięć podręczna (rozproszona lub nie), która pozwala eksmitować elementy z sterty po czasie lub rozmiarze. OpenHFT jest off-stosem i może być brane pod uwagę, jeśli potrzebujesz tylko trwałości dla restartów jvm.