Skip to content

nicholasamorim/brainer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Brainer

Brainer is a simple distributed caching mechanism implemented under the constraint of 48 hours and with no previous experience in the matter at all.

It uses Twisted and ZeroMQ. The client is synchronous.

This is not in any way intended to be used as production or anything. It is pre-alpha and will never cease to be as it was just an exercise.

How it Works (or really: Trade-Offs)

It has a broker-based approach. Obviously, this is a single point of failure. This architecture was chosen due to my lack of experience with ZeroMQ and the 48 hours constraint but it's certainly not ideal. The good news is that with the current code it should not be hard to make it work in a more ring-based approach.

To solve both the resiliency (losing a node without losing data) and the no downtime problem (adding or removing nodes with no downtime), writes are costly.

When writing, all nodes get written. The client can tune this behaviour, though.

The default write behaviour writes to all nodes before returning to the client. You can disable that and make the broker return as soon as the main node has been writen (main in the sense of right node picked by the hashing scheme).

That means that when a node goes down, all other nodes will have that data anyway, so they'll just implicitely assume it when the hashing now starts returning a different machine number.

When a node goes up, the broker requests a snapshot of the cache from any other node and returns that back to the node, which then replay it.

I've aimed for best engineering practices. So a lot of things are easily achieved in the future. A good example is the Cache itself. You can easily code a custom behaviour storage that writes to disk every N writes and fire up a node with it.

But there are still things that can be decoupled around the code. One of them is the node management itself (registering, unregistering, etc) that is in the Broker class. The code also deserves yet another round of refactoring to minimize some code repetition.

Finally, this is by no means, a robust implementation. There are no retries on failed writes and the test suite is quite basic, for example.

But honestly, given the timeframe, I'm fairly happy with it.

Install (optional)

python setup.py install

run_broker, run_node and brainer-cli will be available as binaries in the path after that. But that is optional, you can simply run them from inside the source folder as well.

Run the Broker

./run_broker --debug

The broker by default runs on ipc:///tmp/broker.sock. You can change it by using --broker argument.

Run a Node

./run_node --node-endpoint ipc:///tmp/node1.sock --debug

You can use the --broker argument to set where the broker is located. run_node assumes the default ipc:///tmp/broker.sock

Operations

You can use a (very) simple console client.

./brainer-cli ipc:///tmp/broker.sock set mykey myvalue
./brainer-cli ipc:///tmp/broker.sock get mykey

Or you can use a (very) simple client library.

from brainer.client import Brainer

client = Brainer('ipc:///tmp/broker.sock')
client.connect()
cient.set("mykey", "myvalue")
client.get("mykey")

About

A Toy Distributed Cache

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages