|By Jim Menard||
|September 7, 2004 12:00 AM EDT||
Berkeley DB is a database with a long history. First released in 1991 as a replacement for various dbm implementations, it was soon included in BSD Unix releases. Requests for new features and commercial support led to the formation of Sleepycat Software in 1996. Using a dual license model, Berkeley DB became very popular for both open source and commercial applications. Recently, Sleepycat announced Berkeley DB Java Edition (JE), a 100% Java implementation that runs on any J2SE 1.4.2 or later JVM.
This article introduces JE's features and classes and uses a sample electronic voting application to illustrate its use.
Berkeley DB and JE
The original Berkeley DB is used in a wide variety of open source and commercial applications in telecom, Internet infrastructure, storage, security, financial services, and other industries. Sleepycat estimates that there are over 200 million copies deployed, but most people are not even aware they touched Berkeley DB. (See "Where's the Sleeping Cat?" available at the URL listed in References.)
Berkeley DB is a nonrelational database that stores key/value pairs. Databases can be configured to store multiple values under a single key. Secondary databases can be created that use different keys to access the same values. Searches and joins can be performed using a specific key or a range of keys.
The original Berkeley DB (not JE) is written in C, though there are bindings for other languages, including Java. JE brings to Java developers the features of Berkeley DB and adds better integration with the Java world through Java data type support while avoiding the performance penalty of JNI.
Like its C ancestor, JE is small. The database's footprint is less than 435K. It supports full ACID transactions (meaning its characteristics include Atomicity, Consistency, Isolation, and Durability), performs record-level locking for high concurrency, and can handle huge amounts of data: hundreds of terabytes in a single table, with record sizes up to two gigabytes. Frequently used data is cached in memory. JE has better concurrency than the C Berkeley DB for some applications because, unlike DB, it has record-level locking that allows applications to continue accessing other parts of the database when a record is locked.
JE databases are stored as files on the file system. Backing up a database is accomplished by copying the files. To restore a database, move the copied files into the database directory and restart the application. When an application uses a database with transactions (that group database operations together in order to treat them atomically), checkpoints are periodically saved to the file system by a separate JE thread in order to make recovery faster. Applications without transactions may need to perform manual syncs that tell the database to flush data in memory to the file system, depending upon their requirements.
JE databases are B+Trees whose records are key/value pairs. The keys and values are byte arrays. Databases are stored as files within a single directory. An in-memory cache stores as much as it can of the B+Tree structure and frequently accessed data.
The class DatabaseStats provides information about a database, such as the number of records in the database or the depth of the B+Tree.
A database environment coordinates one or more databases. It manages transactions, allowing them to work across databases. The environment provides the in-memory cache used by an application. It also facilitates administrative operations such as renaming or deleting databases.
Records and Binding
Each record in a database is an instance of DatabaseEntry, essentially a wrapper around a byte array. Since storing Java objects is a common operation, JE provides ways to translate between them and byte arrays. This process is called binding. JE provides classes for binding simple numeric and string objects.
There are two approaches to creating DatabaseEntry values from more complex Java objects: serialization or creating a custom class that translates the objects to and from byte arrays. When serializing objects to be stored in separate database records, each serialized instance carries with it duplicate information: the descriptions of the classes involved in the serialization. JE provides binding APIs that perform the serialization and store the duplicate information only once, in a separate database (see Figure 1).
A custom binding that maps objects to byte arrays must subclass TupleBinding, which implements the EntryBinding interface. This interface consists of two methods: objectToEntry and entryToObject.
Cursors and Iterators
To look up a single key, call myDatabase.get(), passing in the key as a DatabaseEntry and another DatabaseEntry to hold the returned data.
To iterate through the database or a subset of the database, both a cursor and iterators are available. They operate the same way, searching for a (possibly partial) key and iterating over the returned values. The difference is that iteration uses flavors of the Java collection classes called StoredMap, StoredSet, and StoredIterator. Unlike java.util.Iterators, StoredIterators must be closed explicitly. There are two ways to close a StoredIterator: call its close method or call the static method StoredIterator.close. The latter approach avoids casting when the iterator is stored in a variable of type Iterator.
The JE collection classes implement all of the collection methods except for size (for example, get, put, and containsValue) and a few extras. See the Javadocs for details.
To perform searches using keys that are different than those used to store the data, a secondary database must be created. The values in the secondary database are the same as those in the primary database. Multiple secondary databases may be created.
When a primary database is modified, JE updates all of its secondary databases. All writing takes place through the primary database. The one exception to this rule is that records may be deleted from a secondary database. The records in the primary database are also deleted, as are all corresponding records in all other secondary databases.
Creating a secondary database requires three things: a primary database, a binding for the keys, and a binding for the values. The value binding will be the same one used by the primary database. The key creator it must implement is the SecondaryKeyCreator interface, which has the single method createSecondaryKey.
Transactions are enabled by an application when an environment and its databases are created or opened. Once enabled, they must be used for all database modifications. Methods such as Database.get and Database.put take a transaction object as an argument. If the transaction argument is null and transactions are enabled, the method may either use autocommit (committing the data when the operation is finished) as does "put" or it may not use a transaction at all, as with "get", which does not modify the database.
The TransactionRunner class and TransactionWorker interface can make using transactions easier by handling retries and exceptions. A TransactionRunner creates a transaction and calls TransactionWorker.doWork. The runner can retry the work any number of times.
A Sample Application
A pair of electronic voting applications - one that simulates election day and another that runs reports against the collected data - will help illustrate the use of JE. While developing this application, I made heavy use of Sleepycat's JE Javadocs and "Getting Started with Berkeley DB Java Edition," included in the documentation that comes with JE.
The two applications share much of their code. To create the data, the election day simulator creates voting booths, then generates votes and sends them to the vote server. The vote server stores information about the booths and their votes into multiple primary and secondary databases. The reporting application performs queries about the booths and the votes.
The three main classes for these applications are Booth, Vote, and VoteServer. A booth is identified by an IP address and knows what state, city, and district it is in. The booth assigns each vote a sequence number. A vote's unique identifier is a combination of the booth's IP address and the vote's sequence number. A vote holds a few more fields like the race (President, State Assembly, Dog Catcher), political party (Democrat, Republican, Silly), and candidate.
After thinking about the queries I wanted to be able to run, I decided that in addition to the primary databases for Booth and Vote, I would need three secondary databases: for booths using state as the key, for votes using race as the key, and for votes using race plus political party.
Before creating databases, bindings for Booth and Vote need to be created. For the primary databases, I chose to use custom binding classes. Listing 1 contains the two methods implemented by BoothBinding. The JE classes TupleInput and TupleOutput know how to read and write strings and intrinsics (ints, longs, etc.).
Bindings for the keys in the primary databases are unnecessary because the keys are so simple: the booth database's key is the IP address byte array that needs no translation, and the vote database's key is a string from which we can retrieve a byte array.
Each secondary database needs a SecondaryKeyCreator. One of the vote secondary databases is indexed by race and party. Listing 2 shows the method that, given a vote and its primary key, fills in the secondary key DatabaseEntry.
When opening a database for writing, it is created if it does not exist. A flag is set that determines if the database is transactional. Listing 3 shows this process.
The code in Listing 4 creates a transaction, calls the method that stores the booth and its votes, and commits the transaction. (Listings 4-9 can be downloaded from www.sys-con.com/java/sourcec.cfm.) This code commits without synchronizing the change to the log file, which is risky (the data is held in memory until the next sync) but faster.
Booth and vote data are written to the primary database. The secondary databases are updated automatically. The code in Listing 5 stores a vote into the vote primary database.
The VoteServer runs five different reports, each using a different technique.
The following code retrieves the total number of votes in the primary vote database.
// try/catch not shown XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Database db = dbEnvironment.getVoteDb(); Cursor cursor = db.openCursor(null, null); DatabaseEntry foundKey = new DatabaseEntry(); DatabaseEntry foundData = new DatabaseEntry(); int numRecords = 0; while (cursor.getNext(foundKey, foundData, LockMode.DEFAULT) == OperationStatus.SUCCESS) ++numRecords; cursor.close(); [DELETE: int nRecs = dbEnvironment.getVoteDb() .getStats(null).getLnCount(); END DELETE] // (print number of records here)
Database.get is used to find a single vote by its primary key (see Listing 6).
Booths by State
This report selects a state from the database, then prints all of the booths in that state. It runs the same query two different ways: with a cursor (see Listing 7) and with a JE Iterator (see Listing 8). The Iterator code is shorter. In both listings, error handling code and try/catch blocks are not shown.
Total Presidential Race Vote Count
To count how many votes were cast in the presidential race, a StoredMap is opened on the proper secondary database. The duplicate records (votes) for the presidential race are retrieved and the number of votes is reported (see Listing 9).
Presidential Race Results
The last report prints the total votes per party for the presidential race and declares a winner. As in the previous report, a map is created on a secondary database and the map's size method returns the vote count.
The electronic voting application source code contains plenty of comments and deals with all the details ignored in this article such as error handling. The code and properties files that configure the databases and transactions have not been tuned for performance.
To get started with the Berkeley DB Java Edition, download it from Sleepycat Software. Read "Getting Started with Berkeley DB Java Edition," browse the example code that comes with JE, and refer to the JE Javadocs.
JE is available under a dual license. The open source license is online at www.sleepycat.com/download/oslicense.html. Pricing starts at $40,000 for a buyout license, which enables the customer to redistribute JE within a specific product/service in any volume into perpetuity.
Sleepycat Software's site is www.sleepycat.com. There you can download the Berkeley DB Java Edition. The documentation and example code that comes with JE are great starting points. The site also contains a number of technical articles and white papers at www.sleepycat.com/company/technical.shtml.
The paper "Where's the Sleeping Cat?" is available at www.sleepycat.com/pdfs/index.php?paper=jdj_wheresthecat.
The latest version of the electronic voting application code can be found at www.io.com/~jimm/writing/evote.tar.gz.
While creating or opening databases, JE allows you to specify many optional database configuration parameters, including but not limited to:
- Maximum database file size
- Whether transactions are allowed
- Transaction timeout length
- Cache size
- Whether duplications are allowed
- How frequently to perform checkpoints
- How to sort duplicate records
Why Berkeley DB Java Edition?
Where should you use Berkeley DB Java Edition? Consider using JE if:
- Speed and size are issues. JE is fast and can handle huge amounts of data.
- It makes sense to embed the database into your application. Some applications are delivered to platforms that don't have a database installed or can't connect to a database server.
- You know what questions you will be asking of the data. Writing queries involves writing Java code and designing the database structure to allow access to the data based on keys other than the primary key.
- The application needs to perform ad-hoc queries. For this you need to write Java code to perform searches; there is no other query language. Searches that use keys other than the primary key used to store the data require a secondary database, discussed later in this article.
- Data must be shared with non-Java applications. The original Berkeley DB data format is different than the JE format. Berkeley DB supports bindings to many languages, including Java.
Database Log Files
Databases are stored as a series of log files. When data is written to a disk, it's always appended to an existing log file. This enables very fast writes since the disk head does not need to move. Log files are never overwritten or modified; those operations are slower than appends. When the log file in use by a database reaches a maximum size, a new log file is created. A background "cleaner" thread organizes the log files, moving active records from older log files to newer ones and deleting old log files that contain no active data.
|Jim Menard 10/06/04 04:31:59 PM EDT|
I haven't tried creating a hierarchical structure using Berkeley DB. I imagine you could by containing the key of one database within the value of another.
I highly recommend the Sleepycat email lists. The "bdbje" email list is read by users and Sleepycat people (Sleepycats?) alike. See http://www.sleepycat.com/supports/index.shtml for the list of mailing lists. To join the bdbje list, send an email to [email protected].
|Lars Borup Jensen 10/06/04 04:16:17 AM EDT|
Ive been looking for articles regarding berkeley db, IMHO a underused product. I've been wondering for a looong time now, how it would be possible to create a hierarchical structure using bdb. Ive looked at openldap (their bdb and hdb backends) but still "designing" as this task does NOT seem trivial. Have you had any experience regarding this??
|Jim Menard 09/08/04 02:02:26 PM EDT|
Please ignore the text between "[DELETE" and "END DELETE]" in the sample code here online. It's the artifact of a last-minute change. I haven't yet seen the article in its print form, so I'm not sure if the printed code has the same issue.
I look forward to your comments on this article. Thanks for reading it.
SYS-CON Events announced today that CA Technologies has been named “Platinum Sponsor” of SYS-CON's 20th International Cloud Expo®, which will take place on June 6-8, 2017, at the Javits Center in New York City, NY, and the 21st International Cloud Expo®, which will take place October 31-November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. CA Technologies helps customers succeed in a future where every business – from apparel to energy – is being rewritten by software. From ...
Feb. 28, 2017 02:15 AM EST Reads: 684
Web Real-Time Communication APIs have quickly revolutionized what browsers are capable of. In addition to video and audio streams, we can now bi-directionally send arbitrary data over WebRTC's PeerConnection Data Channels. With the advent of Progressive Web Apps and new hardware APIs such as WebBluetooh and WebUSB, we can finally enable users to stitch together the Internet of Things directly from their browsers while communicating privately and securely in a decentralized way.
Feb. 28, 2017 02:15 AM EST Reads: 5,062
"A lot of times people will come to us and have a very diverse set of requirements or very customized need and we'll help them to implement it in a fashion that you can't just buy off of the shelf," explained Nick Rose, CTO of Enzu, in this SYS-CON.tv interview at 18th Cloud Expo, held June 7-9, 2016, at the Javits Center in New York City, NY.
Feb. 28, 2017 02:15 AM EST Reads: 7,076
DevOps is often described as a combination of technology and culture. Without both, DevOps isn't complete. However, applying the culture to outdated technology is a recipe for disaster; as response times grow and connections between teams are delayed by technology, the culture will die. A Nutanix Enterprise Cloud has many benefits that provide the needed base for a true DevOps paradigm.
Feb. 27, 2017 11:45 PM EST Reads: 903
You think you know what’s in your data. But do you? Most organizations are now aware of the business intelligence represented by their data. Data science stands to take this to a level you never thought of – literally. The techniques of data science, when used with the capabilities of Big Data technologies, can make connections you had not yet imagined, helping you discover new insights and ask new questions of your data. In his session at @ThingsExpo, Sarbjit Sarkaria, data science team lead ...
Feb. 27, 2017 11:00 PM EST Reads: 9,162
The Internet of Things will challenge the status quo of how IT and development organizations operate. Or will it? Certainly the fog layer of IoT requires special insights about data ontology, security and transactional integrity. But the developmental challenges are the same: People, Process and Platform and how we integrate our thinking to solve complicated problems. In his session at 19th Cloud Expo, Craig Sproule, CEO of Metavine, demonstrated how to move beyond today's coding paradigm and sh...
Feb. 27, 2017 09:15 PM EST Reads: 4,176
Big Data, cloud, analytics, contextual information, wearable tech, sensors, mobility, and WebRTC: together, these advances have created a perfect storm of technologies that are disrupting and transforming classic communications models and ecosystems. In his session at @ThingsExpo, Erik Perotti, Senior Manager of New Ventures on Plantronics’ Innovation team, provided an overview of this technological shift, including associated business and consumer communications impacts, and opportunities it m...
Feb. 27, 2017 08:00 PM EST Reads: 7,968
WebRTC is about the data channel as much as about video and audio conferencing. However, basically all commercial WebRTC applications have been built with a focus on audio and video. The handling of “data” has been limited to text chat and file download – all other data sharing seems to end with screensharing. What is holding back a more intensive use of peer-to-peer data? In her session at @ThingsExpo, Dr Silvia Pfeiffer, WebRTC Applications Team Lead at National ICT Australia, looked at differ...
Feb. 27, 2017 07:45 PM EST Reads: 7,387
With major technology companies and startups seriously embracing IoT strategies, now is the perfect time to attend @ThingsExpo 2016 in New York. Learn what is going on, contribute to the discussions, and ensure that your enterprise is as "IoT-Ready" as it can be! Internet of @ThingsExpo, taking place June 6-8, 2017, at the Javits Center in New York City, New York, is co-located with 20th Cloud Expo and will feature technical sessions from a rock star conference faculty and the leading industry p...
Feb. 27, 2017 07:30 PM EST Reads: 2,277
SYS-CON Events announced today that IoT Now has been named “Media Sponsor” of SYS-CON's 20th International Cloud Expo, which will take place on June 6–8, 2017, at the Javits Center in New York City, NY. IoT Now explores the evolving opportunities and challenges facing CSPs, and it passes on some lessons learned from those who have taken the first steps in next-gen IoT services.
Feb. 27, 2017 07:15 PM EST Reads: 2,007
SYS-CON Events announced today that WineSOFT will exhibit at SYS-CON's 20th International Cloud Expo®, which will take place on June 6-8, 2017, at the Javits Center in New York City, NY. Based in Seoul and Irvine, WineSOFT is an innovative software house focusing on internet infrastructure solutions. The venture started as a bootstrap start-up in 2010 by focusing on making the internet faster and more powerful. WineSOFT’s knowledge is based on the expertise of TCP/IP, VPN, SSL, peer-to-peer, mob...
Feb. 27, 2017 07:00 PM EST Reads: 2,225
The Internet of Things can drive efficiency for airlines and airports. In their session at @ThingsExpo, Shyam Varan Nath, Principal Architect with GE, and Sudip Majumder, senior director of development at Oracle, discussed the technical details of the connected airline baggage and related social media solutions. These IoT applications will enhance travelers' journey experience and drive efficiency for the airlines and the airports.
Feb. 27, 2017 07:00 PM EST Reads: 2,611
A strange thing is happening along the way to the Internet of Things, namely far too many devices to work with and manage. It has become clear that we'll need much higher efficiency user experiences that can allow us to more easily and scalably work with the thousands of devices that will soon be in each of our lives. Enter the conversational interface revolution, combining bots we can literally talk with, gesture to, and even direct with our thoughts, with embedded artificial intelligence, whic...
Feb. 27, 2017 06:30 PM EST Reads: 2,156
WebRTC sits at the intersection between VoIP and the Web. As such, it poses some interesting challenges for those developing services on top of it, but also for those who need to test and monitor these services. In his session at WebRTC Summit, Tsahi Levent-Levi, co-founder of testRTC, reviewed the various challenges posed by WebRTC when it comes to testing and monitoring and on ways to overcome them.
Feb. 27, 2017 06:15 PM EST Reads: 8,319
In his keynote at 18th Cloud Expo, Andrew Keys, Co-Founder of ConsenSys Enterprise, provided an overview of the evolution of the Internet and the Database and the future of their combination – the Blockchain. Andrew Keys is Co-Founder of ConsenSys Enterprise. He comes to ConsenSys Enterprise with capital markets, technology and entrepreneurial experience. Previously, he worked for UBS investment bank in equities analysis. Later, he was responsible for the creation and distribution of life settle...
Feb. 27, 2017 04:45 PM EST Reads: 1,888
In his session at @ThingsExpo, Steve Wilkes, CTO and founder of Striim, will delve into four enterprise-scale, business-critical case studies where streaming analytics serves as the key to enabling real-time data integration and right-time insights in hybrid cloud, IoT, and fog computing environments. As part of this discussion, he will also present a demo based on its partnership with Fujitsu, highlighting their technologies in a healthcare IoT use-case. The demo showcases the tracking of patie...
Feb. 27, 2017 04:45 PM EST Reads: 1,529
The explosion of new web/cloud/IoT-based applications and the data they generate are transforming our world right before our eyes. In this rush to adopt these new technologies, organizations are often ignoring fundamental questions concerning who owns the data and failing to ask for permission to conduct invasive surveillance of their customers. Organizations that are not transparent about how their systems gather data telemetry without offering shared data ownership risk product rejection, regu...
Feb. 27, 2017 03:30 PM EST Reads: 2,350
The best way to leverage your Cloud Expo presence as a sponsor and exhibitor is to plan your news announcements around our events. The press covering Cloud Expo and @ThingsExpo will have access to these releases and will amplify your news announcements. More than two dozen Cloud companies either set deals at our shows or have announced their mergers and acquisitions at Cloud Expo. Product announcements during our show provide your company with the most reach through our targeted audiences.
Feb. 27, 2017 02:45 PM EST Reads: 2,671
SYS-CON Events announced today that Cloud Academy will exhibit at SYS-CON's 20th International Cloud Expo®, which will take place on June 6-8, 2017, at the Javits Center in New York City, NY. Cloud Academy is the industry’s most innovative, vendor-neutral cloud technology training platform. Cloud Academy provides continuous learning solutions for individuals and enterprise teams for Amazon Web Services, Microsoft Azure, Google Cloud Platform, and the most popular cloud computing technologies. Ge...
Feb. 27, 2017 02:30 PM EST Reads: 2,030
20th Cloud Expo, taking place June 6-8, 2017, at the Javits Center in New York City, NY, will feature technical sessions from a rock star conference faculty and the leading industry players in the world. Cloud computing is now being embraced by a majority of enterprises of all sizes. Yesterday's debate about public vs. private has transformed into the reality of hybrid cloud: a recent survey shows that 74% of enterprises have a hybrid cloud strategy.
Feb. 27, 2017 01:45 PM EST Reads: 2,568