Hi Haldun,
The protocol is not very well documented right now, but I do want to
support clients that aren't in java. Rather than document the protocol
and try to maintain n clients in sync as we evolve the protocol I was
thinking that the best approach would be to change the on-wire
serialization format for things like the vector-clock versions to use
protocol buffers. I don't really know the performance implications of
this, but a coworker of mine did some evaluation and it didn't look at
all unreasonable
(
http://eishay.blogspot.com/2008/11/protobuf-with-option-optimize-for-speed.html).
The default for the java client is to handle a lot of the routing and
failure responsibility, but an initial python client need not be so
ambitious. An initial version could do no client side routing and use
the HTTP-based protocol we have. So a client would look like this:
1. Connect to one of a list of "bootstrap servers" and do an
HTTP-based voldemort request to get the cluster and store metadata to
get the list of nodes and stores
2. Use protocol buffers code to deserialize the vector clock version
that comes with values and handle the fact that many versions might be
returned
3. Round robin requests over servers and let the server handle correct
routing and version reconciliation
The responsibility of the minimum viable client would be constructing
the request/response objects and issuing HTTP GET, POST, and DELETE
operations for the voldemort get, put, and delete operations. This
would be a fairly achievable implementation effort and would still let
us evolve the protocol (since protocol buffers is fairly good at
compatibility).
I have put a little thought in to this, but didn't want to start until
I had a potential non-java client to try out. It sounds like you are
digging around and ready to write some code. If I created a branch in
which I swapped out the current protocol for protocol buffers objects
would you be interested in taking a shot at a python client based on
that?
-Jay
Here would be a very rough attempt at a protocol buffers protocol:
package voldemort;
option java_package = "voldemort.serialization.version";
message ClockEntry {
required int32 node_id = 1;
required int64 version = 2;
}
message VectorClock {
repeated ClockEntry entries = 1;
optional int64 timestamp = 2;
}
message Versioned {
required bytes value = 1;
required VectorClock version = 2;
}
message Error {
required int32 error_code = 1;
required string error_message = 2;
}
message KeyedVersions {
required bytes key = 1;
repeated Versioned versions = 2;
}
message GetRequest {
optional int32 from_node = 1 [default = -1];
optional bool should_route = 2 [default = false];
repeated bytes ids = 3;
}
message GetResponse {
repeated KeyedVersions items = 1;
optional Error error = 2;
}
message PutRequest {
optional int32 from_node = 1 [default = -1];
optional int32 to_node = 2 [default = -1];
optional bool should_route = 3 [default = false];
optional bytes key = 4;
optional Versioned versioned = 5;
}
message PutResponse {
optional Error error = 1;
}
message DeleteRequest {
optional int32 from_node = 1 [default = -1];
optional int32 to_node = 2 [default = -1];
optional bool should_route = 3 [default = false];
optional bytes key = 4;
optional VectorClock version = 5;
}
message DeleteResponse {
optional bool success = 1;
optional Error error = 2;
}
enum RequestType {
GET = 0;
PUT = 1;
DELETE = 2;
}
message VoldemortRequest {
required RequestType type = 1;
optional GetRequest get = 2;
optional PutRequest put = 3;
optional DeleteRequest delete = 4;