Coder Social home page Coder Social logo

akatrevorjay / summitdb Goto Github PK

View Code? Open in Web Editor NEW

This project forked from tidwall/summitdb

0.0 2.0 0.0 3.38 MB

In-memory NoSQL database with ACID transactions, Raft consensus, and Redis API

License: Other

Makefile 0.32% Shell 0.88% Go 98.80%

summitdb's Introduction

SummitDB

SummitDB is an in-memory, NoSQL key/value database. It persists to disk, uses the Raft consensus algorithm, is ACID compliant, and built on a transactional and strongly-consistent model. It supports custom indexes, geospatial data, JSON documents, and user-defined JS scripting.

Under the hood it utilizes Finn, Redcon, BuntDB, GJSON, and Otto.

Features

The goal was to create a fast data store that provides:

Getting started

Building SummitDB

SummitDB can be compiled and used on Linux, OSX, Windows, FreeBSD, and probably others since the codebase is 100% Go. We support both 32 bit and 64 bit systems. Go must be installed on the build machine.

To build simply:

$ make

It's a good idea to install the redis-cli.

$ make redis-cli

To run tests:

$ make test
```

### Running

First start a single-member cluster:
```
$ ./summitdb-server
```

This will start the server listening on port 7481 for client and server-to-server communication.

Next, let's set a single key, and then retrieve it:

```
$ ./redis-cli -p 7481 SET mykey "my value"
OK
$ ./redis-cli -p 7481 GET mykey
"my value"
```

Adding members:
```
$ ./summitdb-server -p 7482 -dir data2 -join :7481
$ ./summitdb-server -p 7483 -dir data3 -join :7481
```

That's it. Now if node1 goes down, node2 and node3 will continue to operate.

## Difference between SummitDB and Redis

*It may be worth noting that SummitDB is not a Redis clone. Redis has a lot of commands and data types that are not available in SummitDB, such Sets, Hashes, Sorted Sets, and PubSub.*

- **Ordered key space** - SummitDB provides one key space that is a large B-tree. An ordered key space allows for stable paging through keys using the [KEYS](https://github.com/tidwall/summitdb/wiki/KEYS) command. Redis uses an unordered dictionary structure and provides a specialized [SCAN](http://redis.io/commands/scan) command for iterating through keys.
- **Everything a string** - SummitDB stores only strings which are exact binary representations of what the user stores. Redis has many [internal data types](http://redis.io/topics/data-types-intro), such as strings, hashes, floats, sets, etc. 
- **Raft clusters** - SummitDB uses the Raft consensus algorithm to provide high-availablity. Redis provides [Master/Slave replication](http://redis.io/topics/replication). 
- **Javascript** - SummitDB uses Javascript for user-defined scripts. Redis uses Lua.
- **Indexes** - SummitDB provides an API for indexing the key space. Indexes allow for quickly querying and iterating on values. Redis has specialized data types like Sorted Sets and Hashes which can provide [secondary indexing](http://redis.io/topics/indexes).
- **Spatial indexes** - SummitDB provides the ability to create spatial indexes. A spatial index uses an R-tree under the hood, and each index can be up to 20 dimensions. This is useful for geospatial, statistical, time, and range data. Redis has the [GEO API](http://redis.io/commands/geoadd) which allows for using storing and querying geospatial data using the [Geohashes](https://en.wikipedia.org/wiki/Geohash).
- **JSON documents** - SummitDB allows for storing JSON documents and indexing fields directly. Redis has Hashes and a JSON parser via Lua.

<a name="in-memory-disk-persistence"></a>
## In-memory with disk persistence
SummitDB store all data in memory. Yet each writable command is appended to a file that is used to rebuild the database if the database needs to be restarted. 

This is similar to [Redis AOF persistence](http://redis.io/topics/persistence).


## JSON Indexes

Indexes can be created on individual fields inside JSON documents.

For example, let's say you have the following documents:

```json
{"name":{"first":"Tom","last":"Johnson"},"age":38}
{"name":{"first":"Janet","last":"Prichard"},"age":47}
{"name":{"first":"Carol","last":"Anderson"},"age":52}
{"name":{"first":"Alan","last":"Cooper"},"age":28}
```

Create an index:

```
> SETINDEX last_name user:* JSON name.last
```

Then add some JSON:
```
> SET user:1 '{"name":{"first":"Tom","last":"Johnson"},"age":38}'
> SET user:2 '{"name":{"first":"Janet","last":"Prichard"},"age":47}'
> SET user:3 '{"name":{"first":"Carol","last":"Anderson"},"age":52}'
> SET user:4 '{"name":{"first":"Alan","last":"Cooper"},"age":28}'
```

Query with the ITER command:

```
> ITER last_name
1) "user:3"
2) "{\"name\":{\"first\":\"Carol\",\"last\":\"Anderson\"},\"age\":52}"
3) "user:4"
4) "{\"name\":{\"first\":\"Alan\",\"last\":\"Cooper\"},\"age\":28}"
5) "user:1"
6) "{\"name\":{\"first\":\"Tom\",\"last\":\"Johnson\"},\"age\":38}"
7) "user:2"
8) "{\"name\":{\"first\":\"Janet\",\"last\":\"Prichard\"},\"age\":47}"
```

Or perhaps you want to index on age:

```
> SETINDEX age user:* JSON age
> ITER age
1) "user:4"
2) "{\"name\":{\"first\":\"Alan\",\"last\":\"Cooper\"},\"age\":28}"
3) "user:1"
4) "{\"name\":{\"first\":\"Tom\",\"last\":\"Johnson\"},\"age\":38}"
5) "user:2"
6) "{\"name\":{\"first\":\"Janet\",\"last\":\"Prichard\"},\"age\":47}"
7) "user:3"
8) "{\"name\":{\"first\":\"Carol\",\"last\":\"Anderson\"},\"age\":52}"
```

It's also possible to multi-index on two fields:

```
> SETINDEX last_name_age user:* JSON name.last JSON age
```

For full JSON indexing syntax check out the [SETINDEX](https://github.com/tidwall/summitdb/wiki/SETINDEX#json) and [ITER](https://github.com/tidwall/summitdb/wiki/ITER) commands.

Fencing Tokens
--------------
A fencing token is simply a number that increases. 
It's guaranteed to be consistent across the cluster and can never be deleted or decreased. 
The value is a 64-bit unsigned integer. The first FENCE call will return "1".
This is useful for things like distributed locking and preventing race conditions.

```
> FENCE mytoken
"1"
> FENCE mytoken
"2"
> FENCE mytoken
"3"
```


<a href="raft-commands"></a>
Built-in Raft Commands
----------------------
Here are a few commands for monitoring and managing the cluster:

- **RAFTADDPEER addr**  
Adds a new member to the Raft cluster
- **RAFTREMOVEPEER addr**  
Removes an existing member
- **RAFTPEERS addr**  
Lists known peers and their status
- **RAFTLEADER**  
Returns the Raft leader, if known
- **RAFTSNAPSHOT**  
Triggers a snapshot operation
- **RAFTSTATE**  
Returns the state of the node
- **RAFTSTATS**  
Returns information and statistics for the node and cluster

Consistency and Durability
--------------------------

SummitDB is tuned by design for strong consistency and durability. A server shutdown, power event, or `kill -9` will not corrupt the state of the cluster or lose data. 

All data persists to disk. SummitDB uses an append-only file format that stores for each command in exact order of execution. 
Each command consists of a one write and one fync. This provides excellent durability.

### Read Consistency

The `--consistency` param has the following options:

- `low` - all nodes accept reads, small risk of [stale](http://stackoverflow.com/questions/1563319/what-is-stale-state) data
- `medium` - only the leader accepts reads, itty-bitty risk of stale data during a leadership change
- `high` - only the leader accepts reads, the raft log index is incremented to guarantee no stale data. **this is the default**

For example, setting the following options:

```
$ summitdb --consistency high
```

Provides the highest level of consistency. The default is **high**.


Leadership Changes
------------------

In a Raft cluster only the leader can apply commands. If a command is attempted on a follower you will be presented with the response:

```
> SET x y
-TRY 127.0.0.1:7481
```

This means you should try the same command at the specified address.

Commands
--------

Below is the complete list of commands and documentation for each.

**Keys and values**  
[APPEND](https://github.com/tidwall/summitdb/wiki/APPEND), 
[BITCOUNT](https://github.com/tidwall/summitdb/wiki/BITCOUNT), 
[BITOP](https://github.com/tidwall/summitdb/wiki/BITOP), 
[BITPOS](https://github.com/tidwall/summitdb/wiki/BITPOS), 
[DBSIZE](https://github.com/tidwall/summitdb/wiki/DBSIZE),
[DECR](https://github.com/tidwall/summitdb/wiki/DECR), 
[DECRBY](https://github.com/tidwall/summitdb/wiki/DECRBY), 
[DEL](https://github.com/tidwall/summitdb/wiki/DEL),
[EXISTS](https://github.com/tidwall/summitdb/wiki/EXISTS),
[EXPIRE](https://github.com/tidwall/summitdb/wiki/EXPIRE),
[EXPIREAT](https://github.com/tidwall/summitdb/wiki/EXPIREAT),
[FLUSHDB](https://github.com/tidwall/summitdb/wiki/FLUSHDB),
[GET](https://github.com/tidwall/summitdb/wiki/GET), 
[GETBIT](https://github.com/tidwall/summitdb/wiki/GETBIT), 
[GETRANGE](https://github.com/tidwall/summitdb/wiki/GETRANGE), 
[GETSET](https://github.com/tidwall/summitdb/wiki/GETSET), 
[INCR](https://github.com/tidwall/summitdb/wiki/INCR), 
[INCRBY](https://github.com/tidwall/summitdb/wiki/INCRBY), 
[INCRBYFLOAT](https://github.com/tidwall/summitdb/wiki/INCRBYFLOAT), 
[KEYS](https://github.com/tidwall/summitdb/wiki/KEYS),
[MGET](https://github.com/tidwall/summitdb/wiki/MGET), 
[MSET](https://github.com/tidwall/summitdb/wiki/MSET), 
[MSETNX](https://github.com/tidwall/summitdb/wiki/MSETNX), 
[PDEL](https://github.com/tidwall/summitdb/wiki/PDEL),
[PERSIST](https://github.com/tidwall/summitdb/wiki/PERSIST),
[PEXPIRE](https://github.com/tidwall/summitdb/wiki/PEXPIRE),
[PEXPIREAT](https://github.com/tidwall/summitdb/wiki/PEXPIREAT),
[PTTL](https://github.com/tidwall/summitdb/wiki/PTTL),
[RENAME](https://github.com/tidwall/summitdb/wiki/RENAME),
[RENAMENX](https://github.com/tidwall/summitdb/wiki/RENAMENX),
[SET](https://github.com/tidwall/summitdb/wiki/SET), 
[SETBIT](https://github.com/tidwall/summitdb/wiki/SETBIT), 
[SETRANGE](https://github.com/tidwall/summitdb/wiki/SETRANGE), 
[STRLEN](https://github.com/tidwall/summitdb/wiki/STRLEN),
[TTL](https://github.com/tidwall/summitdb/wiki/TTL)


**Indexes and iteration**  
[DELINDEX](https://github.com/tidwall/summitdb/wiki/DELINDEX),
[INDEXES](https://github.com/tidwall/summitdb/wiki/INDEXES),
[ITER](https://github.com/tidwall/summitdb/wiki/ITER),
[RECT](https://github.com/tidwall/summitdb/wiki/RECT),
[SETINDEX](https://github.com/tidwall/summitdb/wiki/SETINDEX)

**Transactions**  
[MULTI](https://github.com/tidwall/summitdb/wiki/MULTI),
[EXEC](https://github.com/tidwall/summitdb/wiki/EXEC),
[DISCARD](https://github.com/tidwall/summitdb/wiki/DISCARD)

**Scripts**  
[EVAL](https://github.com/tidwall/summitdb/wiki/EVAL),
[EVALRO](https://github.com/tidwall/summitdb/wiki/EVALRO),
[EVALSHA](https://github.com/tidwall/summitdb/wiki/EVALSHA),
[EVALSHARO](https://github.com/tidwall/summitdb/wiki/EVALSHARO),
[SCRIPT LOAD](https://github.com/tidwall/summitdb/wiki/SCRIPT-LOAD),
[SCRIPT FLUSH](https://github.com/tidwall/summitdb/wiki/SCRIPT-FLUSH)

**Raft management**  
[RAFTADDPEER](https://github.com/tidwall/summitdb/wiki/RAFTADDPEER),
[RAFTREMOVEPEER](https://github.com/tidwall/summitdb/wiki/RAFTREMOVEPEER),
[RAFTLEADER](https://github.com/tidwall/summitdb/wiki/RAFTLEADER),
[RAFTSNAPSHOT](https://github.com/tidwall/summitdb/wiki/RAFTSNAPSHOT),
[RAFTSTATE](https://github.com/tidwall/summitdb/wiki/RAFTSTATE),
[RAFTSTATS](https://github.com/tidwall/summitdb/wiki/RAFTSTATS)

**Fencing tokens**  
[FENCE](https://github.com/tidwall/summitdb/wiki/FENCE)

## Contact
Josh Baker [@tidwall](http://twitter.com/tidwall)

## License

SummitDB source code is available under the MIT [License](/LICENSE).



summitdb's People

Contributors

tidwall avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.