Skip to main content

greendb

async server frontend for symas lmdb.

description

greendb is a lightweight server (and Python client) for symas lmdb. The server uses the new Redis RESPv3 protocol.

greendb supports multiple independent databases, much like Redis. Values are serialized using msgpack, so the server is capable of storing all the data-types supported by msgpack. greendb also provides per-database configuration of multi-value support, allowing you to efficiently store multiple values at a given key, in sorted order (e.g. for secondary indexes).

With greendb, database keys are always bytestrings. Values may be:

  • dict
  • list
  • set
  • bytestrings
  • unicode strings
  • integers
  • floating-point
  • boolean
  • None

installing

$ pip install greendb

Alternatively, you can install from git:

$ git clone https://github.com/coleifer/greendb
$ cd greendb
$ python setup.py install

Dependencies:

running

$ greendb.py -h

usage: greendb.py [-h] [-c CONFIG] [-D DATA_DIR] [-d] [-e] [-H HOST]
                  [-l LOG_FILE] [-m MAP_SIZE] [--max-clients MAX_CLIENTS]
                  [-n MAX_DBS] [-p PORT] [-r] [-s] [-u DUPSORT] [-M] [-W] [-A]

options:
  -h, --help            show this help message and exit
  -c, --config CONFIG   Config file (default="config.json")
  -D, --data-dir DATA_DIR
                        Directory to store db environment and data.
  -d, --debug           Log debug messages.
  -e, --errors          Log error messages only.
  -H, --host HOST       Host to listen on.
  -l, --log-file LOG_FILE
                        Log file.
  -m, --map-size MAP_SIZE
                        Maximum size of memory-map used for database. The
                        default value is 256M and should be increased. Accepts
                        value in bytes or file-size using "M" or "G" suffix.
  --max-clients MAX_CLIENTS
                        Maximum number of clients.
  -n, --max-dbs MAX_DBS
                        Number of databases in environment. Default=16.
  -p, --port PORT       Port to listen on.
  -r, --reset           Reset database and config. All data will be lost.
  -s, --sync            Flush system buffers to disk when committing a
                        transaction. Durable but much slower.
  -u, --dupsort DUPSORT
                        db index(es) to support dupsort
  -M, --no-metasync     Flush system buffers to disk only once per
                        transaction, omit the metadata flush.
  -W, --writemap        Use a writeable memory map.
  -A, --map-async       When used with "--writemap" (-W), use asynchronous
                        flushes to disk.

Complete config file example with default values:

{
  "host": "127.0.0.1",
  "port": 31337,
  "max_clients": 1024,
  "path": "data",  // Directory for data storage, default is "data" in CWD.
  "map_size": "256M",  // Default map size is 256MB. INCREASE THIS!
  "read_only": false,  // Open the database in read-only mode.
  "metasync": true,  // Sync metadata changes (recommended).
  "sync": false,  // Sync all changes (durable, but much slower).
  "writemap": false,  // Use a writable map (probably safe to do).
  "map_async": false,  // Asynchronous writable map.
  "meminit": true,  // Initialize new memory pages to zero.
  "max_dbs": 16,  // Maximum number of DBs.
  "max_spare_txns": 64,
  "lock": true,  // Lock the database when opening environment.
  "dupsort": false  // Either a boolean or a list of DB indexes.
}

Example custom configuration:

  • 1GB max database size
  • dupsort enabled on databases 13, 14 and 15
  • data stored in /var/lib/greendb/data
{
  "map_size": "1G",
  "dupsort": [13, 14, 15],
  "path": "/var/lib/greendb/data/"
}

Equivalent configuration using command-line arguments:

$ greendb.py -m 1G -u 13 -u 14 -u 15 -D /var/lib/greendb/data/

client

A Python client is included in the greendb module. All server commands are implemented as client methods using the lower-case command name, for example:

from greendb import Client
client = Client(host='10.0.0.3')

# Execute the ENVINFO command.
print(client.envinfo())

# Set multiple key/value pairs, read a key, then delete two keys.
client.mset({'k1': 'v1', 'k2': 'v2'})  # MSET
print(client.get('k1'))  # GET
client.mdelete(['k1', 'k2'])  # MDELETE

Additionally, the Client implements much of the Python dict interface, such as item get/set/delete, iteration, length, contains, etc.

If an error occurs, either due to a malformed command (e.g., missing required parameters) or for any other reason (e.g., attempting to write to a read-only database), then a CommandError will be raised by the client with a message indicating what caused the error.

A note about connections: the greendb client will automatically connect the first time you issue a command to the server. The client maintains its own thread-safe (and greenlet-safe) connection pool. If you wish to explicitly connect, the client may be used as a context manager.

In a multi-threaded or multi-greenlet application (e.g. a web app), the client will maintain a separate connection for each thread/greenlet.

command reference

Below is the list of supported commands. Commands are available on the client using the lower-case command name as the method name.

command description arguments return value
ENVINFO metadata and storage configuration settings (none) dict
ENVSTAT metadata related to the global b-tree (none) dict
FLUSH delete all records in the currently-selected database (none) boolean indicating success
FLUSHALL delete all records in all databases (none) dict mapping database index to boolean
PING ping the server (none) "pong"
STAT metadata related to the currently-selected database b-tree (none) dict
SYNC synchronize database to disk (use when sync=False) (none) (none)
USE select the given database database index, 0 through (max_dbs - 1) int: active database index
KV commands
COUNT get the number of key/value pairs in active database (none) int
DECR decrement the value at the given key amount to decrement by (optional, default is 1) int or float
INCR increment the value at the given key amount to increment by (optional, default is 1) int or float
CAS compare-and-set key, original value, new value boolean indicating success or failure
DELETE delete a key and any value(s) associated key int: number of keys removed (1 on success, 0 if key not found)
DELETEDUP delete a particular key/value pair when dupsort is enabled key, value to delete int: number of key+value removed (1 on success, 0 if key+value not found)
DELETEDUPRAW delete a particular key/value pair when dupsort is enabled using an unserialized bytestring as the value key, value to delete int: number of key+value removed (1 on success, 0 if key+value not found)
DUPCOUNT get number of values stored at the given key (requires dupsort) key int: number of values, or None if key does not exist
EXISTS determine if the given key exists key bool
GET get the value associated with a given key. If dupsort is enabled and multiple values are present, the one that is sorted first will be returned. key value or None
GETDUP get all values associated with a given key (requires dupsort) key list of values or None if key does not exist
LENGTH get the length of the value stored at a given key, e.g. for a string this returns the number of characters, for a list the number of items, etc. key length of value or None if key does not exist
POP atomically get and delete the value at a given key. If dupsort is enabled and multiple values are present, the one that is sorted first will be removed and returned. key value or None
REPLACE atomically get and set the value at a given key. If dupsort is enabled, the first value will be returned (if exists) and ALL values will be removed so that only the new value is stored. key previous value or None
SET store a key/value pair. If dupsort is enabled, duplicate values will be stored at the given key in sorted-order. Additionally, if dupsort is enabled and the exact key/value pair already exist, no changes are made. key, value int: 1 if new key/value added, 0 if dupsort is enabled and the key/value already exist
SETDUP store a key/value pair, treating duplicates as successful writes (requires dupsort). Unlike SET, if the exact key/value pair already exists, this command will return 1 indicating success. key, value int: 1 on success
SETDUPRAW store a key/value pair, treating duplicates as successful writes (requires dupsort). Additionally, the value is not serialized, but is stored as a raw bytestring. key, value (bytes) int: 1 on success
SETNX store a key/value pair only if the key does not exist key, value int: 1 on success, 0 if key already exists
Bulk KV commands
MDELETE delete multiple keys list of keys int: number of keys deleted
MGET get the value of multiple keys list of keys dict of key and value. Keys that were requested, but which do not exist are not included in the response.
MGETDUP get all values of multiple keys (requires dupsort) list of keys dict of key to list of values. Keys that were requested, but which do not exist, are not included in the response.
MPOP atomically get and delete the value of multiple keys. If dupsort is enabled and multiple values are stored at a given key, only the first value will be removed. list of keys dict of key to value
MREPLACE atomically get and set the value of multiple keys. If dupsort is enabled and multiple values are stored at a given key, only the first value will be returned and all remaining values discarded. dict of key to value dict of key to previous value. Keys that did not exist previously will not be included in the response.
MSET set the value of multiple keys. dict of key to value int: number of key / value pairs set
MSETDUP store multiple key/value pairs, treating duplicates as successful writes (requires dupsort). Unlike MSET, if the exact key/value pair already exists, this command will treat the write as a success. dict of key to value int: number of key / value pairs set
MSETNX store multiple key/value pair only if the key does not exist dict of key to value int: number of key / value pairs set
Cursor / range commands
DELETERANGE delete a range of keys using optional inclusive start/end-points start key (optional), end key (optional), count (optional) int: number of keys deleted
GETRANGE retrieve a range of key/value pairs using optional inclusive start/end-points start key (optional), end key (optional), count (optional) list of [key, value] lists
GETRANGEDUPRAW retrieve a range of duplicate values stored in a given key, using optional (inclusive) start/end-points key, start value (optional), end value (optional), count (optional) list of values (as bytestrings)
KEYS retrieve a range of keys using optional inclusive start/end-points start key (optional), end key (optional), count (optional) list of keys
PREFIX retrieve a range of key/value pairs which match the given prefix prefix, count (optional) list of [key, value] lists
VALUES retrieve a range of values using optional inclusive start/end-points start key (optional), end key (optional), count (optional) list of values
Client commands
QUIT disconnect from server (none) int: 1
SHUTDOWN terminate server process from client (be careful!) (none) (none)

protocol

The protocol is the Redis RESPv3 protocol. I have extended the protocol with one additional data-type, a dedicated type for representing UTF8-encoded unicode text (notably absent from RESPv3). This type is denoted by the leading ^ byte in responses.

Details can be found here: https://github.com/antirez/RESP3/blob/master/spec.md

Metadata

Release files for greendb 0.2.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for greendb 0.2.6
File Size Uploaded
greendb-0.2.6.tar.gz 22.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for greendb 0.2.6
File Interpreter ABI Platform
greendb-0.2.6-py3-none-any.whl Python 3 none any Details

Total release size: 43.9 kB

Release files / greendb-0.2.6.tar.gz

Download URL greendb-0.2.6.tar.gz
Size 22.0 kB
Tags Source
SHA-256 checksum
How to use checksums
48a618d87621d04bfc6703ec865e13a0c32bf2d8e2468712ac9fc34360d505d3
BLAKE2b-256 checksum
How to use checksums
369b78845afd4624912c3cfc26aab8b2bbc09c212d3e88a93815984f08adc809
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / greendb-0.2.6-py3-none-any.whl

Download URL greendb-0.2.6-py3-none-any.whl
Size 21.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1dcf8288d4e45ebc3f7984d71aaa2c23918044809b89d30916d25f321894ecef
BLAKE2b-256 checksum
How to use checksums
a1e6bf68274d300fcbfae3d3afea8b72618393410d3d9e5fcf2b36f0961fdbb4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release history Release notifications | RSS feed

This release

0.2.6 This release

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

1 release file

0.2.2

1 release file

0.2.1

1 release file

0.2.0

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page