Spring et le NoSQL
Introduction
Les bases de données NoSQL, émergées comme une alternative aux systèmes SQL traditionnels, répondent aux besoins croissants des applications web et mobiles contemporaines en gérant efficacement de vastes volumes de données. Ces bases offrent une performance et une évolutivité supérieures pour les applications exigeant des opérations de lecture/écriture rapides grâce à leurs modèles de données non relationnels qui facilitent la distribution sur plusieurs serveurs. Leur flexibilité permet d’adapter facilement les schémas de données aux évolutions des applications, alignant ainsi avec les méthodologies Agile et DevOps. Les bases NoSQL sont idéales pour divers types de données, y compris les données non structurées, et sont conçues pour une haute disponibilité dans des environnements cloud. Bien qu’elles soient souvent open source et moins coûteuses, elles ne remplacent pas entièrement les bases SQL ; en pratique, une combinaison des deux est fréquemment utilisée pour maximiser les avantages de chaque technologie en fonction des besoins spécifiques du projet.
Modèles de données
Les bases de données NoSQL se caractérisent par leur diversité et sont classées en plusieurs catégories en fonction de leur modèle de données. Voici les principaux types de bases de données NoSQL :
-
bases clé/valeur ;
-
bases document ;
-
bases orientées graph ;
-
bases de données de colonnes larges ;
-
bases de données orientées objet.
1. Bases de données clé/valeur
Ces bases stockent les données sous forme de paires clé/valeur.
Les bases de ce type les plus connues sont : Redis, DynamoDB, et Riak.
Elles sont idéales pour les scénarios où l’accès rapide aux données par clé est nécessaire.
2. Bases de données document
Elles stockent les données sous forme de documents, généralement au format JSON, XML ou BSON.
Les bases de ce type les plus connues sont : MongoDB, CouchDB, et Firestore.
Elles conviennent bien pour stocker des données semi-structurées avec une structure flexible.
3. Bases de données de graphes
Elles sont conçues pour stocker et naviguer dans des relations complexes, souvent sous forme de graphes.
Pour ce type de base nous avons par exemple : Neo4j, ArangoDB, et OrientDB.
Elles sont excellentes pour modéliser des réseaux sociaux, des systèmes de recommandation, et...
Principes des bases de données
Le théorème CAP, formulé par Eric Brewer en 2000, est un principe clé dans le domaine des systèmes de bases de données distribués, affirmant qu’il est impossible pour un tel système d’offrir simultanément plus de deux des trois garanties suivantes : cohérence (toutes les données sont uniformes à travers le système), disponibilité (chaque requête reçoit une réponse, même si elle n’est pas la plus récente), et tolérance au partitionnement (le système continue de fonctionner malgré des coupures dans le réseau). Ce théorème souligne le dilemme auquel sont confrontés les concepteurs de systèmes distribués : choisir entre ces trois propriétés essentielles selon les besoins spécifiques de leur application, sachant que maximiser l’une peut compromettre les autres.
Ainsi, un système favorisant cohérence et disponibilité sera vulnérable en cas de partitionnement réseau, un choix cohérence-tolérance au partitionnement compromettra la disponibilité, et un système valorisant disponibilité et tolérance au partitionnement pourrait affronter des incohérences de données. Le compromis entre ces propriétés dépend...
Pourquoi et quand utiliser une base NoSQL ?
L’adoption de bases de données NoSQL représente un tournant vers une gestion de données plus flexible et scalable, idéale pour les grands volumes de données non structurées ou semi-structurées et pour des architectures de microservices. Ces bases offrent des avantages significatifs en termes de performance, scalabilité, et facilité de développement, particulièrement dans des contextes nécessitant une rapidité de lecture/écriture et une gestion efficace de données diversifiées. Néanmoins, elles posent de nouveaux défis organisationnels et techniques, comme la gestion des inconsistances en production par les équipes de développement, ou la relative immaturité comparée aux solutions SQL traditionnelles.
Leur simplicité de gestion et leur capacité à fonctionner en clusters rendent les NoSQL attrayantes pour des projets stratégiques visant un Time To Market court, bien que leur déploiement dans des environnements cloud nécessite une attention particulière à la séparation des données et à la connectivité réseau. Malgré leur polyvalence pour gérer des données clé/valeur ou polymorphiques, le passage du SQL au NoSQL demande une réadaptation en matière...
Spring et le NoSQL
Comme pour les bases SQL, Spring rend plus simple l’utilisation des bases NoSQL à travers la mise à disposition d’API.
Il existe une multitude de bases NoSQL utilisable avec le framework Spring.
Voici les plus populaires :
Base |
Caractéristiques |
MongoDB |
Base de données de documents open source. |
CouchDB |
Base de données qui utilise JSON pour les documents, JavaScript pour les requêtes MapReduce et l’API standard HTTP. |
GemFire |
Plateforme de gestion de données distribuée offrant une évolutivité dynamique, de hautes performances et une persistance de type base de données. |
Redis |
Serveur de structure de données dans lequel les clés peuvent contenir des chaînes, des hachages, des listes, des ensembles et des ensembles triés. |
Cassandra |
Base de données offrant extensibilité et haute disponibilité sans compromettre les performances. |
Memcached |
Système open source à haute performance, à mémoire distribuée et à mise en cache d’objets. |
Hazelcast |
Plateforme de distribution de données open source hautement évolutive. |
HBase |
Base de données Hadoop, un grand entrepôt de données distribué et évolutif. |
Mnesia |
Système de gestion de base de données distribuée qui présente des propriétés logicielles... |
Cache de données
Les bases de données NoSQL sont souvent utilisées pour créer des caches de données dans des applications Spring, en raison de leur flexibilité, de leur performance en matière de lecture/écriture et de leur capacité à gérer de grandes quantités de données non structurées. Voici quelques bases de données NoSQL couramment utilisées pour le caching avec Spring :
-
Redis : très populaire pour le caching, Redis est une base de données en mémoire, offrant des performances exceptionnelles pour les opérations de lecture/écriture. Elle est souvent utilisée pour le caching de sessions, de pages web, et dans les architectures microservices.
-
Apache Geode (anciennement GemFire) : c’est une base de données en mémoire distribuée, optimisée pour des performances élevées et une faible latence. Elle est souvent choisie pour des systèmes nécessitant une grande évolutivité et une gestion de données en temps réel.
-
MongoDB : bien qu’elle soit principalement une base de données orientée document, MongoDB peut être utilisée pour le caching, en particulier lorsque la structure des données est complexe ou change fréquemment.
« Il y a seulement deux problèmes...
Cache simple
Nous pouvons utiliser un ResourceBundle pour charger une ressource afin de garder en mémoire des données fixes, mais cela ne suffit pas toujours. Pour simplifier, nous dirons dans la suite de ce chapitre que nous « cachons » des données quand nous les rendons disponibles à travers l’utilisation d’un cache de données.
Spring offre un support simple pour cacher les beans managés par Spring via l’utilisation de l’annotation @Cacheable.
Cette annotation indique que le résultat de l’appel d’une méthode (ou de toutes les méthodes d’une classe) peut être mis en cache. À chaque fois qu’une méthode est invoquée, on vérifie si on a en mémoire le résultat d’un appel précédent pour les arguments donnés. Nous pouvons aussi fournir une expression SpEL pour calculer la clé via l’attribut key, ou une implémentation KeyGenerator personnalisée qui peut remplacer celle par défaut.
Si aucune valeur n’est trouvée dans le cache pour la clé calculée, la méthode cible est invoquée et la valeur renvoyée est stockée dans le cache associé. Notez que les types de retour facultatifs de Java8+ sont gérés automatiquement et que leur contenu est stocké dans...
Cacher des données avec Geode
Apache Geode (anciennement GemFire) est une data grid (grille de données) en mémoire. Elle permet de stabiliser nos services de données à la demande pour répondre aux exigences de performance des applications temps réel. Elle accompagne la montée en charge cohérente et homogène sur plusieurs data centers, offre des données temps réel à des millions d’utilisateurs, a une architecture orientée événements, et elle est idéale pour les microservices. Ses caractéristiques principales sont sa latence faible et prévisible, sa scalabilité et son élasticité, la notification d’événements en temps réel, la haute disponibilité et la continuité de l’activité. Elle est durable et fonctionne sur le cloud.
Pour l’exemple qui suit, nous utilisons la configuration embarquée (embedded) qui est la plus simple pour obtenir un cache distribué haute disponibilité.
Exemple d’utilisation
Classe Application :
@ClientCacheApplication(name = "CachingGemFireApplication",
logLevel = "error")
@EnableGemfireCaching
@SuppressWarnings("unused")
public class Application {
private static final Logger logger= LoggerFactory.getLogger
(Application.class); ...
Geode en tant que base de données NoSQL
Geode peut aussi être utilisé en tant que base de données NoSQL.
La classe ApplicationEnableGemfireRepositories :
@ClientCacheApplication(name = "DataGemFireApplication", logLevel =
"error")
@EnableGemfireRepositories
public class ApplicationEnableGemfireRepositories {
public static void main(String[] args) throws IOException {
SpringApplication.run(ApplicationEnableGemfireRepositories.class,
args);
}
@Bean("Department")
public ClientRegionFactoryBean<String, Department>
departmentRegion(GemFireCache gemfireCache) {
ClientRegionFactoryBean<String, Department> departmentRegion =
new ClientRegionFactoryBean<>();
departmentRegion.setCache(gemfireCache);
departmentRegion.setClose(false);
departmentRegion.setShortcut(ClientRegionShortcut.LOCAL);
return departmentRegion;
}
@Bean
ApplicationRunner run(DepartmentRepository departmentRepository) {
return args -> {
Department...
Redis en mode autonome
Utilisation de Redis pour le cache de données
La classe Departement reste la même que dans le premier exemple.
Le lanceur :
@SpringBootApplication
@EnableCaching
public class Ex3CacheRedis implements CommandLineRunner {
private static final Logger LOGGER =
LoggerFactory.getLogger(Ex3CacheRedis.class);
public static void main(String[] args) {
SpringApplication.run(Ex3CacheRedis.class, args);
}
@Autowired
private DepartementRepository departementRepository;
@Override
public void run(String... args) throws Exception {
departementRepository.cacheEvict();
LOGGER.info("27->{}",
departementRepository.getByCode("27"));
LOGGER.info("44->{}",
departementRepository.getByCode("44"));
LOGGER.info("51->{}",
departementRepository.getByCode("51")); ...
MongoDB
MongoDB est un système de base de données orienté documents, sous licence AGPL, avec les données réparties sur plusieurs serveurs. Il n’y a pas de schéma de données. Les pilotes sont sous Apache et la documentation sous licence Creative Common.
Créée en 2007, il a fallu attendre la version 1.4 de 2010 pour pouvoir l’utiliser en production. Les données sont au format BSON (JSON binaire), enregistrées sous forme de collections d’objets JSON à niveaux multiples. Ces enregistrements dans la base peuvent être polymorphiques avec comme contrainte de partager un champ-clé principal nommé "id". Cet index unique permet d’identifier un document (enregistrement dans la base). Les requêtes se font en JavaScript.
La base de données dispose d’un interpréteur de commande en mode texte directement accessible via le binaire Mongo. Des outils graphiques libres existent, comme nosqlbooster4mongo.
1. MongoDB avec Spring Boot
Nous utilisons la version Community Edition de MongoDB pour nos tests.
Pour les tests unitaires et les tests d’intégration, il est aussi possible d’utiliser les tests containers (https://www.testcontainers.org/modules/databases/mongodb/).
Pour cet exemple, nous mettons dans le pom.xml le starter spring-boot-starter-data-mongodb. Ceci a pour effet d’inclure les dépendances vers MongoDB.
Il n’y a pas de différences notables avec un programme classique utilisant du SQL.
La classe du lanceur :
@SpringBootApplication
public class Ex1MongoDB implements CommandLineRunner {
private static final Logger LOGGER
= LoggerFactory.getLogger(Ex1MongoDB.class) ;
@Autowired
private CapitaleRepository repository ;
public static void main(String[] args) {
SpringApplication.run(Ex1MongoDB.class, args) ;
}
@Override
public void run(String… args) throws Exception {
repository.deleteAll();
repository.save(new Capitale("Afghanistan",
"Kaboul", "Asie"));
repository.save(new...
Points clés
Points à retenir :
-
Les bases NoSQL remplacent les bases SQL pour les projets qui demandent un Time to Market performant.
-
Les bases NoSQL sont adaptées pour les microservices ou le Big Data.
-
Les bases NoSQL sont généralement gérées en production par les équipes de développement.
-
Un bon sharding qui correspond à la répartition des données entre serveurs est critique.