Goodbye, CouchDB
saucelabs.com
saucelabs.com
COBOL? Really? I don't see the COBOL connection at all.
SQL is more closely related to relational algebra, so it makes absolute sense when you're querying relational data.
So that's why many of us prefer to query our relational data in SQL. It's the same reason why we write stylesheets in CSS instead of C++... and why we validate postal codes and phone numbers with regular expressions instead of "manually" parsing them with PHP, Ruby, Python, or what have you. It's all about the right tool for the right job.
Relational data isn't the right solution for everything; there are lots of use cases where NoSQL databases absolutely rock and traditional databases are inappropriate. Again, right tool for the right job.
I'm not by any means saying that the NoSQL movement as a whole is a fad - there's good motivations behind some of these products - but a lot of people who are just ignorant also seem to have hopped onto the bandwagon.
Rather, I think the author has confused "relational" with a lot of other properties of relational databased management systems - such as transactions and data integrity guarantees.
> Like "power steering" for SQL. Doesn't teach you how to drive!
for foo in bar
ubiquitous in modern programming languages?What would you prefer? Fortran? Assembly?
My primary point was just that SQL is old, and I think the reason it is the way it is has more to do with history and compatibility than what we'd want it to look like if we started from scratch today.
SQL is still around because it was successful. And there are reasons to value compatibility, and to avoid changing things for no reason. But my personal experience using a database without using SQL was pleasant, and I'm anxious to see the world move on to something new and improved.
But beyond very simple cases I feel like non-SQL query interfaces very quickly become terrible, clumsy, leaky abstractions.
I usually try to have the best of both worlds - I create a SQL view/function/sproc containing my big gross gnarly joins, and then query it in a pretty way via the ORM.
Unlike COBOL (which I admit to not being very familiar with) SQL uses standard mathematical symbols as operators whenever possible... + instead of "ADD" etc.
select * from users
Looks more like Haskell now.So, on one hand, you have a group of people who think they know SQL well enough and dismiss it as inadequate. These are people who build schema without foreign key and run queries without JOIN because they "know better".
On the other hand, you have a group of people who think they know SQL well enough and fall back to it whenever possible. They go on to create views on top of views on top of views, create temp tables to hold intermediate values that get discarded right away, format application output with string concatenation in SELECT, add DISTINCT to SELECT whenever in doubt, etc etc.
We have an interview question (for a senior position) to test if the applicant grasps the concept of "EXISTS/IN (<subquery>)", and thus the concept of set-based SQL. Nobody has got it right yet, though they all can write a ton of SQL.
While they do mention the need to enforce constraints on your data, it's comments like these that make me wish all application developers were required to work as a DBA for a few months.
A properly normalized and "constrained" database prevents data loss from stupid mistakes.
Guess what - in lots of applications data integrity is more important than developer convenience.
if (data.schema_version === 1) { ... } else if (data.schema_version === 2) { ... }
UGH!
A properly written application layer also prevents data loss from stupid mistakes. A stupid mistake made while setting up a properly normalized database also causes data loss.
You have to be very smart to be able to design a normalized constrained DB well. The fact that only smart people can do it doesn't mean that people who don't do it aren't smart.
Agreed but the application layer _generally_ doesn't have the abstractions at a point where it's trivially easy to put these safe guards in place like it is at the database layer.
Also, "stupid mistakes" does not in any way imply that the people who make them are stupid. Nor am I implying that you have to be particularly intelligent to normalize and constrain a database properly. I'm simply lamenting how undervalued a "good schema" can be.
[side note: upvoted your comment :D]
Eh, nit picking, but I think "very smart" is overkill--I think "just smart" people should still be capable of designing normalized constrained schemas.
If they are incapable of doing this, then I don't want them writing any code anyway.
Being capable of doing it and choosing not to is either at least forgivable or completely understandable, depending on the situation.
But you can be a complete moron and write "[a] properly written application layer [that] prevents data loss from stupid mistakes"?
What's the difference? Writing correct code can be hard. I don't think it's particularly easier to apply all your constraint in app code unless you just don't know about the database backend you're using.
This is fairly trivial to express as a table-level constraint. I've done very similar things in Postgres. I have no idea if you can do this in MySQL, but it's quite crippled.
http://draconianoverlord.com/2012/05/08/whats-wrong-with-a-s...
Don't get me wrong, I love my RDBMS (MySQL and PostgreSQL) and I also use Mongo and love its extreme simplicity, but I wish more developers understood that schemas exist in places other than RDBMS.
...
Given that we had experience with MySQL and knew it was adequate for our needs, it was hard to justify any other choice.
Agreed. It seems pretty clear from reading the article why they went with MySQL, which you wouldn't know from all of the Postgres butthurt in the comments.
I'm pretty sure given this kind of workload MySQL will outperform PostgreSQL handily.
Both of those statements are not accurate, but hey, what's it matter? Without benchmarks we're both talking out our ass anyway.
The lock manager bottlenecks that stopped PG from using more than 60% of the cpu power on a 24 core box were discovered a little less than a year ago.
http://rhaas.blogspot.com/2011/07/read-scaling-out-to-32-cor...
See here for an example of mysql having problems at only 8 cores (and postgresql destroying mysql's performance): http://www.scribd.com/doc/551889/Introducing-Freebsd-70
Postgresql scaling to 28 cores in 2007: https://docs.google.com/viewer?a=v&q=cache:-ytn3fY_Lr8J:...
Postgresql on 32 core t2000 being able to scale up to 1024 concurrent clients in 2008: http://www.pgcon.org/2008/schedule/attachments/50_46_pgcon20...
In terms of "real" workloads, I'm not going to bother getting into it, as this is quickly devolving in to a true Scotsman argument.
Instead of arguing pointlessly about it, maybe our energy would be better spent publishing some benchmarks.
http://rhaas.blogspot.se/2012/04/did-i-say-32-cores-how-abou...
The fact is current versions of PG are unable to use more than 60% CPU on a 24 core machine. Do you know anyone who uses a dev version of an RDBMS in production?
http://archives.postgresql.org/message-id/BANLkTimVboKxzGS9B...
I don't know about MySQL, but my database caches compiled queries.
"Things like SQL injection attacks simply should not exist."
They don't exist, if you don't construct SQL queries by concatenating strings and variables.
Meanwhile, all the cool kids are talking about getting rid of procedural code in favor of declarative DSLs...
My point is, people still do this. You never hear about REST-injection or memcached-injection attacks, even though those are possible in principle, because those protocols don't encourage this mistake the way using SQL as a database API does.
This attitude right here is why the RDBMS old guard despises NoSQL. Willful ignorance should not be celebrated.
A lot of the excitement over schema-less data stores (I think) really comes down to instant DDL changes, which is why you should really just use Postgres instead of MySQL.
I've spent many years using schemas, and I know well how they work and what they achieve. I'm saying they're a lousy tradeoff.
*edit I misspelled ignorant... irony alert
Engineering choices are always tradeoffs. If they're founded on ignorance, they're bad choices--always. Your article is trying too hard to be cute and funny and comes across as ignorant. I assert that promoting uninformed decision-making is both intellectually dishonest and constitutes a much truer form of "cognitive poisoning."
One thing I would say about postgres is that it has a lot of features. As a new user, it's hard to know which ones to use in which ways, and what the downsides might be.
Do you have some suggestions how that can be improved? Are there features that you would classify as "bloat" or that seem confusing or poorly documented?
Postgres is a very general system and has a large variety of users as a result. That means that the features tend to be very well-thought out and don't carry a lot of surprises, but it also means that it's hard to guide users toward specific usage patterns. Even among web users, a feature like LISTEN/NOTIFY might be an instrumental part of the caching infrastructure for some users, but seem like bloat to others.
Output to any external system must be encoded to prevent fill-in-the-blank injection, if it uses a language vs a string API-only approach. Used prepared statements.
SQL is not COBOL. Sets != ISAM.
You can store arbitrary data (XML, JSON) in BLOBS/CLOBS in an RDBMS. Denormalization is frowned upon, but not forbidden.
PostgreSQL is arguably a better free / open DBMS than MySQL.
DBMS data constraints are a good thing; use them when they make sense.
It seems like all the problems he has are with scaling. I can't comment on that, but I would whole-heartedly recommend it for internal tooling.
Although, I do have high hopes for Key:Value store data repositories.
TANSTAAFL.
Remember only successful companies have to worry about scaling. Un(/not yet)-successful company have to worry about shipping first, then scaling. So perhaps Saucelabs reached that milestone, and they simply have outgrown the original technology that helped them ship.
Who knows, maybe if they had spent time re-implementing a REST interface on top of MySQL or re-implementing Futon for doing debugging, we might not even have heard about Saucelabs these days.
It did make a few things harder later on but we were better equipped to make a change around the time we actually needed to. If we had spent a lot of time up front developing for SQLite, we'd have paid an overhead tax for years for no good reason. And possibly wouldn't have made it to the point in which we needed to make a change.
That said - our use case was incredibly narrow (read only data store, server outputs JSON anyway, etc.) and so we made a reasoned choice.
If we needed complex queries/joins, updates/deletes, incremental loading, etc. - then a JSON store would've been terrible.
This is most generally a sign of bad indexing/query construction. I've seen so many databases with dozens of indexs placed on tables (which only had a requirement for a few) because the developers just didn't grasp how they should be setup - which isn't rocket science.
Programs, by comparison, are a lot more flexible here, unless you're in the financial/health/auto/aero industries.
As an aside, where I work we use a lot of node. It works.
The future of what? Non-relational data? Relational databases are very good for a wide variety of problems. And they will continue to be very good for a wide variety of problems.
Shameless plug: If you're looking to benchmark or load test CouchDB a bit, I wrote one at https://github.com/mgp/iron-cushion. Hopefully someone out there will use this to decide if CouchDB's performance meets their needs, because migrating away from any database is painful...
https://github.com/stochastic-technologies/goatfish
Not production code by any stretch, but an interesting concept, and I'd be more inclined to work on it if more people were using it.
Yet in the same page makes fun of SQL for being old and busted? I don't get it.
It is also so easy to build on, that people who don't know what they're doing and shouldn't be building any software for redistribution, will do so anyway, and gain just enough success to become extremely annoying. Its IDE is about on par with most other IBM-involved software development exercises, i.e., fairly bad.
Now, all that aside, it is a very powerful, but not generally well-appreciated, system, and is great (fast, cheap, hard to kill) for a large swath of applications that don't require any of the stuff from the first paragraph.
Also, he actually linked 2 articles, I'd never seen the first one so it may very well be a hoax or whatever. But the 2nd one has made it's rounds a few times and has stood up (IMO) to scrutiny.
Many of the issues they found with CouchDB have been resolved with Riak. I think the sync API for CouchDB is really cool, but Riak has the auto-sharding thing down cold.
Riak runs map reduce queries across multiple nodes, so performance and capability can grow as you add nodes.
CouchDB's views are neat but they impose some constraints that Riak's more dynamic approach resolves (at the cost of possibly running more queries, but these results can be cached easily giving Riak a form of "views" for often run queries.)
I believe Riak's choices for backend are superior to CouchDB's. Further, Riak supports multiple backends so you can choose the one appropriate for your service (including InnoDB, LevelDB and Basho's Bitcask, as well as a super secret hidden gem of a Caching RAM backend.)
Riak now has indexing of data, and queries on these indexes, but I can't compare it to CouchDB. I can say that the feature is close enough for me to not miss SQL.
I think Riak's "view performance" compared to CouchDB should be good, but may not compare to MySQL, but then, we're talking single node performance. Riak is distributed- you need more performance, you just add nodes and point them at the cluster. MySQL requires you to architect a (from my perspective) brittle configuration of servers that can run into SPF issues.
For instance they talk about having a single write master. What happens when a meteor crashes to earth and takes out that machine? Really unlikely, sure, but I have had enough machines have failures (and failures are often really weird) that I don't trust ANY machine to be a single point of failure. ... and when I'm forced to, like being in a single datacenter or having a single network switch, I don't like it, so I avoid it when I can.
Riak has automatic sharding and automatic rebalancing. It loses a node and keeps running. You add nodes and it redistributes around. Riak is an operational dream.
Not to bash CouchDB at all (or MySQL). I think CouchDB is a great product for certain use cases.
I just think a LOT of people are really missing out by passing over Riak.
It also has secondary indexes.
But we not using to for large datasets. We are using it mostly for configuration, and setup. There is a custom clustering setup built in its m-m replication and changes feeds.
But I agree that for IO scaling and large data sets Riak would be a top choice. But there are other contenders to look at as well: Cassandra, BigCouch and the upcoming Couchbase Server 2.0
Continuous changes feed- you can get this with Riak and more importantly you can get a feed of just the relevant changes. Plus you don't need this in Riak the way you do in CouchDB because Riak already has distribution built in.
Master-Master replication as done in CouchDB is inferior to the turely distributed database that Riak is. (Eg: its not replication, it is distributed itself.)
Web interface to data management-- futon was a lead here but there are several tools for Riak that cover these bases in my opinion.
I think CouchDB as a configuration database is an excellent job.
I looked at BigCouch which is taking the Dynamo Ring concept and applying it to CouchDB which is a good solution for couchDB (in fact, they should build it in to the core) ... but that's also what Riak is built from the ground up to be (a dynamo ring.) Cassandra is a different animal and I can never figure out what Couchbase is going to become.
Once you are dealing with more than 500k keys or so, Riak starts to fall over.
EDIT: The 500k key limit pertains to mapreduce jobs, not the overall data size.
You're bashing a product here based on your lack of knowledge, not the products lack of capabilities.
We just saw you over in the programming languages thread, now you're here, refusing to confront the reality of how broken M/R is in Riak.
What monkey crawls around on your back to make you so confrontational and irrational?
Hadoop may have been better for what you are doing, and logging metrics is a particular use case where a specialized database is most appropriate.
But it is incorrect to imply that Riak falls over at any specific key limit. This is simply untrue. With Riak you can always add more nodes if you need more capacity, and Map Reduce is done in a distributed fashion so adding more nodes adds map reduce capacity. Its not perfect but it is not brittle.
http://lists.basho.com/pipermail/riak-users_lists.basho.com/...
"If large-scale mapreduce (more than a few hundred thousand keys) is important, or listing keys is critical, you might consider HBase."
"Riak can also collapse in horrible ways when asked to list huge numbers of keys. Some people say it just gets slow on their large installations. We've actually seen it hang the cluster altogether. Try it and find out!"
You want to say I'm wrong, make a specific argument. Don't selectively quote things out of context that actually don't rebut my position, as that's profoundly dishonest. It is a way of pretending to rebut someone but without saying anything yourself so you can't be pinned on any statements. It is disingenuous.
I'm really tired of having to rebut these argument-from-ignorance "rebuttals" here on HN.
Ctrl-F billions and found one match in the post I was quoting. No other reference to very large MR jobs in the post quoted.
"At Showyou, we're also building a custom backend called Mecha which integrates Riak and SOLR, specifically for this kind of analytics over billions of keys. We haven't packaged it for open-source release yet"
So the OP is supposed to use an unreleased experimental custom backend to do his big mapreduce jobs?
Riak will handle billions of keys just fine. We had, I dunno, a half a billion in a six node bitcask-backed cluster and were only at half capacity. Much much bigger installs exist. The limit I was referring to is for a single mapreduce job; Riak MR just isn't well-suited to operations over millions of keys at a time. It can do it, but Riak MR isn't really designed for bulk processing: and I wouldn't be surprised to see MR become unusably slow over millions of keys. You'll get better performance out of Hadoop, generally, for bulk analytics.
The other tough point is key-listing. Listing buckets, listing keys, key filters, MR over buckets, all those features are essentially useless in production. Where the number of keys is large and unguessable it can become a logistical nightmare to keep track of them. 2I key indexes can help, though.
I want to put millions of items in riak, play with it, and then throw then away.
I might want to do that because I'm testing out something, or because it's the result of some periodic batch processing in production, which I want to get by key later.
Unfortunately, riak doesn't seem to have the notion of a "db", "keyspace" or whatever you want to call it; i.e. something which you could "drop" and that will simply delete a directory with a dozen of files in it (should be quite cheap).
The only thing I can do is to drop the whole riak db, which has the following problems:
1) I have to do it manually on all nodes (stopping the cluster, deleting the files etc)
2) I cannot share a riak cluster between several users/team, so that each user/team can play with a portion of it but there is only a central installtion of the whole cluster. Every application (which I want to be able to drop all the db and recreate it) has to run it's own riak cluster.
Initially I thought that "buckets" were intended to solve this problem, but buckets don't map to a separate storage location, it's just a way to group items. Even listing all buckets present in the db requires scanning all keys and, as the doc says, "Similar to the list keys operation, this requires traversing all keys stored in the cluster and should not be used in production."
Although I've been told that "riak is not designed to do this and that", I'm not sure if these limitations are really technical, or just because the product development effort was targeted at some of the aspects, and these issues could be addressed in a later stage.
Any idea?
a.) Run multiple clusters--not too difficult. Just give each one a different erlang cookie and run em on subsequent ports.
b.) Take bitcask_backend or leveldb_backend and add drop-bucket functionality. Custom backends are more difficult than running multiple clusters, but certainly not impossible. You could build it on top of fold or split writes up into, say, one leveldb per bucket. Don't recall if the vnode interface has drop-bucket so you might have to write some plumbing alongside Riak. jrecursive has done this in Mecha.
If I were building something like this, I might look first at Cassandra or Hbase, or possibly sharded master-slave postgres.
1. Even if it's easy, somebody has to do that. 2. Setting up all the monitoring etc for each instance 3. Running more than one riak daemon on the same machine means that the riak daemon is unaware of the IO operations performed by the other one, hence IO throughput could suffer. This means that in practice you would need to mount separate disk heads (and we are back to 1.) 4. Each riak instance will require some RAM as well, so memory has to be allocated and there is the risk that's over-allocated. 5. Port allocation. I fear it would end up with smth like: "just keep a internal wiki page where each 'db space' is mapped to a port number"
Well, the problem with (b) is of course that I don't have time to do that. For now we stick to cassandra, but Riak is so nice in many aspects that I really hope that at some point, as the product matures, more resources can be invested in aspects which are not currently perceived as "selling points" for riak, but are important for some scenarios and not technically impossible.
Looking into Riak, I am under the impression there is some caching done on parts of their map reduce system, but I couldn't really find a lot of advice on the performance characteristics of frequently running a map reduce over a large, slowly-changing dataset.
Does anyone else have experience using Riak for this kind of thing?
So, I get the squicks now whenever I see someone talking about how lame and broken an old, mature technology is. The way this article shits on schemas, for example -- if a coworker said that to me in real life I'd get a sinking feeling in the pit of my stomach. It's a short hop from that type of thing into the land of the straight-up cowboy coder.
Riak looks interesting but its overkill. They recommend at least three nodes. We went back to PostgreSQL.