J'ai créé une application vendue à des clients, dont certains sont des fabricants de matériel avec des contraintes fixes (CPU lent). L'application doit être en Java, de sorte qu'elle puisse être facilement installée en tant que package unique.
L'application est multithread et conserve les enregistrements audio. Dans ce cas particulier, tout ce que nous avons est INSERT SOMEDATA FOR RECORD, chaque enregistrement représentant un fichier audio (et cela peut être fait par différents threads), puis plus tard, nous avons SELECT SOMEDATA WHERE IDS in (x, y, z) par un thread unique, puis la troisième étape consiste à SUPPRIMER toutes les données de ce tableau.
La principale contrainte est cpu, seule cpu lente. La mémoire est également une contrainte, mais uniquement en ce que l'application est conçue de manière à pouvoir traiter un nombre illimité de fichiers, et donc même si elle avait beaucoup de mémoire, elle finirait par s'épuiser si tout était stocké en mémoire plutôt que d'utiliser le disque.
Dans mon application Java), j'ai commencé à utiliser la base de données H2 pour stocker toutes mes données. Mais le logiciel doit fonctionner sur des serveurs CPU simples et lents, donc je veux réduire les cycles de processeur utilisés, et un la zone que je veux regarder à nouveau est la base de données.
Dans de nombreux cas, j'insère des données dans la base de données simplement dans le but de garder les données hors du tas, sinon je manquerais de mémoire, puis plus tard, nous récupérons les données, nous n'avons jamais à METTRE À JOUR les données.
J'ai donc envisagé d'utiliser un cache comme ehCache mais cela pose deux problèmes:
Quelle est une alternative qui résout ces problèmes?
Les bases de données relationnelles comme Oracle ont des décennies (41 ans), pouvez-vous imaginer combien de cycles CPU étaient disponibles à l'époque? Basé sur des recherches de 1970 et bien compris par les professionnels, testé, documenté, fiable, cohérent (checksums), maintenable (sauvegardes sans perte de données), performant s'il est utilisé correctement (tous types d'index), accessible en toute sécurité sur le réseau, évolutif, etc mais apparemment pas inventé ici.
De nos jours, il existe même de nombreuses bases de données Open Source gratuites comme PostgreSQL qui ont des exigences très modestes et le potentiel d'implémenter facilement de nouvelles exigences dans le futur (ce qui est difficile à prévoir) et avec quelques efforts interchangeables avec d'autres bases de données (JDBC, JPA)
Mais oui, il y a des frais généraux, mais généralement le matériel est moins cher que de changer votre architecture tard dans le projet et les cycles de processeur ne sont plus une ressource coûteuse (pensez Raspberry Pi, smartphones, etc.)
D'après votre question et les commentaires faits sur la réponse de Mark Bramniks, j'ai compris ceci:
Ce sont des contraintes très strictes. Habituellement, vous "échangez" le processeur contre la mémoire ou la mémoire contre le disque. Dans votre cas, ce sont toutes des contraintes. Vous avez mentionné que vous avez regardé ehCache, mais je pense que cette solution (et peut-être d'autres comme Memcached) ne sont pas plus légères que H2.
Une solution que vous pouvez essayer est MappedByteBuffer. Cette classe permet d'avoir des parties d'un fichier en mémoire et échangera ces parties si nécessaire. Mais cela a un coût, ce n'est pas une bête facile à apprivoiser. Vous devrez écrire votre propre algorithme pour localiser les données dont vous avez besoin. Veuillez considérer le temps qu'il vous faudra pour le faire fonctionner par rapport au coût supplémentaire d'une machine plus grosse. Parfois, un meilleur matériel est la solution.
Quelques idées qui peuvent aider
Vous dites que vous utilisez un seul processeur et que vous souhaitez vérifier une substitution à H2. Ainsi, H2 "consomme" beaucoup de puissance CPU et l'application est prétendue "lente". Mais que se passe-t-il si c'est à cause d'un disque lent et non d'un processeur, après tout, les bases de données stockent leurs données sur des disques et les disques peuvent être lents. Si vous voulez vérifier cette théorie - mappez le disque sur un lecteur sauvegardé par RAM (sous Linux, c'est une tâche facile) et mesurez à nouveau avec le même processeur.
Si vous parvenez à la conclusion qu'en effet H2 est gourmand en ressources processeur pour les cas d'utilisation, cela vaut peut-être la peine d'investir du temps pour optimiser les requêtes, c'est beaucoup moins cher que de remplacer la base de données.
Maintenant, si vous ne pouvez pas rester avec H2, considérez Lucene, qui est vraiment optimisé pour ce cas d'utilisation "ajouter uniquement" (je comprends que vous avez un flux "ajouter uniquement" parce que vous avez dit "plus tard, nous récupérons les données, nous n'avons jamais à METTRE À JOUR les données). Cela dit, Lucene devrait également avoir ses propres threads qui gèrent l'indexation, donc une surcharge du processeur est attendue de toute façon. Cependant, il est probable que Lucene sera plus rapide pour ce cas d'utilisation. Le prix est que vous n'obtiendrez pas de requêtes "faciles", car lucene n'implémente pas de modèle relationnel (enfin, peut-être en partie à cause de cela, il devrait être plus rapide), en particulier vous n'aurez pas de JOIN et de gestion des transactions. Il est possible d'interroger par conditions d'une seule table comme dans RDMBS, vous n'avez pas à obtenir les "meilleurs résultats" comme vous le décrivez.