3 ms·
Using the Redis protocol doesn't seem like the most efficient way to implement a fast client/server architecture. The Redis protocol[1] is text-based, where eac
by thamer 5y ago
Using the Redis protocol doesn't seem like the most efficient way to implement a fast client/server architecture. The Redis protocol[1] is text-based, where each command is an array with a header describing the number of elements in the command, and each element is prefixed by `$` and its length, with abundant \r\n to separate all those (this is a simplification, but almost all commands sent to Redis follow this array format).
For example, to send "SET my-key hello" to Redis, this is a 3-element array (the initial *3) with elements of length 3, 6, and 5. So you'd send:
*3\r\n
$3\r\n
SET\r\n
$6\r\n
my-key\r\n
$5\r\n
hello\r\n
(^ all of those would be joined together, this is presented on multiple lines for readability)
Decoding lengths from their textual representation is inefficient in both space and time, and the various \r\n add to the request and response sizes without adding anything useful to a program that uses it (it is of course useful for humans typing those commands, but who does that?).
Even using something as common as protobuf would likely be more efficient, with smaller requests and responses – although object creation can lead to memory pressure for complex messages.
But really, since Elixir leverages Erlang, why not have a basic common protocol with pattern matching on binaries? This would make a lot more sense than using a text-based protocol, in my opinion.
[1] https://redis.io/topics/protocol https://redis.io/topics/protocol
- eternalban 5y agoOne of the things, among many then unique features, that charmed me about Redis when I first encountered it when it first surfaced (2008?) was the ability to open a telnet session to Redis and type commands see the responses. It also hugely helped in writing drivers for it. As to your intuition (“seems”), the fact is that Redis is a very high performance server. I think the key is considering what fraction of time of servicing a request is spent on parsing the requests — given the network hop and other non-protocol computations, it is likely to be negligible.
- latch 5y agoI think Redis would have been successful even without a text-heavy protocol. Redis took a middle ground and [ascii]-length prefixed responses (though I don't think it was initially like this). That's a reasonable and likely necessary compromise. A bit similar to how HTTP can include a content-length. You'd hate to be scanning large payloads for that trailing \r\n. So Redis terminates with \r\n (which isn't strictly necessary for all message types) and ascii encodes the types and length prefix. Everything else is just bytes. Here's (1) a paper that looked at text vs binary protocols. They looked at it in the context of MonetDB though, which has, by far, the worse text-based protocol I've ever seen (so much so that even their official drivers have (had?) plenty of protocol-related bugs) (1) - https://15721.courses.cs.cmu.edu/spring2018/papers/14-networking/p1022-muehleisen.pdf https://15721.courses.cs.cmu.edu/spring2018/papers/14-networ...
- thamer 5y agoAh yes I remember trying out Redis with telnet, it was helpful at the very beginning. Thankfully command-line clients came around soon enough. Also, the protocol as it is today was only introduced in Redis 1.2, and wasn't around at the very beginning. It's true that the parsing time is small compared to the network round-trip, but Redis being single-threaded means that while it's parsing a large nested command and allocating memory as it goes through it… well nothing else is being processed. I'm pretty familiar with the costs of parsing this protocol, being the original author of the phpredis extension. Written in C, it's a high-performance client whereas pure-PHP clients can't use the same zero-copy tricks or careful memory management in general to avoid repeated calls to strlen/malloc/memcpy/free (in that order). In Webdis – another high-performance Redis tool I wrote – protocol parsing with Hiredis is similar to HTTP parsing in the sense that it's where most CPU cycles are spent. I'm not really sure why Salvatore chose to keep the text-based protocol when his focus was so often on performance. I'm not aware of any attempts made by him or other people to change the protocol, but it would be interesting to see how much of a difference this could make.
- eternalban 5y agoIIRC he did discuss his decision in the redis google group - don’t recall the details.