BerkeleyDB Java Edition
Inleiding
Af en toe komt de situatie voor dat je een groot aantal key/value paren wil opslaan. Sessies aan de hand van hun sessie id, klanten met hun klantnummer, webpagina’s aan de hand van hun url, etc. Verder wil je dit ook snel en makkelijk implementeren. In dat geval is BerkeleyDB de moeite waard om eens te bekijken.
Wat is het
BerkeleyDB Java Edition is een open-source non-relationele database geimplementeerd in java. Conceptueel werkt BerkeleyDB als een oneindig grote (gelimiterd door harde schijf ruimte), persistente HashMap. Verder is BerkeleyDB Open Source met een GNU compatible licentie.
Hoe werkt het
Werken met BerkeleyDb is heel eenvoudig. De opzet is altijd als volgt:
- Download BerkeleyDB Java Edition en voeg de jar aan de classpath toe.
Doe vervolgens in je code:
- Maak een database omgeving aan.
Hierbij is er 1 verplichte parameter: de directory waar BerkeleyDB zijn bestanden moet opslaan. Alle andere parameters zijn optioneel. Dit maakt het initieel opstarten van een project met BerkeleyDB erg eenvoudig. - Creeer een index voor je object.
Hierbij geef je aan wat je object type, je index type en je index property is. - Sla objecten op met index.put(Object)
- Haal objecten op met index.get(ObjectKey)
Voorbeeld
We gaan een miljoen random ‘Customers’ opslaan en weer ophalen.
Eerst ons business object: Customer. Customer bevat onderstaande properties en verder een default constructor en getters en setters voor elke.
Omdat BerkeleyDB objecten als geserializeerde java objecten opslaat moet het object ook Serializable zijn.
De @PrimaryKey geeft aan dat in dit geval de ‘id’ property de PrimaryKey is.
|
@Entity public class Customer implements Serializable {
@PrimaryKey private String id; private String firstName; private String lastName; private double amount; // Default constructor & getters and setters for all properties } |
Vervolgens initialiseren we de database omgeving. (Complete sourcecode hiervoor is beschikbaar in de resources).
Hierna gebruiken we onderstaande eenvoudige class om de Customer op te slaan:
import com.sleepycat.je.DatabaseException; import com.sleepycat.persist.PrimaryIndex;
/** * Stores and retrieves Customer objects. * * @author paul siegmann * */ public class CustomerDB {
private PrimaryIndex<String, Customer> primaryIndex;
public CustomerDB(BerkeleyDB bdb) throws DatabaseException { primaryIndex = bdb.getStore().getPrimaryIndex(String.class, Customer.class); }
/** * Store the given Customer. * * @param customer * @throws DatabaseException */ public void storeCustomer(Customer customer) throws DatabaseException { primaryIndex.put(customer); }
/** * Retrieve the customer with the given customerId. * * @param customerId * @return * @throws DatabaseException */ public Customer retrieveCustomer(String customerId) throws DatabaseException { return primaryIndex.get(customerId); } } |
En dat was het. Nu kan er met customerDB.storeCustomer() een Customer opgeslagen worden, en met customerDB.get() eentje opgehaald.
Ik heb een test gemaakt die 1.000.000 random gegenereerde Customers opslaat en vervolgens 1.000.000 random Customers weer ophaalt.
Mijn laptop met 1.83 GHz CPU slaat ongeveer 24.000 customers per seconde op disk op. De opslag test gebruikt echter CustomerId’s in oplopende volgorde, wat waarschijnlijk niet helemaal realistisch is.
Een realistischer test is het ophalen van 1.000.000 Customers aan de hand van een random gegenereerde Customer ID. In deze test halen we rond de 10.000 retrieves per seconde.
Dit aantal is vergelijkbaar met de performance die ik voor een ander project haal.
Het complete eclipse project met alle code is ge-attached.
Verdere opties
Behalve de in het voorbeelde getoonde features ondersteund BerkeleyDB ook transacties, secondaire indexes, in-memory of on-disk storage.
Conclusie
Voor het opslaan van key/value paren bied BerkeleyDB een uitstekende oplossing die snel, goedkoop én goed is. (Pick all three)
Resources
BerkeleyDB Java Edition blog ecplise project
Meer informatie over BerkeleyDB op de BerkeleyDB Java Edition web pagina: http://www.oracle.com/database/berkeley-db/je/index.html



Hmm geen slechte performance volgens mij. Ik heb net even een h2 (on disk) / iBATIS versie geprobeerd en die bleef hangen op zo’n 13.000 / 4.700 max. Terwijl jouw code bij mij op 28.000 / 12.000 zat. Maar goed daar krijg je natuurlijk ook meer voor. Dan is het ‘gewoon’ in een relationele database opgeslagen.
Misschien dat je met een h2 / pure JDBC implementatie nog wat eruit kan halen. Nu even geen zin in alleen.
Auke van Leeuwen - oktober 26, 2008 23:54
Hoe zit het met transactionele garanties? Is er transaction support (commit/rollback) op BerkeleyDB, hoe schaalbaar is BerkeleyDB (hoe gedraagt het zich binnen een omgeving met 10, 100 of 1000 parallelle transacties? Ik kan die informatie niet vinden op de Oracle site. Ik denk dat ik bedoel te vragen wat de toepassingsomgeving is waarbinnen je deze applicatie gebruikt.
Cor - november 13, 2008 9:58
http://www.oracle.com/technology/documentation/berkeley-db/je/TransactionGettingStarted/index.html
Auke van Leeuwen - november 24, 2008 21:10