Hacker News new | ask | show | jobs
by warfangle 4398 days ago
Riak, when you use LevelDB behind it, certainly has indexes. As many as you want (within reason), through secondary indexes[0]. While it doesn't have joins specifically, you can link data blobs and walk the links[1]. For when that isn't quite enough, you can always perform a compiled erlang map reduce across a given dataset[2].

I don't quite see how CockroachDB offers anything Riak doesn't.

Riak, while not offering true locking transactions (it doesn't look like CockroachDB does either - imagine how long it would take to perform a locked transaction across sixteen data centers in as many countries, two of which have gone dark due to power outages and giant robots), offers you the option of resolving data version conflicts when you read the record[3]. (ed. Many times if doing a partial update of a record, you need to read before writing anyway. This resolves a conflict before you write to a potentially conflicted record chain. Typically this is done with a pre-commit hook. [4])

(ed.: The major differences seem to stem from the snapshotting system CDB uses to provide external consistency across data centers. This comes at a (potentially huge, especially if two clusters lose connection with each other but not with clients) delay in write verification.

Riak, on the other hand, would still allow writes - and would resolve any conflicts when the datacenters connect again. It's a hairy problem to fix, especially in a general manner.

It all depends on what kind of data you're storing.)

0. http://docs.basho.com/riak/latest/dev/using/2i/

1. http://docs.basho.com/riak/latest/dev/using/link-walking/

2. http://docs.basho.com/riak/latest/dev/using/mapreduce/

3. http://docs.basho.com/riak/latest/theory/concepts/Vector-Clo...

4. http://docs.basho.com/riak/latest/dev/using/commit-hooks/

4 comments

Simple, CockroachDB is a CP system, while Riak is an AP system.

If you need multi-key ACID transactions, and can tolerate potential downtime in the event that some partition loses a majority of its Raft replicas, you might want to use CockroachDB.

If high availability is a concern, and you can tolerate the occasional data conflict in the case of incomparable vector clocks due to writes accepted during a network partition, or, if your schema can be modeled with CRDTs (LWW register, PN counter, Union-Set, etc), you might want to use Riak.

Multi Data Center Replication doesn't come in the free-lunch-pack. To get that with Riak, you probably need to downpay $6000 for getting that license for a node. So if you have two geolocations for your data, it would be at least $12000 for a minimal setup.

Of course for people looking at the usage for this, money is not the major issue.

Very good point.
What is your comment on the "No availability or weak consistency with datacenter failure" part?

Is that referring to Riak's cross data center replication (enterprise feature). I guess for regular case (non-enterprise version) it is true, as it is not possible to specifically assign ring sections to data centers?

Fully ACID transactions is a big deal.
They're based on Raft--that's not a consensus protocol that's designed for multi-datacenter operations. I suspect you'll have reliability and throughput issues fairly quickly, just as you see with multi-datacenter zookeeper.

The solution Google uses for this kind of problem: multidatacenter transactions are rare, so they're not optimized for latency (instead for reliability), and they tend to use 2PC, as it's easier to get right with unpredictable WAN latencies.

Riak will have strongly consistent buckets in 2.0+, which pretty much takes care of the cases in which I'd need guarantees for data in this storage model.
Consistency of single updates is vastly different than multi-write atomic transactions. The former precludes, for example, financial applications which require atomic updates of multiple balances.
Clearly, but I would just be using Riak to store the single command that indicates an update of multiple balances should be scheduled. Given sound guarantees at that level, I'll be able to implement the transaction myself in any number of ways, inclusive of interop with external services.
And if two commands get stored in quick succession, such that the first results in a state that renders the second impossible? Particularly if some of the balance updates in the first command, are contingent on others ( credit line backing checking account updated if deposit balance < 0, for example )?

Financial transactions are pretty much the poster child for atomic, multi update transactions and pessimistic locking.

You can always save the fact that a transaction was started, read the account's state (including the most recent transactions as an ordered list), calculate the validity of the item, and update the success/failure accordingly.

It is not the transaction itself that is hard, it is the network partition. E.g. what happens if two network partition approve transactions, that wouldn't have been accepted if there were no partitions.

I've probably gotten off base here by wanting to perform arbitrary actions against services I may or may not control in the course of satisfying a command, and worrying too much about made up corner cases.

If this DB is the sole record of The Money, and I can move some quantity from X to Y in a transaction, then that's fine by me.