Extensible command syntax
dustin at spy.net
Tue Nov 13 06:23:15 UTC 2007
On Nov 8, 2007, at 2:35, Tomash Brechko wrote:
>> I fail to see what I'm missing. As far as I can tell, you're
>> describing what I already do. See my write up on client optimization
>> and let me know what I'm missing.
> According to this page, when several threads issue [a], [b], [a, b,
> c], [a], [d], you combine this requests into the one, [a, b, c, d].
> Alright, suppose you got the reply, [c, d]. How do you know what to
> reply to each thread? You have to compare keys in client side to know
> what results you have got. But if the reply was [nil, nil, c, d],
> you'll have to compare only numbers: first goes to t1, t3, t4, second
> goes to t2. t3, etc.
In the binary protocol, you do only use numbers (keys aren't
returned). In the text protocol, you do string compares on the
results. In both cases I use a hash table. If it ever bubbles up in
my profiler, I might try to make it more efficient, but in the
meantime, it doesn't seem to matter much.
> What matters is _overall_ throughput, not solely server performance.
> If you optimize the server at the cost of additional work on all
> clients, it's not good.
If you optimize the server at the cost of additional work on the
clients, you're optimizing the more centralized resource at the cost
of the less centralized resource. The server absolutely has to be the
most optimal part of the whole thing for this very reason.
That's not to say the optimization of other components should be
ignored, but I have not found any dissatisfaction in my ability to
optimize things with the existing protocol.
>> In the text protocol, a get with several keys only returns hits and
>> an end marker. The idea is that if you're issuing that request,
>> you're probably going to return some kind of dictionary structure to
> This "probably" comes from no where, and is a bad assumption for the
> generic design. Client might not need to have the dictionary, and
> currently it is forced to have it.
Does any client out there do a multi-get for a series of keys and not
return values mapped to those keys?
>> Ah, well in the general case, there's no processing to do for not
>> found keys.
> As follows from your page, t1 that has requested [a] would have to
> wait until [d] is processed, while it could continue once [nil] for
> [a] has been returned.
> On the page you should also describe the drawbacks of single
> I/O-thread approach: that threads effectively block each other. For
> instance, high-priority t5 asking for small data for [d] would be
> blocked by low-priority t1 asking for large data for [a].
I don't see that as a drawback. If you actually had different
priorities for different request types and determined that you were
actually running into a blocking condition as such that caused a
latency problem, you could just use different client instances and
it'd go away immediately. Alternatively, if anyone cared, I could
implement a priority concept for requests.
It had been suggested that I allow multiple connections per
destination per client to reduce latency. I experimented with a
branch doing that, but I wasn't able to measure a difference (I think
you need more computers than I have available for such a test).
Whichever way you look at it, it's only a drawback to the single IO
thread approach if you can demonstrate that my IO thread is somehow
limiting the throughput.
It seems like memcached has historically been single threaded for
most installations, and as far as I can tell, when it's multithreaded
it's not because one thread can't keep IO buffers full.
More information about the memcached