OS X 10.4.2, storing objects roughly over 32K ...
James Robinson
jlrobins at socialserve.com
Tue Aug 30 21:08:33 PDT 2005
On Aug 30, 2005, at 5:37 PM, Alex Stapleton wrote:
> This sounds suspiciously like a problem I reported a while ago. Do
> you get different behaviour depending on whether or not you have
> just restarted memcached before running the test? e.g. if you
> create the keys with smaller data first for example?
>
Started up memcached again, then ran the following script to test
timing stores of ever increasing payload sizes:
---
import memcache
import time
c = memcache.Client(['127.0.0.1:11211'])
for i in range(0,38000, 20):
if i % 50 == 0:
print 'did %d' % (i,)
val = 's' * i
t1 = time.time()
c.set(i,val)
t2= time.time()
if t2 - t1 > 1:
print "%d store took %d seconds" % (i, t2 - t1)
---
Here's the result. From payload size 0 to 32640 was under a second
each store + recv response, but ...
... [ boring part from 0 to 32300 snipped ]
did 32400
did 32500
did 32600
32660 store took 4 seconds
32680 store took 4 seconds
did 32700
32700 store took 4 seconds
32720 store took 4 seconds
32740 store took 4 seconds
32760 store took 4 seconds
32780 store took 4 seconds
did 32800
32800 store took 4 seconds
32820 store took 4 seconds
So, every store after some payload size very near 32660 tickles
something odd.
The MTU on the loopback device is 16384.
I restarted memcached and worked backwards, from payload size 32740
down to 32000, and once it got below 32660 again it got brisk again:
---
import memcache
import time
c = memcache.Client(['127.0.0.1:11211'])
for i in range(32740,32000, -20):
if i % 50 == 0:
print 'did %d' % (i,)
val = 's' * i
t1 = time.time()
c.set(i,val)
t2= time.time()
if t2 - t1 > 1:
print "%d store took %d seconds" % (i, t2 - t1)
---
32740 store took 4 seconds
32720 store took 4 seconds
did 32700
32700 store took 4 seconds
32680 store took 5 seconds
32660 store took 5 seconds
did 32600
did 32500
did 32400
did 32300
did 32200
did 32100
---
So it doesn't seem to be immediately related to being the first data
being sent over the wire. Stepping down from 32660 by increments of
one byte shows the pivot point at 32641 -- this size or higher things
go slowly.
I have since slightly altered memcached.c, going through all 4
permuntations of twiddling TCP_NODELAY and TCP_NOPUSH on and off on
the server socket in function server_socket(), but these have no
effect upon this symptom. Neither did doing the same thing on newly
accepted client sockets (just in case OS X didn't copy the server
socket options over to the accepted connection sockets).
Bumping both the TCP_SNDBUF and TCP_RCVBUF from default 32K to 64K on
the newly accepted socket connection had no discernible effect.
Neither did twiddling the TCP_NOWAIT, SO_SNDBUF and SO_RCVBUF values
on the client end. Turning TCP_NOPUSH off at the client end
definitely made things worse -- making payload sizes greater than the
MTU but 16K take 4 or more seconds for the total round trip, but
sparing those less than MTU size:
----
import memcache
import time
import socket
c = memcache.Client(['127.0.0.1:11211'])
c.get(0) # Force connection establishment.
method = c.servers[0].socket.setsockopt
for level, opt, val in (
(socket.SOL_SOCKET, socket.SO_SNDBUF, 32767*2),
(socket.SOL_SOCKET, socket.SO_RCVBUF, 32767*2),
(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1),
(socket.IPPROTO_TCP, 4, 1) # TCP_NOPUSH value gleamed from /
usr/include/netinet/tcp.h -- YMMV
):
method(level, opt, val)
for i in (32641, 32639, 16000, 14000, 18000, 32641, 32644,55000,
32641 * 2):
val = 's' * i
t1 = time.time()
c.set(i,val)
t2= time.time()
print "%d store took %d seconds" % (i, t2 - t1)
---
Yeilds:
32641 store took 4 seconds
32639 store took 5 seconds
16000 store took 0 seconds
14000 store took 0 seconds
18000 store took 10 seconds
32641 store took 5 seconds
32644 store took 9 seconds
55000 store took 5 seconds
65282 store took 9 seconds
----
So, the only effect I've had on things at all is enabling TCP_NOPUSH
on the client end, which makes things worse.
----
James Robinson
Socialserve.com
More information about the memcached
mailing list