The goal for this project is to implement a small distributed system, to get experience in cooperatively developing a protocol specification, and to get experience benchmarking a system.
You should do this project in groups of 2 or 3.
Notes and additions
- To enable writing the client in different languages, it is fine o.k. to implement a client interface and share the code for those interfaces rather than a binary library.
Due date
- The project is due on Thursday, September 25th at midnight
Groups
- This project must be done in groups of 2-3 people.
- Your group must partner with one other group (or two if we have add odd number of groups).
Service
The service to provide is a simple key-value store, where keys and values are strings. You service should be as consistent as possible, so that requesting a value should return the most recently value set as often as possible. Furthermore, your service should recover from failures, so you will need to store data persistently.
There is no standard protocol. You must work with your partner group to create a protocol.
Client library
You must implement a client library to access key/value data. The interface is detailed in the specification below.
You will provide a shared library named "lib739kv.so" implementing the interface to your server. The client code must run on standard CS department workstations.
Here are the functions you must implement:
- int kv739_init(char *server) - provide the name of the server in the format "host:port" and initialize the client code. Returns 0 on success and -1 on failure.
- int kv739_get(char * key, char * value) - retrieve the value corresponding to the key. If the key is present, it should return 0 and store the value in the provided string. The string must be at least 1 byte larger than the maximum allowed value. If the key is not present, it should return 1. If there is a failure, it should return -1.
- int kv739_put(char * key, char * value, char * old_value) - Perform a get operation on the current value into old_value and then store the specified value. Should return 0 on success if there is an old value, 1 on success if there was no old value, and -1 on failure. The old_value parameter must be at least one byte larger than the maximum value size.
There are restrictions on keys and values:
- Keys are valid printable ASCII strings without special characters and are 128 or less bytes in length. They cannot include the "[" or "]" characters.
- Values are valid printable ASCII strings with neither special characters nor UUencoded characters and 2048 or less bytes in length. They cannot include the "[" or "]" characters.
Tests
You should write a test program that links against the shared library described above. You should write two kinds of tests:
- Correctness tests: ensure the code does what it is supposed to (including failure/recovery)
- Performance tests: measure the performance, as latency and throughput, for some workloads
You must test your code in three configurations
- Your tests, your library, your server.
- Your test, your partner's library, your server.
- Your partner's tests, your partner's library, your server.
Implementation
You may use any implementation language for the server and client, as long as it implements the required API and protocol. For example, you can use regular sockets, RPC Google's protocol buffers for communication between your servers, or an HTTP implementation.
What to turn in
You will turn in a short report describing your effort that includes:
- Your names, and the names of the members of your partner group
- A short discussion of how you implemented your client and server
- A specification of the protocol between client and server
- A description of the tests you wrote and an explanation why they are appropriate/suitable for testing your service. Please include the test methodology
- The results of the three sets of tests
Grading
Performance is not the primary concern of this project. We are instead interested in the ability to return consistent results under failure conditions.
For the writeup, we will look for these things:
- Does the writeup adequately describe the project?
- Does the design make sense?
- Does the described tests adequately test the guarantees of the design?
- Does the code interoperate correctly?