reinventing the wheel: libmc
TRANSCRIPT
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Reinventing the wheel: libmc
Jan 23, 2015
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Outline
WordplayThe memcached family
Why reinventing the new wheelBad things of libmemcached
Design a new memcached clientThe ASCII protocol(get/set part)Module DiagramBufferWriterBufferReaderOther parts
Lessons I learnedTipsGreat Toolchain
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Outline
WordplayThe memcached family
Why reinventing the new wheelBad things of libmemcached
Design a new memcached clientThe ASCII protocol(get/set part)Module DiagramBufferWriterBufferReaderOther parts
Lessons I learnedTipsGreat Toolchain
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
The memcached family
▶ memcached (the memcached server-side software)
▶ memcache (typo and nickname)
▶ mc (nickname)
▶ libmemcached ( C/C++ client library)
▶ libmemcache (yet another C client library, DEAD since 2006)
▶ python-memcached (pure python client library)
▶ python-libmemcached (Cython client, library based onlibmemcached)
▶ cmemcached (alias of python-libmemcached)
▶ pylibmc (C-Extensions for Python by hand, based onlibmemcached)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Outline
WordplayThe memcached family
Why reinventing the new wheelBad things of libmemcached
Design a new memcached clientThe ASCII protocol(get/set part)Module DiagramBufferWriterBufferReaderOther parts
Lessons I learnedTipsGreat Toolchain
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Bad things of libmemcached
▶ Divergence of libmemcached between upstream and thebranch we use. (the “large split” feature)
▶ Complex
▶ Buggy
▶ (lib)memcached is a weird creature.http://hoborglabs.com/en/blog/2013/memcached-php
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Outline
WordplayThe memcached family
Why reinventing the new wheelBad things of libmemcached
Design a new memcached clientThe ASCII protocol(get/set part)Module DiagramBufferWriterBufferReaderOther parts
Lessons I learnedTipsGreat Toolchain
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Retrieval Commands
Request and Response
get <key>*\r\n
VALUE <key> <flags> <bytes>\r\n<data block>\r\n
Example
get foo bar baz\r\n
VALUE foo 0 3\r\nabc\r\nVALUE baz 0 5\r\nsimp.\r\nEND\r\n
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Storage Commands
Request and Response
<key> <flags> <exptime> <bytes>\r\n<data block>\r\n
STORED\r\n | NOT STORED\r\n
Example
set dou 0 0 10\r\n0123456789\r\nset ban 0 0 4\r\naoei\r\n
NOT STORED\r\nSTORED\r\n
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Outline
WordplayThe memcached family
Why reinventing the new wheelBad things of libmemcached
Design a new memcached clientThe ASCII protocol(get/set part)Module DiagramBufferWriterBufferReaderOther parts
Lessons I learnedTipsGreat Toolchain
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Design of libmc
PyClient
|
Client
| (1:1)
ConnectionPool
| (1:N)
Connection
/ | (1:1) \
BufferReader Parser BufferWriter
| (1:N)
DataBlock
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Outline
WordplayThe memcached family
Why reinventing the new wheelBad things of libmemcached
Design a new memcached clientThe ASCII protocol(get/set part)Module DiagramBufferWriterBufferReaderOther parts
Lessons I learnedTipsGreat Toolchain
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
BufferWriter
s s i z e t sendmsg ( i n t socket , con s t s t r u c t msghdr ∗message , i n t f l a g s ) ;
s t r u c t i o v e c {vo i d ∗ i o v b a s e ;s i z e t i o v l e n ;
} ;
s t r u c t msghdr {. . .s t r u c t i o v e c ∗msg iov ;s i z e t msg i o v l e n ;. . .
} ;
▶ UIO MAXIOV
▶ commitRead
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Outline
WordplayThe memcached family
Why reinventing the new wheelBad things of libmemcached
Design a new memcached clientThe ASCII protocol(get/set part)Module DiagramBufferWriterBufferReaderOther parts
Lessons I learnedTipsGreat Toolchain
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
BufferReader
+ Fixed + Flexible
+------------+------------+-----------------------+---------------
| 8192 recved| 8192 recved| more than 8192 recved | DataBlock ...
+----+----+-------+-------+---------------------------------------
|XXXX|OOOO|BB|BBBB|CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC| DataBlockSlice
|XXXX|OOOO|BB|BBBB|CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC| ...
+------------+------+------------+------------+-------------------
|VALU|foo | 0 0 20| value of foo value of foo valu| Token
|E | | | e of foo .....................| ...
|----+----+-------+-------------------------------+---------------
▶ peek / readUntil / skipUtil / readUnsigned / readBytes /skipBytes / (no rewind)
▶ token.size() in 0, 1, 2 / SmallVector
▶ predictive DataBlock size
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Outline
WordplayThe memcached family
Why reinventing the new wheelBad things of libmemcached
Design a new memcached clientThe ASCII protocol(get/set part)Module DiagramBufferWriterBufferReaderOther parts
Lessons I learnedTipsGreat Toolchain
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Other parts
▶ Parser as a finite-state machine (FSM)
▶ poll in ConnectionPool
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Outline
WordplayThe memcached family
Why reinventing the new wheelBad things of libmemcached
Design a new memcached clientThe ASCII protocol(get/set part)Module DiagramBufferWriterBufferReaderOther parts
Lessons I learnedTipsGreat Toolchain
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.
▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing▶ Lazy connecting.▶ GIL issue.▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.
▶ Avoid memory copy.▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing▶ Lazy connecting.▶ GIL issue.▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.
▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing▶ Lazy connecting.▶ GIL issue.▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.▶ SmallVector optimization.
▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing▶ Lazy connecting.▶ GIL issue.▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.
▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing▶ Lazy connecting.▶ GIL issue.▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error
▶ Server may refuse if too much data is “send”(sent) without“recv”-ing
▶ Lazy connecting.▶ GIL issue.▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing
▶ Lazy connecting.▶ GIL issue.▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing▶ Lazy connecting.
▶ GIL issue.▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing▶ Lazy connecting.▶ GIL issue.
▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing▶ Lazy connecting.▶ GIL issue.▶ gevent issue.
▶ man 2 recv: For TCP sockets, the return value 0 means thepeer has closed its half side of the connection.
▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing▶ Lazy connecting.▶ GIL issue.▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.
▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing▶ Lazy connecting.▶ GIL issue.▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.▶ write the right benchmark. bench order? dependency?
▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing▶ Lazy connecting.▶ GIL issue.▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.
▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tips
▶ Prefer “switch statements” to if-else condition.▶ “Exception” and “heap allocation” are slow in C++.▶ Avoid memory copy.▶ SmallVector optimization.▶ Undocumented “UIO MAXIOV” limit in iovec.▶ clean buffer on error▶ Server may refuse if too much data is “send”(sent) without
“recv”-ing▶ Lazy connecting.▶ GIL issue.▶ gevent issue.▶ man 2 recv: For TCP sockets, the return value 0 means the
peer has closed its half side of the connection.▶ write the right benchmark. bench order? dependency?▶ md5 is slow. bugfree fnv1 is hard to implement.▶ vim: Rip-Rip/clang complete + cpplint.py
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Outline
WordplayThe memcached family
Why reinventing the new wheelBad things of libmemcached
Design a new memcached clientThe ASCII protocol(get/set part)Module DiagramBufferWriterBufferReaderOther parts
Lessons I learnedTipsGreat Toolchain
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Great Toolchain
▶ CMake
▶ Valgrind
▶ Callgrind(valgrind –tool=callgrind) +kcachegrind/qcachegrind
▶ googletest
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Links I
libmc: https://github.com/douban/libmc
benchmark of libmc: https://gist.github.com/mckelvin/8ded053f6523931765d4
Improving performance of std::vector:http://fahrenheit2539.blogspot.com/2012/06/
introduction-in-depths-look-at.html
How to profile C++ application with Callgrind / KCacheGrind:http://baptiste-wicht.com/posts/2011/09/
profile-c-application-with-callgrind-kcachegrind.
html