Skip to content
Andrey Lomakin edited this page May 26, 2023 · 29 revisions

Welcome to JetBrains Xodus, a high-performance, embedded database designed to simplify your project's data storage needs. This guide introduces Xodus, highlighting its unique features and demonstrating why it is the perfect choice for developers starting a new project.

Xodus is licensed under the Apache License, Version 2.0.

Overview

Xodus is a perfect fit for developers seeking an embedded database that can be used without the complexity inherent in the relational database model. Its flexibility and versatility are its defining strengths. You can use Xodus as a transactional key-value store that provides high performance, or opt for its object-oriented data model for more complex structures. This dual nature of Xodus is achieved through a layered architecture that supports both a transactional key-value storage (Environments) and a set of typed entities with named properties and relations (Entity Stores).

The primary use case for Xodus is as a part of JetBrains YouTrack project, where it performs as a general-purpose database. Its data model closely aligns with object-oriented programming, making it highly efficient for developers to manipulate database code.

On top of these features, Xodus is open-source and backed by an active community and responsive developer team. Its development is guided by an innovative roadmap and there's a dedicated chat where developers can interact with the Xodus team.

Compared to similar databases like SQLite and MongoDB, Xodus stands out due to its append-only storage mechanism, reducing the random IO overhead caused by in-place updates. It also offers a snapshot isolation level by default, free from write skew anomaly. Unlike MongoDB, Xodus can be used in an embedded mode, providing a seamless experience for developers.

So, are you ready to dive into Xodus? Let's begin!

Snapshot Isolation

Xodus operates exclusively on the snapshot isolation level, guaranteeing a consistent snapshot of the entire database for all reads within a transaction. Unlike other databases which provide multiple isolation levels leading to potential data inconsistencies, Xodus maintains the integrity of your data. This unique feature stems from Xodus's log-structured design, where all modifications are sequentially written to a log. This log, a series of .xd files, serves as an immutable record store of your data. Each committed transaction creates a new snapshot (version) of the database, enabling subsequent transactions to reference this snapshot. This design effectively transforms your Xodus database into a persistent functional data structure providing multi-version concurrency control (MVCC).

Garbage Collector

As Xodus operates on an append-only basis, outdated data records can accumulate over time. These records, no longer in use, are effectively garbage and need to be cleaned up to maintain the physical size of your database. With Xodus, you don't need to fret over this, as it handles garbage collection (GC) in the background automatically. By default, GC operates on a single background thread, balancing the need to minimize database size and ensuring minimal impact on user transactions. In certain cases, you can further optimize GC with a range of additional properties.

Performance

One of the best proofs of Xodus's performance is the production instance of JetBrains' YouTrack, which boasts a database spanning over a decade and housing more than 2 million issues. With a physical database size exceeding 400 GB, Xodus manages to offer outstanding performance on a moderate 16-CPU server with a Java heap of 54 GB. This performance is attributed to its compact data-storing mechanism, lock-free reads, optimistic writes, and intelligent lock-free caching. Xodus shines in environments with high concurrency reads, as it ensures zero contention of read operations even under write operations.

Getting Started

With Xodus, you get the flexibility of choosing between two different API layers to manage your data:

  1. Environments serve as a transactional key-value storage.
  2. Entity Stores allow you to describe a data model as a set of typed entities with named properties (attributes) and named entity links (relations).

Before diving into coding, take a moment to decide on the API layer that best fits your project requirements. This choice will determine the set of artifacts your project depends on. Regardless of your choice, you will need to create an instance of Environment. Note that Entity Store operates on top of Environment.

To create an Environment, you can use the following code:

import jetbrains.exodus.env.*;

Environment environment = Environments.newInstance("/path/to/your/database");

And to close it:

environment.close();

Working with Entity Stores involves creating an instance of PersistentEntityStore. This can be done as follows:

import jetbrains.exodus.entitystore.*;

PersistentEntityStore entityStore = PersistentEntityStores.newInstance("/path/to/your/database");

or

import jetbrains.exodus.entitystore.*;

PersistentEntityStore entityStore = PersistentEntityStores.newInstance(environment);

The first variant creates and closes Environment automatically.

To close the PersistentEntityStore:

entityStore.close();

Transactions in Xodus are straightforward. Starting a transaction looks like this:

final StoreTransaction txn = entityStore.beginTransaction();

or for a read-only transaction:

final StoreTransaction txn = entityStore.beginReadonlyTransaction();

Ensure to finish your transactions, either by committing or aborting them:

txn.commit(); // or txn.abort();

You can also use various utility methods to execute transactions:

entityStore.executeInTransaction(new StoreTransactionalExecutable() {
    @Override
    public void execute(@NotNull final StoreTransaction txn) {
        // your code here
    }
});

Entities in Xodus can have properties and blobs, and can be linked. Each property, blob, or link is identified by its name. To create an entity with a property, you could do something like this:

entityStore.executeInTransaction(new StoreTransactionalExecutable() {
    @Override
    public void execute(@NotNull final StoreTransaction txn) {
        final Entity user = txn.newEntity("User");
        user.setProperty("name", "John Doe");
    }
});

The strength of Xodus lies in its flexibility, performance, and ease of integration into any Java project. You can start with Xodus today and find out how it can boost your development efficiency and product performance.

For more information, please refer to the detailed guides on Environments, Entity Stores, managing your project's dependencies and also sample application based on Environment API and sample application based on EntityStore API.