annotate doc/threads.txt @ 3:0b6ac95a09bb default tip

Fix unix sockets support under FreeBSD.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 03 Oct 2007 05:34:42 +0400
parents 30782bb1fc04
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
1 Multithreading support in memcached
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
2
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
3 OVERVIEW
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
4
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
5 By default, memcached is compiled as a single-threaded application. This is
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
6 the most CPU-efficient mode of operation, and it is appropriate for memcached
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
7 instances running on single-processor servers or whose request volume is
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
8 low enough that available CPU power is not a bottleneck.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
9
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
10 More heavily-used memcached instances can benefit from multithreaded mode.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
11 To enable it, use the "--enable-threads" option to the configure script:
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
12
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
13 ./configure --enable-threads
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
14
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
15 You must have the POSIX thread functions (pthread_*) on your system in order
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
16 to use memcached's multithreaded mode.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
17
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
18 Once you have a thread-capable memcached executable, you can control the
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
19 number of threads using the "-t" option; the default is 4. On a machine
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
20 that's dedicated to memcached, you will typically want one thread per
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
21 processor core. Due to memcached's nonblocking architecture, there is no
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
22 real advantage to using more threads than the number of CPUs on the machine;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
23 doing so will increase lock contention and is likely to degrade performance.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
24
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
25
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
26 INTERNALS
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
27
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
28 The threading support is mostly implemented as a series of wrapper functions
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
29 that protect calls to underlying code with one of a small number of locks.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
30 In single-threaded mode, the wrappers are replaced with direct invocations
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
31 of the target code using #define; that is done in memcached.h. This approach
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
32 allows memcached to be compiled in either single- or multi-threaded mode.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
33
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
34 Each thread has its own instance of libevent ("base" in libevent terminology).
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
35 The only direct interaction between threads is for new connections. One of
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
36 the threads handles the TCP listen socket; each new connection is passed to
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
37 a different thread on a round-robin basis. After that, each thread operates
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
38 on its set of connections as if it were running in single-threaded mode,
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
39 using libevent to manage nonblocking I/O as usual.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
40
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
41 UDP requests are a bit different, since there is only one UDP socket that's
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
42 shared by all clients. The UDP socket is monitored by all of the threads.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
43 When a datagram comes in, all the threads that aren't already processing
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
44 another request will receive "socket readable" callbacks from libevent.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
45 Only one thread will successfully read the request; the others will go back
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
46 to sleep or, in the case of a very busy server, will read whatever other
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
47 UDP requests are waiting in the socket buffer. Note that in the case of
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
48 moderately busy servers, this results in increased CPU consumption since
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
49 threads will constantly wake up and find no input waiting for them. But
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
50 short of much more major surgery on the I/O code, this is not easy to avoid.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
51
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
52
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
53 TO DO
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
54
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
55 The locking is currently very coarse-grained. There is, for example, one
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
56 lock that protects all the calls to the hashtable-related functions. Since
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
57 memcached spends much of its CPU time on command parsing and response
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
58 assembly, rather than managing the hashtable per se, this is not a huge
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
59 bottleneck for small numbers of processors. However, the locking will likely
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
60 have to be refined in the event that memcached needs to run well on
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
61 massively-parallel machines.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
62
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
63 One cheap optimization to reduce contention on that lock: move the hash value
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
64 computation so it occurs before the lock is obtained whenever possible.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
65 Right now the hash is performed at the lowest levels of the functions in
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
66 assoc.c. If instead it was computed in memcached.c, then passed along with
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
67 the key and length into the items.c code and down into assoc.c, that would
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
68 reduce the amount of time each thread needs to keep the hashtable lock held.