twitter/twemproxy — pull request #191 by Almasty (2014-01-07 09:25:20+00:00)
Title: Memcache binary protocol support

The changes are split into three commits:
- one for the changes in the engine
- one for the configuration tweaks to support more protocols than memcache text and redis protocols
- one for the memcache binary dedicated protocol functions (parsers, split, coalesce, etc)

The binary protocol recommendation for multi-get request implementation is to send one silent get request per key to retrieve, followed by a noop packet per targeted server. Most of the changes in the engine are performed to support buffering of the silent get requests within a multi-get request and to flush the buffer once a NOOP or standard get is received (actually, any other request received on the client connection will flush the buffered requests to the servers). As some memcache clients send the silent get requests and the NOOP packet in two distinct write operations, the fragment management logic had to be duplicated in the request filtering process where the buffering operations are done.

The parsing logic works by parsing chunks of data rather than tokenizing a string by iterating on its characters. The format of a request is defined in the protocol: there is a header optionally followed by extra data, a key and a value (any data chunk other than the header can be empty).

One additional point with the recommended multi-get implementation in memcache binary protocol is that memcache servers won't send replies to silent get requests if the requested data is not found on the server, which does not match the all-or-nothing noreply logic of twemproxy. Therefore, the parser changes on the fly the GETQ/GETKQ opcodes to GET/GETK, and the pre-coalesce logic reverts them to GETQ/GETKQ in order to ensure every get request in the multi-get operation gets a response from the server.