2012-03-29 10 views
2

In meinem Java-Code, ich bin mit Guava der Multimap (com.google.common.collect.Multimap) durch diese mit:Ausgabe mit Hash Karte Raum

Multimap<Integer, Integer> Index = HashMultimap.create() 

Hier ist Multimap Schlüssel ein Teil einer URL und Wert ein anderer Teil der URL ist (umgewandelt in eine Ganzzahl). Jetzt weise ich meinen JVM 2560 Mb (2.5 GB) Heapspeicher zu (mit Xmx und Xms). Es kann jedoch nur 9 Millionen solcher (Schlüssel, Wert) Paare von ganzen Zahlen (ca. 10 Millionen) speichern. Nun, Problem ist, ich kann JVM nur eine begrenzte Menge an Speicher zur Verfügung stellen (sagen wir 2 GB).

Also, kann mir jemand helfen,

1) Gibt es eine andere Art und Weise oder hausgebackenem Lösung dieses Speicherproblem zu lösen? Bedeutet, ist Disk/DB Based Multi-Map eine nette Lösung? Ich lese aus einigen Web-Artikeln, dass es eine DB/Disk-basierte Lösung gibt, um dieses Problem zu lösen. Berkley DB oder Ehcache. Kann mir jemand mitteilen, ob (oder welcher) schneller ist?

2) Ist diese Disk/DB Based Multi-Map Leistungsproblem (Ich frage nach Speichern und Suchen)?

3) Irgendeine Idee oder Information wie man diese in Kürze benutzt.

4) Jede andere Idee wird nett für mich sein.

Hinweis: Ich möchte Multimap (Schlüssel können mehrere Werte haben) Lösungen für das oben genannte Problem. Und ich muss die Leistung des Lagerns und Suchens auch berücksichtigen.

+0

Darf ich fragen, warum Sie das tun möchten? Für diese vielen Elemente können Sie eine einfache relationale Datenbank mit einem Index verwenden, der für Ihre Schlüsselspalte konfiguriert ist. – Groo

+0

@Groo, ich habe mehr als 100 Millionen Schlüsselwertpaare. Und ich möchte einen schönen schnellen Weg zum Speichern und Suchen. – Arpssss

+0

FYI, ich schlug eine Antwort auf Ihre ursprüngliche Frage vor, mit der Sie Guavas "Multimap" mit reduziertem Platzaufwand weiter verwenden können. –

Antwort

1

Sie werden sicherlich nicht 100 Millionen Paare Integer Objekte in 2,5 GB Speicher speichern. Wenn ich mich nicht irre, wird ein Integer mindestens 16 Bytes Speicher in Oracle/Sun JVM verwenden (und die Ausrichtung ist auch 16 Bytes), was bedeutet 3,2 GB Speicher für die Integer s allein, ohne jede Struktur.

Mit dieser Datengröße sollten Sie auf jeden Fall mit etwas gehen, was vom Datenträger unterstützt wird, oder einen Server mit viel Speicher und/oder optimierten Datenstrukturen verwenden (insbesondere primitive Wrapper vermeiden). Ich habe H2 für ähnliche Aufgaben verwendet und fand es ziemlich gut (es kann zugeordnete Dateien verwenden, um auf die Festplatte statt Lesezugriffe zuzugreifen), aber ich habe keinen Vergleich mit anderen ähnlichen Bibliotheken.

+0

Danke. Kann es aber verwendet werden, um einen einzelnen Schlüssel mit mehreren Werten zu speichern? Können Sie Ihre Antwort ein wenig erläutern, indem Sie einfachen Code für die Verwendung bereitstellen? Aus Ihrer Erfahrung ist es schneller? – Arpssss

+0

Die API ist über JDBC (es gibt eine alternative, schnellere API, auch wenn Sie eine große Anzahl von Transaktionen pro Sekunde benötigen). Sie kodieren also im Wesentlichen für eine SQL-Datenbank, was bedeutet, dass mehrere Werte entweder durch Relationen und mehrere Tabellen repräsentiert werden müssen oder irgendwie zu einem einzigen Wert (der normalerweise weniger elegant ist) kodiert werden. Was die Geschwindigkeit angeht, habe ich sie nicht mit der Konkurrenz verglichen, andere Faktoren waren entscheidend. Es wird sicherlich viel langsamer als eine In-Memory-Karte sein. Sie könnten nach spezialisierten Strukturen suchen oder versuchen, Ihre eigenen zu rollen, z. auf Trove (sehr gut, aber normale Karten, keine Multimap). –

+0

Kleine Addition auf den 16 Bytes pro Integer, wie oben richtig erklärt: Angesichts der Menge an Daten, über die Sie sprechen, erhalten Sie wahrscheinlich eine 64-Bit-VM. Und ein Integer würde tatsächlich 24 Bytes verwenden. Da der Object-Header bereits 2 Wörter (2 x 64 Bit) und dann den Int (32 Bit) benötigt, ergibt sich bei der Speichererweiterung und der Objektausrichtung eine Länge von 24 Byte ... Die Objektausrichtung ist 8 Bit lang wie ich es auf HotSpot weiß. (16 auf JRockit 64 Bits mit 64 GB komprimierten Refs?). Wie auch immer, alles zwischen 3 und 4,5 GB für 200 Millionen Integer ohne irgendeine Struktur, um sie zu enthalten! –

2

JDBM3 ist eine sehr schnelle HashMap/TreeMap (B + Tree) -Bibliothek und wird angeblich 4x schneller als berkeley db. Milliarden von Datensätzen können in der Karte gespeichert werden. Es wird intern zwischengespeichert, sodass die Kartenoperationen aufgrund des Festplattenzugriffs nicht langsamer werden.

DB db = DBMaker.openFile(fileName).make(); 
Map<Integer,Integer> map = db.createHashMap("mapName"); 
map.put(5, 10); 
db.close() 

Es hat keine Multimap, aber der Wert kann eine Menge/Liste sein.

+0

Danke. Ist es schneller als Kyoto Kabinett? Ist es schön für eine große Datenbank (wie für Milliarden)? – Arpssss

+0

Ein anderer Punkt ist: Gibt es eine andere Struktur dafür (wie B Tree oder wie dieser R Tree), die Duplikate bedeutet Schlüssel mit mehreren Werten? – Arpssss

+0

Es hat eine B + Baumstruktur mit mehreren Schlüsseln, die auf einem einzelnen Baumknoten gespeichert sind und Milliarden von Datensätzen unterstützen. Die Website sagt, das ist langsamer als Tokyo Kabinett, aber es ist wahrscheinlich die schnellste reine Hava-Lösung – Andrejs

Verwandte Themen