2012-03-29 2 views
2

Dans mon code Java, je me sers Multimap de Goyave (com.google.common.collect.Multimap) en utilisant ceci:Problème avec Hash carte Espace

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

Ici, la clé Multimap est une partie d'une URL et de la valeur est une autre partie de l'URL (converti en un entier). Maintenant, j'affecte mon espace de tas JVM 2560 Mo (2,5 Go) (en utilisant Xmx et Xms). Cependant, il ne peut stocker que 9 millions de paires d'entiers (clé, valeur) (environ 10 millions). Maintenant, question est, je peux fournir à la JVM seulement une quantité limitée de mémoire (disons 2 Go).

Alors, quelqu'un peut me aider,

1) Y at-il une autre façon ou d'une solution au four à la maison pour résoudre ce problème de mémoire? Moyens, est-ce que Multi-Map disque/DB est une bonne solution? J'ai lu à partir de certains articles Web qu'il existe une solution basée sur DB/Disk pour résoudre ce problème. Berkley DB ou Ehcache. Quelqu'un peut-il m'informer si (ou lequel) est plus rapide?

2) Est-ce que ces disques/bases multi-cartes ont un problème de performance (je demande à la fois de stocker et de chercher)?

3) Toute idée ou information sur la manière d'utiliser ces informations.

4) Toute autre idée sera agréable pour moi. NB: Je souhaite que les solutions multimap (la clé puisse avoir plusieurs valeurs) pour le problème ci-dessus. Et je dois considérer la performance de stockage et de recherche aussi.

+0

Puis-je vous demander pourquoi vous voulez faire cela? Pour ce nombre d'éléments, vous pouvez utiliser une base de données relationnelle simple, avec un index configuré sur votre colonne clé. – Groo

+0

@Groo, j'ai plus de 100 millions de paires de valeurs clés. Et je veux un bon moyen rapide de stocker et de rechercher. – Arpssss

+0

FYI, j'ai suggéré une réponse à votre question originale qui pourrait vous permettre de continuer à utiliser le 'Multimap' de Guava avec des frais généraux réduits. –

Répondre

1

Vous ne stockez certainement pas 100 millions de paires d'objets Integer dans 2,5 Go de mémoire. Si je ne me trompe pas, un Integer utilisera au moins 16 octets de mémoire dans Oracle/Sun JVM (et l'alignement est également de 16 octets), ce qui signifie 3,2 Go de mémoire pour les Integer seuls, sans aucune structure. Avec cette taille de données, vous devez utiliser un serveur avec beaucoup de mémoire et/ou des structures de données optimisées (essayez en particulier d'éviter les wrappers de type primitif). J'ai utilisé H2 pour des tâches similaires et l'ai trouvé assez bon (il peut utiliser des fichiers mappés pour accéder au disque au lieu de lire), mais je n'ai aucune comparaison avec d'autres bibliothèques similaires.

+0

Merci. Mais, peut-il être utilisé pour stocker une clé unique avec plusieurs valeurs? Pouvez-vous élaborer un peu votre réponse en fournissant un code simple pour l'utiliser? D'après votre expérience, est-ce plus rapide? – Arpssss

+0

L'API est via JDBC (il existe aussi une API alternative plus rapide si vous avez besoin d'un grand nombre de transactions par seconde). Donc, essentiellement, vous codez comme pour une base de données SQL, ce qui signifie que plusieurs valeurs doivent être représentées par des relations et des tables multiples ou codées en une seule valeur (ce qui est généralement moins élégant). Quant à la vitesse, je ne l'ai pas comparée à la concurrence, d'autres facteurs étaient cruciaux. Ce sera certainement beaucoup plus lent qu'une carte en mémoire. Vous pouvez rechercher des structures spécialisées ou essayer de lancer les vôtres, par exemple. sur Trove (très bon, mais des cartes régulières, pas de multimap). –

+0

Petit ajout sur les 16 octets par nombre entier, comme expliqué ci-dessus: Étant donné la quantité de données dont vous parlez, vous aurez probablement une machine virtuelle 64 bits. Et un nombre entier utiliserait réellement 24 octets. Raison étant l'en-tête d'objet nécessite déjà 2 mots (2 x 64 bits), puis l'int (32 bits), mais compte tenu de l'augmentation de la mémoire et l'alignement des objets, vous obtenez 24 octets ... comme je le sais sur HotSpot. (16 sur JRockit 64 bits avec 64GB refs compressés?). De toute façon, n'importe quoi entre 3 et 4,5 Go pour 200 millions d'entiers sans aucune structure pour les contenir! –

2

JDBM3 est une bibliothèque HashMap/TreeMap (B + Tree) très rapide sur le disque et est supposée être 4x plus rapide que berkeley db. Des milliards d'enregistrements peuvent être stockés sur la carte. Il effectue une mise en cache interne afin que les opérations de carte ne ralentissent pas en raison de l'accès au disque. Il n'a pas de Multimap mais la valeur peut être un Set/List.

+0

Merci. Est-ce plus rapide que le cabinet de Kyoto? Est-ce que c'est bon pour une grande base de données (comme pour des milliards)? – Arpssss

+0

Un autre point est que: est-ce que n'importe quelle autre structure pour elle (comme B Tree ou comme cet arbre R) qui permet de dupliquer signifie des clés avec des valeurs multiples? – Arpssss

+0

Il a une structure arborescente B + avec plusieurs clés stockées sur un seul nœud d'arbre et prend en charge des milliards d'enregistrements. Le site Web dit que c'est plus lent que le cabinet Tokyo, mais c'est probablement la solution la plus rapide de pure hava – Andrejs