async-aof-write

we are suffering ``Latency due to AOF and disk I/O`` (see: http://redis.io/topics/latency)

redis has already use a single thread to do ``fsync``, but ``write`` still would block, we use::

    sudo strace -f -p $(pidof redis-server) -T -e trace=fdatasync,write 2>&1 | grep -v '0.0' | grep -v unfinished

watch a ``write`` block more than **2 seconds**.

so I think can we use async-thread to write aof to avoid the main working thread block,

this patch do so, here is the test script and result::

    $ cat 2.8.12.conf
    appendfilename appendonly.2.8.12
    appendonly yes
    port 12000
    $ cat async.conf
    appendfilename appendonly.async
    appendonly yes
    port 12001

    $ cat run-test.sh
    pkill -f 1200
    rm appendonly.*
    rm *.latency
    rm *.qps

    sleep  1

    ../src/redis-server.2.8.12 ./2.8.12.conf &
    ../src/redis-server.async  ./async.conf &

    sleep  1

    ../src/redis-cli -p 12001 set k1 v1
    ../src/redis-cli -p 12000 set k0 v0

    ../src/redis-benchmark --csv -n 10000000 -p 12000 -t set > 2.8.12.qps&
    ../src/redis-benchmark --csv -n 10000000 -p 12001 -t set > async.qps&

    dd if=/dev/zero of=xxxxx bs=1M count=10000 &

    ../src/redis-cli --latency-history -p 12000 >2.8.12.latency &
    ../src/redis-cli --latency-history -p 12001 >async.latency  &

and here is the result::

    $ tail -f 2.8.12.latency
    min: 0, max: 35, avg: 0.18 (1447 samples) -- 15.00 seconds range
    min: 0, max: 49, avg: 0.15 (1458 samples) -- 15.01 seconds range
    min: 0, max: 20, avg: 0.14 (1468 samples) -- 15.01 seconds range
    min: 0, max: 1, avg: 0.12 (1473 samples) -- 15.01 seconds range
    min: 0, max: 91, avg: 0.19 (1416 samples) -- 15.00 seconds range
    min: 0, max: 495, avg: 0.62 (1388 samples) -- 15.00 seconds range
    min: 0, max: 20, avg: 0.23 (1416 samples) -- 15.00 seconds range
    min: 0, max: 1885, avg: 3.61 (1087 samples) -- 15.01 seconds range
    min: 0, max: 772, avg: 0.66 (1435 samples) -- 15.76 seconds range
    min: 0, max: 602, avg: 0.80 (1359 samples) -- 15.01 seconds range
    min: 0, max: 1, avg: 0.16 (1465 samples) -- 15.01 seconds range
    min: 0, max: 2, avg: 0.37 (1432 samples) -- 15.01 seconds range

    $ tail -f async.latency
    min: 0, max: 2, avg: 0.10 (1461 samples) -- 15.00 seconds range
    min: 0, max: 1, avg: 0.10 (1461 samples) -- 15.01 seconds range
    min: 0, max: 12, avg: 0.13 (1467 samples) -- 15.00 seconds range
    min: 0, max: 1, avg: 0.12 (1472 samples) -- 15.00 seconds range
    min: 0, max: 1, avg: 0.10 (1409 samples) -- 15.01 seconds range
    min: 0, max: 3, avg: 0.17 (1443 samples) -- 15.01 seconds range
    min: 0, max: 1, avg: 0.10 (1460 samples) -- 15.00 seconds range
    min: 0, max: 1, avg: 0.11 (1470 samples) -- 15.01 seconds range
    min: 0, max: 11, avg: 0.13 (1441 samples) -- 15.01 seconds range
    min: 0, max: 6, avg: 0.16 (1435 samples) -- 15.00 seconds range

    $ cat 2.8.12.qps
    "SET","56891.23"
    $ cat async.qps
    "SET","61486.62"

so the async-aof patch give us stable latency, and higher qps.

the test is run on a 8 cpu machine with traditional hdd.