I am working on a team that is building an in-memory SQL database. It features a custom language that makes it possible to push the time-critical, data-processing parts of the application directly to the database, which allows for the same speed as this no-DB approach. But you don't have to build your own DB and do everything yourself (correct persistence, backup, transactions...)
Now that people are considering NOSQL will more people consider no-DB
91–100 of 147 posts
Re: Now that people are considering NOSQL will more people consider no-DB
#92I've always wanted "no-DB" to the level of it being part of the platform/language. I've always thought that software-transactional memory and persistent distributed heaps would get us there. Unfortunately the nearest things have been Redis and Terracotta plugged into Clojure. It should be: Insert? new an object. Delete? dispose an object. Look up? Hash table. Solved problems that just require persistence.
Re: Now that people are considering NOSQL will more people consider no-DB
#93Earlier quoted context omitted.
> Uh, OK. So, you're happy with single-core boxes then, I take it? Not at all. You use only one core for the core execution of write transactions, but that's a small part of any real system. All cores can read simultaneously. All cores can also do all sorts of other work, including preparing transactions to execute, deserialization of requests, rendering responses, logging, and anything else your app needs to get up…
"All cores can read simultaneously." Unless someone is writing, of course, in which case you have to worry about isolation. So a single writer would block all readers, right? "You mean a bug in our code that causes a problem?" No, I mean like "I already wrote some data, but now a constraint has been violated so I need to undo it".
Correct. For the fraction of a millisecond the transaction is executing, anyhow. Since transactions only deal with data hot in RAM, transactions are very fast.
> No, I mean like "I already wrote some data, but now a constraint has been violated so I need to undo it".
That shouldn't happen, and I've used two approaches to make sure. One is do all your checking before you change anything. The other is to make in-command reversion easy, which is basically the same way you'd make commands undoable.
Basically, instead of solving the problem with very complicated technology (arbitrary rollback), you solve it with some modest changes in coding style. Since you never have to worry about threading issues, I've found it pretty easy.
Re: Now that people are considering NOSQL will more people consider no-DB
#94Earlier quoted context omitted.
The goal is not to replace databases altogether. The goal is to solve some particular problems very well. Last time I used this approach, for example, we mirrored a bunch of data in a traditional SQL store for reporting and ad-hoc querying, things that databases are great at. In my view, direct access to data decoupled from application code is a bug, not a feature. With multiple code bases touching the same data, sch…
"With multiple code bases touching the same data, schema improvements become nearly impossible." Few companies have procedures in place that allow this; but it is possible if you have the right procedures.
Re: Now that people are considering NOSQL will more people consider no-DB
#95As far as I can see, they seem to be comparable to b+tree indexed key value stores. A key would e.g. be "/home/user/test.txt". Thanks to the B+Tree "indexation" you can do a prefix scan and list folders (e.g. "ls /home/user/"--> all keys starting with "/home/user/").
In the case of e.g. ReiserFS they actually use B+Trees. They have a caching layer managed by the OS. Most of them have journaling which would be the equivalent of a "write ahead log".
Map reduce based "view" generation can easily be done by pipes and utilities like grep. We might be even able to do some sort of simplistic filtering/views/relations using symlinks.
I guess the main difference is that they aren't optimized for this database-like behavior from a performance standpoint and that the network interfaces to them are SMB/AFP/NFS.
Re: Now that people are considering NOSQL will more people consider no-DB
#96"The key element to a memory image is using event sourcing, which essentially means that every change to the application's state is captured in an event which is logged into a persistent store."
That is a key element of a database. It's called a logical log.
"Furthermore it means that you can rebuild the full application state by replaying these events."
Yup, logical log.
"Using a memory image allows you to get high performance, since everything is being done in-memory with no IO or remote calls to database systems. "
This is _exactly_ what sophisticated old-school databases do. You can have them require to write to the DB on commit, or just to memory, and have a thread take care of IO in the background.
"Databases also provide transactional concurrency as well as persistence, so you have to figure out what you are going to do about concurrency."
Righty-ho.
"Another, rather obvious, limitation is that you have to have more memory than data you need to keep in it. As memory sizes steadily increase, that's becoming much less of a limitation than it used to be."
So why not store your old-school DB in memory?
I can understand the argument that you don't want to lock into a big DB vendor's license path, but the technical arguments here look distinctly weak to me.
Maybe old-fashioned DBs are hipper than people think?
Re: Now that people are considering NOSQL will more people consider no-DB
#97Earlier quoted context omitted.
- The startup times can be a problem if you have a lot of data. Modern disks are pretty fast for streaming reads, though, and you can split the deserialization load across multiple processors. - Mirroring state is easy; you just pipe the serialized commands to multiple boxes. - It's very fault tolerant. Because every change is logged before being applied, you just load the last snapshot and replay the log. - It didn'…
Thanks for the informative response. Just a couple more questions: > - The startup times can be a problem if you have a lot of data. Modern disks are pretty fast for streaming reads, though, and you can split the deserialization load across multiple processors. Reading data, at even a GB/second from disk (which is currently not possible) is going to mean a second spent of a GB of data, just to read, let alone deseria…
If that's just saying that startup time can be an issue, I agree. There are a variety of techniques to mitigate that, though. The simplest is to compress snapshots and/or put them on RAID, boosting read speed. The most complicated is just to have mirrored servers and only restart the one not in use right now.
> I'm talking about having more data than fits in an reasonable amount of RAM (say 1TB).
For something where you need transactions across all of that? This architecture's probably not a reasonable approach, then. The basic precondition is that everything fits in RAM. However, sharding is certainly possible if you can break your data into domains across which you don't require consistent transactions.
> So it's going to at the speed of the disk.
Sort of.
Because it's just writing to a log, mutations go at the speed of streaming writes, which is very fast on modern disks. And there are a variety of techniques for speeding that up, so I'm not aware of a NoDB system for which write speed is the major problem.
Regardless, it's a lot better for writes than the performance of an SQL database on the same hardware.
> My other question is how much of a pain in the ass is it to debug such a system?
It seemed fine. A big upside is that you have a full log of every change, so there's no more "how did X get like Y"; if you want to know you just replay the log until you see it change.
Last I did this we used BeanShell to let us rummage through the running system. It was basically like the Rails console.
Re: Now that people are considering NOSQL will more people consider no-DB
#98I am 100% agreeing with the article, with one caveat. Database engines are not just for storing - each is basically a "utility knife" of data retrieval - indexing, sorting and filtering are available via (relatively) simple SQL constructs. If your app uses an index right now, ditching the DB will mean re-implementing it manually. It's not hard, but it's extra code. So basically, the DB engine might still be a necessa…
The SQL constructs are great, but the biggest advantage to relational databases is that the engine handles your data consistency issues for you. Consistency isn't just about rolling the datastore back to a specific moment in time -- you have to handle locking, concurrent reads/writes, etc. If you're building a trading platform that handles 6M transactions/second, you have the money to handle this in the application l…
Re: Now that people are considering NOSQL will more people consider no-DB
#99What about ROLLBACK? And no, going back in time by replaying logs is no substitute, because you lose other transactions that you want to keep (and perhaps already reported to the user as completed). What about transaction isolation? How do you keep one transaction from seeing partial results from a concurrent transaction? Sounds like a recipe for a lot of subtle bugs. And all of the assumptions you need to make for t…
Basically instead of making a transaction between 2 entities, you send a message to the first reserving some data, a message to the second reserving the data and once you get confirmation from both (or however many entities are involved in the transaction) you send a commit to them.
These reservations can be revoked though. Your rollback has to be managed by an "activity".
Ex: Bank transfers. You have the activity called BankTransfer. It manages the communication between entities and the overall workflow. It starts by sending messages to entities Account#1 with 100$ in it and Account#2 also with 100$. To #1 it says debit 500$. To #2 it says credit 500$. #2 responds first and says Done. #1 responds second and says Insufficient Funds. BankTransfer sends another message to #2 saying Cancel event id 100 (the crediting).
Other activities that want to read the state of number 1 will see 100$ in it but the transfer (as yet unconfirmed) had been of 50 rather than 500$ and another debit of 75$ comes in it would respond insufficient funds. At this point it's the activity's job to decide what to do. Wait and try again? Fail entirely and notify any other entities relevant to the workflow? That's up to the business rules. Also, since the credit has not yet been confirmed, reading the balance on #2 would still say 100, not 600$.
Of course, depending on your use case you may want the read to return the balance with unconfirmed transactions. That's entirely up to the application code and business rules but the example should be explanatory as to how rollback is implemented.
Eventual consistency is the only scalable way to go for very large systems.