News for hackers. Stuff that matters.
Re:Massively faster DB with async batching by skrebbel on Thursday January 26, 2012 @07:46AM (#3513872)
This appears to me as a ridiculously good idea. I've no clue whether it's really novel, but to me it is.

Anyone got a clue about the implications? Also, how difficult to do? (besides than the author's own impressions) Would it be possible make a more generic solution?

Re:Massively faster DB with async batching by julochrobak on Thursday January 26, 2012 @12:23PM (#3514985)
What do you find so rediculously good about this? I find it complicated. If I understood it properly, it's just making inserts asynchrounous (removing durability) and batches data into single statement (removing atomicity). Or did I miss something?
Re:Massively faster DB with async batching by willvarfar on Sunday January 29, 2012 @02:21AM (#3524682)
You missed something; the only part of ACID its relaxing is isolation: http://en.wikipedia.org/wiki/ACID#Isolation

"This property of ACID is often partly relaxed due to the huge speed decrease this type of concurrency management entails."

Indeed.

If you have the viewpoint that DB validation is for catching programming errors, not invalid data (i.e. you validate everything before it hits DB anyway), this relaxation can be reasoned about client-side anyway.

Re:Massively faster DB with async batching by willvarfar on Thursday January 26, 2012 @12:30PM (#3515020)
Its still ACID. Its the same callee code as you use in, for example, twisted already to have DB async. It just gets way better performance because the DB speed is measured in requests/sec and not how big those requests are. So merging many requests into a single one where possible means you get more throughput.
Re:Massively faster DB with async batching by julochrobak on Thursday January 26, 2012 @02:51PM (#3515660)
I'm sure the statements to the database comply to ACID properties. Nevertheless, from the client perspective the batching simply means that request from client one is batched together with request of client two - i.e. the atomicity is broken. If the operation fails due to problems with data from client one it impacts client two. I guess my point is, why use a database which comply to all ACID properties if you don't need them.
Re:Massively faster DB with async batching by marshray on Thursday January 26, 2012 @02:29PM (#3515555)
But it's not ACID. For example, if the server or process running his database worker queue were to crash, records would be lost.

Of course, it's quite likely an acceptable trade-off for for these records. Relational DBs sold everyone on ACID in the 90's, but a lot of data doesn't really deserve its cost. He hasn't found a way around Brewer's Conjecture (and I wish I had a nickel for every time it's rediscovered :-).

Re:Massively faster DB with async batching by willvarfar on Thursday January 26, 2012 @02:43PM (#3515612)
But then the callback to the request would timeout and the callee code waiting on the web request would be in no misunderstanding that the thing was committed or not.

Things in the queue get acknowledged - and sometimes resultsets or IDs returned, in the case of SELECT and INSERTs that return auto keys.

Re:Massively faster DB with async batching by marshray on Thursday January 26, 2012 @03:47PM (#3515920)
OK, I see. So your batching related inserts to cut down on the per-transaction overhead, but not actually returning anything to the client until the commit is confirmed.

I think this is a good method, as long as you're careful about these things. (I assume you've taken care of them, just talking about this method in general).

1) If there were multiple transactions in the web request, previously the second ones likely wouldn't have been run if the first were to fail. This would likely change that and it could even necessitate having rollback for the second transaction.

2) Now there is a potential "thundering herd" problem. When the transaction batch commit notification is received, all 1000 web requests made over that 100 ms period become ready to execute and start competing for network/disk/database resources simultaneously. A disk that was just sitting idle now has 1000 different things to do at once. If everybody hits the network at once it can cause temporary packet loss. When packets are lost, connections can be dropped or delayed by retransmits. Sometimes client retries and retransmits can happen synchronously. In the worst case, such a system can end up oscillating wildly between excessive load and excessive idle.

Re:Massively faster DB with async batching by willvarfar on Thursday January 26, 2012 @04:10PM (#3516011)
Yes this is what twisted's "interactions" are and how I talk about throwing rollbacking-exceptions and such in the article.

Yes, you do have to be careful about saturating links generally. The thundering herd thing is a rich man's problem :)

Re:Massively faster DB with async batching by fleitz on Thursday January 26, 2012 @08:19AM (#3513979)
It's really simple. I did it back in 2001, when I did it I used XML and a stored proc to read the XML and write directly to a cursor. It probably takes an hour to do it the first time and about 15 to 20 minutes once you're used to the idea of it. (on SQL Server 2000)

With something like SQL Server 2005 it's super simple (< 5 mins) you can basically write an XML file as a stream to your DB server and it eats it and writes directly to the table. (SQL Server supports transforming XML into a table using XPath). You can basically treat the connection like a filehandle and dump XML directly to the stream. Just make sure you open/close the connection often enough not to cause the lock optimizer to grab a table lock. (Or just grab a table lock if you really want it to scream)

All you need to ensure is that you don't hold the steam open too long. If you don't mind a little logic in your DB server you can even consume complex object graphs. If you go the XML route you can max the CPU on your DB server which is generally a bad thing for the most part on modern systems it won't matter unless your DB server has 200+ disks.

You can use this type of system to stream 200 or 300 MB worth of data to your server in a few seconds. This assumes your DB server isn't a piece of crap. (If it can't keep up with a gig ethernet card on random IO or is virtualized it's most likely a piece of crap).

The more generic version is to take advantage of the INSERT syntax and use multiples sets of values.

eg. INSERT INTO foo (id) VALUES (1),(2),(3); instead of INSERT INTO foo (id) VALUES (1); INSERT INTO foo (id) VALUES (2); INSERT INTO foo (id) VALUES (3);

Now because MySQL is one of the most retarded (I mean that in the literal sense of the word) databases in the world it doesn't support prepared statements so you get huge overhead when you issue SQL to it, compared to a prepared statement. Also, make sure you explicitly start a transaction before you issue a bunch of inserts, else each statement becomes its own transaction.

Also on the readside to increase performance use something like MARS and issue multiple SELECT statements.

eg. SELECT * from parent where id = 5; SELECT * from child where parent_id = 5;

If you have to do more than a few levels consider a SHAPE query. Or use map reduce and 'fold' your join back into something sane.

Re:Massively faster DB with async batching by dkoch on Thursday January 26, 2012 @08:39AM (#3514033)
MySQL has had server-side prepared statements since 5.0.