Introduction à Oracle Berkeley DataBase Java Edition, une base de données clé/valeur développée en Java

| François Ostyn (Soat) | Soat |

Aujourd'hui, je me suis connecté à mon compte GMail, passé quelques appels professionnels, ajouté quelques sources dans Subversion, installé quelques RMP sur ma distribution Linux… Mais pourquoi est-ce que je vous parle de ça ? Eh bien tout simplement car GMail, SVN, RPM ont un élément en commun, ils stockent certaines de leurs données dans une base Berkeley DB.

Pour réagir au contenu de cet article, un espace de dialogue vous est proposé sur le forum Commentez .

- Titre : Introduction à Oracle Berkeley DataBase Java Edition, une base de données clé/valeur développée en Java

- Auteurs : François Ostyn (Soat), Soat

- Parution : 13 octobre 2012

- Licence : Copyright ® 2012 SOAT. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. À propos de Berkeley DB

- III. La famille de Berkeley DB

- III-A. Oracle BDB Core

- III-B. Oracle BDB XML Edition

- III-C. BDB Java Edition

- IV. Les fonctionnalités-clés

- V. Les fonctionnalités additionnelles

- VI. Introduction à Berkeley DB Java Edition

- VI-A. Installation

- VI-B. Les API d'accès aux données

- VI-C. L'API de base par la pratique

- VI-D. L'API DPL par la pratique

- VII. Description de l'environnement de Berkeley DB Java Edition

- VIII. Le support des transactions

- IX. Monitorer une application utilisant BDB JE

- X. Les sources

- XI. Conclusion

- XII. Remerciements

I - Introduction

Aujourd'hui, je me suis connecté à mon compte GMail, passé quelques appels professionnels, ajouté quelques sources dans Subversion, installé quelques RMP sur ma distribution Linux… Mais pourquoi est-ce que je vous parle de ça ? Eh bien tout simplement car GMail, SVN, RPM ont un élément en commun, ils stockent certaines de leurs données dans une base Berkeley DB.

II - À propos de Berkeley DB

Berkeley DB (que nous nommerons BDB) fait partie de la famille des bases de données « clé-valeur » et est sans doute le produit de cette famille le plus utilisé au monde avec plusieurs dizaines de millions de déploiements revendiqués par l'éditeur. La première version de BDB remonte à 1986 et est la propriété d'Oracle depuis février 2006.

III - La famille de Berkeley DB

III-A - Oracle BDB Core

Cette version de Berkeley DB est écrite en C ANSI et peut être utilisée comme une bibliothèque pour accéder aux données persistées. Oracle BDB fournit de nombreuses interfaces pour différents langages de programmation (C, Perl, PHP, Python…).

III-B - Oracle BDB XML Edition

Cette version est une surcouche de BDB. Cette version XML permet de stocker et récupérer facilement des documents XML. L'utilisation de XQuery permet d'accéder aux documents XML stockés.

III-C - BDB Java Edition

Cette version de Berkeley DB, 100 % Java est une base embarquée adoptant le format de stockage clé-valeur. De plus, BDB JE est très performante et flexible. Cette base supporte les transactions, permet de stocker des objets Java en utilisant seulement quelques annotations.

IV - Les fonctionnalités-clés

Chaque membre de la famille BDB possède différentes fonctionnalités. Dans toutes les familles de BDB, nous pouvons remarquer les fonctionnalités suivantes.

Feature Set

Description

Data Store (DS)

1 Writer and n reader

Concurrent Data Store (CDS)

n writers and n snapshot reader

Transactional Data Store (TD)

Full ACID support on top of CDS

High Availability (HA)

Replication for fault tolerence. Fail over recovery support

Le tableau suivant décrit les différences entre BDB "core" et BDB JE.

DS

CDS

TS

HA

BDB/BDB XML

X

X

X

X

BDD JE

X

X

V - Les fonctionnalités additionnelles

Vous trouverez les fonctionnalités qui rendent BDB unique !

Fonctionnalité

Bénéfice

Locking

Haute concurrence

Données stockées dans le format natif de l'application

Performance et pas de conversion nécessaire

API et pas de SQL

Performances et flexibilité et contrôle

In Process et pas de client/serveur

Performances et pas d'IPC nécessaire

Zéro administration

Coût de possession faible

Transactions ACID et récupération

Fiabilité et données intègres

Dual licences

Open/Close source distributions

En mémoire ou sur disque

Transacted caching/Persisted data store

Similar data access API

Facilité de passer de BDB à BDB JE

Faible dépendance vers des bibliothèques tierces

Facile à déployer et à utiliser

Bases de données de grandes capacités

Virtuellement pas de limite de base de données

Et pour ce qui est BDB Java Edition, vous trouverez ses propres fonctionnalités dans le tableau ci-dessous :

Fonctionnalité

Bénéfice

Fast, Indexed, B-Tree

Récupération des données très rapide

Java JEE JTA et JCA Support

Intégration avec les serveurs d'applications Java EE

Efficient Direct Persistence Layer

Utilisation d'annotations pour stocker les graphes d'objets Java

Easy Java Collections API

Manipulation transactionnelle des API de base au travers de Collections Java améliorées

Low Level Base API

Travailler avec des schémas de données dynamiques

JMX Support

Possibilité de monitoring

VI - Introduction à Berkeley DB Java Edition

VI-A - Installation

Tout d'abord, débutons par le commencement. Pour pouvoir utiliser BDB Java Edition, vous devez l'installer à l'adresse suivante : http://www.oracle.com/technetwork/products/berkeleydb/downloads/index.html.

L'installation de Berkeley DB est assez simple, il suffit de décompresser l'archive que vous venez de télécharger !

Le seul fichier dont vous aurez besoin pour faire fonctionner les exemples que nous verrons plus tard est le : "je-*.jar".

VI-B - Les API d'accès aux données

BDB JE fournit trois API pour accéder aux données :

- l'API de base fournit un simple modèle clé-valeur pour stocker et récupérer les données ;

- l'API DPL (Direct Persistence Layer) qui vous laisse persister n'importe quelle classe Java comportant un constructeur par défaut en base de données. Cette API vous permet de récupérer les données avec des fonctionnalités de recherche assez riches ;

- la Collection API qui étend la Java Collection API avec le support de la persistance et des transactions en plus de l'accès aux données.

VI-C - L'API de base par la pratique

// Ouverture de la base de données et création si nécessaire
EnvironmentConfig environmentConfig = new EnvironmentConfig();
environmentConfig.setAllowCreate(true);
// Physiquement où se trouve la base
Environment environment = new Environment(new File(System.getProperty("java.io.tmpdir")), environmentConfig);
DatabaseConfig databaseConfig = new DatabaseConfig();
databaseConfig.setAllowCreate(true);
databaseConfig.setSortedDuplicates(false);
Database database = environment.openDatabase(null, "BDBJESample", databaseConfig);
// Enregistrement en base
DatabaseEntry key = new DatabaseEntry("keyValue".getBytes("UTF-8));
DatabaseEntry data = new DatabaseEntry("dataVAlue".getBytes("UTF-8));
database.put(null, key, data);
// Récupération des enregistrements
DatabaseEntry searchEntry = new DatabaseEntry();
database.get(null, key, searchEntry, LockMode.DEFAULT);
String found = new String(searchEntry.getData(),"UTF-8");
// Mise à jour de l'enregistrement
database.put(null, key, data);
// Suppression en base
database.delete(null, key);
// Fermeture de la connexion à la base
database.close();
environment.close();

Comme vous pouvez le remarquer, l'utilisation de cette API est très simple mais assez verbeuse.

VI-D - L'API DPL par la pratique

Tout d'abord, avant de commencer à vous parler de DPL, même si nous sommes dans l'univers « NoSQL », il est toujours possible de faire une analogie avec le SQL.

Terme SQL

Équivalence Oracle DPL

Database

Environment

Table

Primary Index and its related secondary indices

Primary Index

Primary Index

Secondary Index

Secondary Index

Tuple/Row

Entity

L'exemple que je vais vous présenter se décompose en deux parties. Premièrement, un entity bean et une classe de management qui gère le CRUD (Create-Replace-Update-Delete) au-dessus de l'entity bean.

@Entity
public class Employee {

@PrimaryKey
public Integer id;
public String name;
public String forname;

@SecondaryKey(relate = Relationship.MANY_TO_MANY,
relatedEntity = Project.class,
onRelatedEntityDelete = DeleteAction.NULLIFY)
public Set<Long> projects;

public Employee(Integer id, String name, String forname, Set<Long> projects) {
this.id = id;
this.name = name;
this.forname = forname;
this.projects = projects;
}
}

Il s'agit en effet d'un simple POJO avec quelques annotations. Ceux qui connaissent un peu JPA ne seront pas perdus !

Le code ci-dessous vous montre comment accéder aux données présentes dans le POJO Employee.

@Entity
EnvironmentConfig environmentConfig = new EnvironmentConfig();
environmentConfig.setAllowCreate(true);
// Physiquement où se trouve la base
Environment environment = new Environment(new File(System.getProperty("java.io.tmpdir")), environmentConfig);
StoreConfig storeConfig = new StoreConfig();
storeConfig.setAllowCreate(true);

EntityStore entityStore = new EntityStore(environment, "BDBJEDPLSample", storeConfig);
PrimaryIndex<Integer, Employee> employeePrimaryIndex = entityStore.getPrimaryIndex(Integer.class, Employee.class);
employeePrimaryIndex.putNoReturn(new Employee(12,"francois", "ostyn", null));

Employee employee = employeePrimaryIndex.get(12);
Assert.assertNotNull(employee);
employeePrimaryIndex.delete(12);
employee = employeePrimaryIndex.get(12);
Assert.assertNull(employee);

entityStore.close();
environment.close();

Dans l'exemple ci-dessus nous ne gérons ni les transactions, ni des relations complexes.

VII - Description de l'environnement de Berkeley DB Java Edition

Une base de données BDB JE est composée d'un ou plusieurs fichiers de logs qui sont situés dans le répertoire d'environnement.

Par défaut, leur taille est de 10 Mb et peut être modifiée (par exemple, augmenter la taille des logs permet de limiter le nombre d'I/O).

VIII - Le support des transactions

Pour gérer les transactions avec DPL, il faut faire quelques modifications dans son code.

EnvironmentConfig environmentConfig = new EnvironmentConfig();
environmentConfig.setAllowCreate(true);
environmentConfig.setTransactional(true); // << gestion des transactions

TransactionConfig transactionConfig = new TransactionConfig(); // << gestion des transactions
transactionConfig.setReadCommitted(true); // << gestion des transactions
// Physiquement où se trouve la base
Environment environment = new Environment(file, environmentConfig);
StoreConfig storeConfig = new StoreConfig();
storeConfig.setAllowCreate(true);
storeConfig.setTransactional(true); // << gestion des transactions

Transaction tx = environment.getThreadTransaction(); // << gestion des transactions
environment.beginTransaction(tx, transactionConfig); // << gestion des transactions

EntityStore entityStore = new EntityStore(environment, "BDBJEDPLSample", storeConfig);

PrimaryIndex<Integer, Employee> employeePrimaryIndex = entityStore.getPrimaryIndex(Integer.class, Employee.class);

employeePrimaryIndex.putNoReturn(new Employee(12, "francois", "ostyn", null));

tx.commit();

Bien entendu, vous pouvez préciser un timeout transactionnel, ainsi que le retry policy…

IX - Monitorer une application utilisant BDB JE

Étant donné que BDB JE est totalement écrit en Java, ce dernier expose bon nombre de métriques via JMX. Pour l'activer, il faut positionner la property "-DJEMonitor=true" au démarrage de la JVM.

Ceci peut être très utile pour modifier le comportement de votre application à chaud ou récupérer certaines métriques.

X - Les sources

Vous pourrez trouver les sources présentées dans les exemples sur GitHub à l'adresse suivante : https://github.com/francoisostyn/bdbJeSampleFost.

XI - Conclusion

À l'heure où l'on nous parle de bon nombre de solutions « NoSQL », Berkeley DB Java Edition est bien souvent oublié et à tort. En effet, cette version est d'une performance redoutable. Cependant, je regrette tout de même la « double licence » qui pourra freiner beaucoup de monde.

En tout cas, BDB JE est parmi mes solutions NoSQL clé-valeur !

XII - Remerciements

Cet article a été publié avec l'aimable autorisation de la société Soat.

Nous tenons à remercier ClaudeLELOUP pour sa relecture orthographique attentive de cet article et Mickael Baron pour la mise au gabarit.