Boost logo

Boost :

Subject: Re: [boost] ACID transactions/flushing/MySQL InnoDB
From: Dean Michael Berris (mikhailberis_at_[hidden])
Date: 2009-12-12 10:01:50


On Sat, Dec 12, 2009 at 8:00 PM, Stefan Strasser <strasser_at_[hidden]> wrote:
>
> in case you're interested, I now get about 5000 synced small transactions/s.
> with a theoretical maximum of about 7000, but the 5000 are including the data
> writes and the writing-ahead to zero out the data and make sure the log file
> doesn't grow on each transaction sync.

That's cool. :)

> thanks again.

Glad to be of help.

>
> there are some more weird conditions to get sequential writing performance,
> e.g. when you write with the following sync intervals, starting from offset 0
> and "|" representing syncs:
>
> 512 | 2048 | 512 | 512 | 512 | ...
>
> performance is much much worse than:
>
> 512 | [1536] | 2048 | 512 | 512 | ...
>
> with 1536 bytes of garbage inserted so the 2048-bytes block can be written
> aligned to its own size. and yes, the sync after writing the garbage is
> necessary.
>

One other thing you can do is to pack the data into 512-byte divisible
chunks. If you know you're writing 2048 in one go, then you might have
to align to 512-byte chunks. Instead of writing "garbage" you can pack
null bytes past the 2048 bytes you originally wanted to store. It also
helps if you can deal with a memory pool with fixed-chunk recyclable
arrays so that you can leverage processor-cache locality for the bytes
you are going to eventually pass to the kernel -- which it will
eventually copy (unfortunately).

>
>> Sounds like a good approach. If you're thinking of multi-threading and
>> having an active object do the flush management, that should be
>> something worth looking into to move the latency from persistence away
>> from "worker" threads to a single serializing writer thread.
>
> I've tried something like that, still synced by the worker threads but the
> sync is lock-free, so in theory the threads could meet at the sync call and
> if there were no writes between the sync calls, the OS could decide to
> perform only one of them. but it doesn't have large effects, about 5200 txs/s
> with 10 threads (on single CPU).
> I guess you could improve multithreaded performance a lot if you yield the
> thread right before the sync and only sync in one thread if threads meet at
> that point. but I haven't looked into this and I don't plan to right now.

The buffer packing algorithm that I describe above could be done on a
single thread (the active object's lifetime thread) and the write/sync
done appropriately. I imagine the cost of context switching is
mitigated by the improved worker-thread free-up because it doesn't
need to wait for a transaction to be actively committed after it has
passed it to the active object.

I'm not sure if this is part of the requirements in your design or
whether you want client threads to really block on transaction commits
(even though the syncing is lock-free).

HTH

-- 
Dean Michael Berris
blog.cplusplus-soup.com | twitter.com/mikhailberis
linkedin.com/in/mikhailberis | facebook.com/dean.berris | deanberris.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk