This is the MulletDB project, a new database server that aims to use protocols, not storage, as the means of scaling a data store. It combines ZeroMQ with sqlite, tokyo cabinet, and the disk to create a server that can handle both NoSQL style storage needs, document storage needs, or SQL database models in one easy to use server.
Using ZeroMQ you can then mix and match multiple servers using various programming languages interacting with request/response or asynchronous models of communication in pretty much any topology you want.
SQL For Business, NoSQL For Partay!
The purpose of MulletDB is that data storage in multiple ways is trivial today because of freely available libraries to do it. With ZeroMQ the networking and scalable communications are already solved for us. With SQLite3 we have a great SQL database engine. With Tokyo Cabinet we have one of the best key=value stores, but nothing beats the disk.
With all that it's even easier to create a server that gives you the best of all worlds, and make it simple enough that if it doesn't do what you need, you can make it do what you need.
What Can It Do?
Right now you can:
- Store key=value data on disk or in RAM.
- Store documents with full text search retrieval.
- Do full SQL operations using SQLite3 with either a normalized JSON interface or direct SQL.
- Transfer data server side between them so you don't have to copy multiple times.
- Access the server using either Request/Response or Publish/Subscribe models of communication, and using N:M servers/clients.
- It should also be trivial to implement sharding, clustering, or other topologies using ZeroMQ proxies.
How's It Work?
Everything you send and receive from MulletDB is JSON over ZeroMQ. For the most part your client libraries don't need to care about this other than to parse the JSON into your own data structures and then use the ZeroMQ socket you need.
Here's a sample from the Python test suite for doing a SQL insert:
def test_insert(self):
res = sql.insert("test", values={"name": "Frank", "age": 70})
assert_valid(res)
assert_equal(res.rowcount(), 1)
res2 = sql.insert("test", values={"name": "Frank", "age": 70})
assert_valid(res2)
assert_equal(res.rowcount(), 1)
assert res._row_id < res2._row_id
And here's how that's implemented:
class Sql(object):
def __init__(self, session):
self.sess = session
def request(self, action, data):
return self.sess.request("sql." + action + " " + json.dumps(data),
klass=ResultSet)
...
def insert(self, table, values={}):
req = {"table": table, "values": values}
return self.request("insert", req)
That's literally the entire operation. Because what you send and receive is already JSON there's not much you need to do.
Is It Stable?
I started it to work on crapmania.com and as a joke, so it's barely stable right now. It probably leaks RAM and crashes, but it's also just a few weeks old.
Feel free to grab the source and take a look.
What's The License
It's AGPL so you're free to use it as long as everything it talks to is GPL.