Re: Parallel serialization and writes ? (Was: ACIDity of Prevayler 2.6)
Arnaud Masson <[email protected]> Sun, 18 Nov 2012 11:09:25 +0100
| Newsgroups | gmane.comp.java.prevayler |
|---|---|
| Message-ID | <[email protected]> |
Yes, I agree that my "one byte" example was a bit ambiguous! :)
Disk latency won't change if you are under some threshold.
1) 50ms-100ms seems a large value (especially on SSD).
On my system,
try (FileOutputStream os = new FileOutputStream(f)) {
os.write('A');
os.getFD().sync(); // like DurableOutputStream.java
} // close
takes about 2ms on average (because of OS caches?).
I don't know how to flush "harder" from java code anyway.
(NB: I'm not sure if sync() is required in this example since the stream
is closed.)
2) "Adding ... latency to _every_ query"
This is the worst case scenario, isn't it?
In a typical webapp, that would mean that every time a user GET a page,
someone sends a mutating POST request at the same time...
And if there is no pending tx, queries don't have to wait for disk.
On 18/11/2012 02:06, Justin T. Sampson wrote:
> Rather than responding in detail, I'd just like to quickly explain a
> couple of points that I've so far just been hinting at.
>
> First, remember that whether you're writing 1 byte or 1000 bytes, the
> latency is really the same. Disks typically write in blocks of, say, 8K.
> The latency of serializing a transaction to an in-memory buffer is
> really pretty trivial compared to the latency of actually writing that
> buffer or even a tiny marker to disk. That's where the inherent latency
> of transactions vs. queries comes from. Prevayler already maximizes the
> throughput of transactions by batching lots of transactions together in
> a single disk write, but the latency (50-100ms) is unavoidable.
>
> Second, let's make sure we're on the same page about why queries would
> also have to be slow if transactions were written to disk _after_
> execution. Between the time a transaction executes and the time it (or
> its commit marker) is written to disk, any changes it caused must be
> considered uncommitted. We don't ever want uncommitted changes to be
> seen by the user. It's actually fine for queries to execute against
> uncommitted data (isolation is guaranteed by Prevayler's simple locking
> model) as long as the results aren't actually returned until all the
> transactions preceding that query are committed. Each batch of
> transactions actually being written to disk effectively "releases" the
> results of those transactions _and_ any queries that were interleaved
> with them.
>
> Let's say our disk write latency is 100ms (pretty close to the truth),
> and let's say the actual execution of a query or transaction is
> instantaneous (also pretty close to the truth). As Prevayler currently
> works, queries don't wait for disk writes and therefore execute and
> return near-instantaneously. Each transaction arrives somewhere in the
> middle of a prior batch being written to disk, so it has to wait for, on
> average, 50ms for that batch to finish writing and an additional 100ms
> to be written itself, for an average latency of 150ms. If transactions
> were to be written to disk after execution, their latency would stay the
> same but queries would also have to wait an average of 150ms before
> returning their results.
>
> That's actually pretty significant. Adding 150ms latency to every query
> means adding _at least_ 150ms latency to every page-load in a webapp,
> for example. A typical target for reasonable responsiveness is less than
> 200ms _total_ from the user clicking to the user seeing the result
> rendered in the browser. Of course, most apps come nowhere near
> achieving that level of responsiveness; if you already have 5s page-load
> times then your users might not notice an extra 150ms. But if you're
> down around 200ms, an extra 150ms would make the difference between
> "Wow, this app is fast," and "Ugh, this app is slow."
>
>
> On Sat, Nov 17, 2012 at 12:56 PM, Arnaud Masson <[email protected]
> <mailto:[email protected]>> wrote:
>
> It's a bit like my last email, because there are 2 phases:
>
> write "unfinished" tx in journal --> mark tx as completed
> vs
> prepare capsule --> write capsule
>
> Tx execution on in-memory model is during or after the 1st phase.
>
> The key point is that the first phase doesn't have to block incoming
> queries, while second phase must block them because the in-memory model
> has already been changed, so the tx must be made "durable" before its
> effects are visible by new queries.
>
> So it adds latency for (some) queries, the latency of the 2nd phase.
> That's why as much work as possible should be done in the 1st phase,
> while the 2nd phase should be as short as possible (e.g. write just one
> byte in the journal on disk).
>
> (With 2 "twin" in-memory models, I think it's possible to have both
> journal correctness and no IO latency on queries, but you need more
> RAM...)
>
>
> On 17/11/2012 16:27, Paul Bennett wrote:
> > I've been pouring through the code (version 2.3), both to
> understand in
> > more details, and see if it is possible to serialize and write
> > transactions completely in parallel with execution. I *think* I
> > understand what is happening, and want to offer a possible
> explanation
> > and implementation
> >
> > It seems to me that as a general principle, if you can order
> writes to
> > the journal in the same order as transaction execution, there is no
> > reason why you cannot do the two in parallel. It would mean that the
> > system state could get ahead of the log by
> > multiple transaction executions, but as long as this is bounded, it
> > doesn't violate the persistence invariants (I'm trying to stay
> away from
> > the term 'ACID' :-) - the system would still restore properly up
> to the
> > point of last write. The only transactions lost would be the ones
> > waiting to be written, which would by definition be bounded -
> probably
> > by a system parameter or some kind of heuristic
> >
> > So how would you do that? As I understand it now, Prevayler orders
> > journal serialization and write first, using the Guide's
> Turn,then use
> > that ordering to drive transaction execution (and interleaving
> queries
> > with that). So how would it be if that were reversed? Transaction
> would
> > arrive and be dispatched to a parallel journal-writing thread,
> and then
> > go on to execute, ordered as is done now. The writing thread would
> > prepare the transaction for writing (create the Capsule), then
> wait for
> > a signal from the transaction execution before actually writing it
> > (actually, that would be the publish operation, so that other
> publishers
> > (e.g ClientPublish) would get the same ordering).
> >
> > All that is required to do this is a reference in
> > the transaction execution that references the to-be-created Capsule.
> > When transactions executes, their references are queued in the same
> > order, so that the writing thread can examine that queue each
> time it is
> > done with preparation - it then decides if it has the Capsule
> referred
> > to by the head of the queue ready for writing. If it does, it removes
> > the reference and writes the Capsule, if not it goes back to
> preparing
> > more capsules. You might even prepare each Capsule on it's own
> thread,
> > and match Capsule creation and queue head each time one finishes. You
> > would not have more threads than there are CPU cores, with an amount
> > left over for user threads.
> >
> > It seems that this would remove the journal write and serialization
> > latency from transactions in the same way as is now done for queries,
> > while still maintaining the correct ordering and persistence
> guarantees.
> >
> > What did I miss ?
> >
> > -pb
> >
> >
> > On Nov 17, 2012, at 2:44 AM, Justin T. Sampson wrote:
> >
> >> Arnaud -- You've got things a bit backwards. Yes, larger
> latencies are
> >> acceptable for transactions than for queries, but that's exactly how
> >> Prevayler behaves: Queries execute and return immediately whereas
> >> transactions have to wait for writing to disk before executing and
> >> returning. If transactions were written to disk after executing,
> then
> >> both queries and transactions would execute immediately but both
> would
> >> wait for writing to disk before returning. Throughput would be
> >> similar, but query latency would be worse than it is now.
> >>
> >> Transactions are already serialized concurrently (in memory) without
> >> holding any locks, so don't worry about that. And the journal is
> >> written as a continuous stream, not individual files, so
> >> moving/renaming is not an option (and would be significantly
> slower).
> >>
> >>
> >> On Fri, Nov 16, 2012 at 2:06 AM, Arnaud Masson
> <[email protected] <mailto:[email protected]>
> >> <mailto:[email protected] <mailto:[email protected]>>> wrote:
> >>
> >> Many systems have much more queries than transactions,
> >> so transaction latency wouldn't be so critical.
> >>
> >> Moreover a transaction could be physically pre-serialized
> (or maybe in
> >> parallel thread) on the disk, in some temporary location,
> before the
> >> lock scope.
> >> After tx successful execution, just a quick "file move/rename"
> >> operation
> >> would be required to commit it to the journal, not a full
> >> serialization.
> >>
>
>
>
> ------------------------------------------------------------------------------
> Monitor your physical, virtual and cloud infrastructure from a single
> web console. Get in-depth insight into apps, servers, databases, vmware,
> SAP, cloud infrastructure, etc. Download 30-day Free Trial.
> Pricing starts from $795 for 25 servers or applications!
> http://p.sf.net/sfu/zoho_dev2dev_nov
>
>
>
> _______________________________________________
> To unsubscribe go to the end of this page: http://lists.sourceforge.net/lists/listinfo/prevayler-discussion
> _______________________________________________
> "Databases in Memoriam" -- http://www.prevayler.org
>
------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
To unsubscribe go to the end of this page: http://lists.sourceforge.net/lists/listinfo/prevayler-discussion
_______________________________________________
"Databases in Memoriam" -- http://www.prevayler.org