1) The user u1 will end up connecting to all nodes. Thus as you scale adding an "E" you always end up connecting to each cluster having the same amount of connections. Example, let's say A,B,C,D have 5k connections open and you add "E". Now "E" has 5k connections. Now you are blocked by the number of requests per second and no amount of hardware can save you.
2) Let's say B and B1 die. (It happens.) Now your system is completely out. All 5k connections are blocked. It would be nice if A,C,D,E continue to run.
I usually get around things like this using an index server between user u1 and A,B,C,D. When u1 starts retrieving keys the system needs to be designed such that u1 only connects to single node for it's keys.
How do you get around 1,2? Do other people use index servers?
1) The amount of connections is not very relevant. You can set a max limit if you want, like with the redis-rb-client that will close old connections before opening new ones if the limit set by the user is less than the number of master nodes. However this is not recommendable as actually what is an idle connection? Just an entry in a data structure of the kernel. So it is not an issue for every client running in a given box to have multiple connections to multiple nodes.
2) The limit in the partition resistance in Redis Cluster is a fundamental design trade off, it means no need for a "merge" operation and that in a given moment only one node is responsible for a given key. I think that in the case of Redis most of the times less partition tolerance in favour of a simpler consistency model is what users need.
EDIT: a clarification on "1", what I mean is that every connection will be active only for the subset of keys it holds, so basically the traffic of every client is split across all its connections. Similarly every node of the cluster only performs a percentage of work proportional to the number of hash slots it holds compared to the full set of 16k hash slots.
EDIT 2: it is not clear from your point "2" if you understand you can have B2, B3, B4, BN if you want.
The redis cluster client in your programming language will know the entire current redis cluster state. The redis cluster client will automatically place (and read) keys directly to (and from) the correct instances. The direct reading also reduces latency found in some other cluster implementations where you only have the option to proxy your requests. You as an application programmer never have to worry about multiple servers.
When your redis cluster client connects to the cluster, the redis client reads the current key slot to server map, and uses that for every action (with updates as necessary as failures/promotions happen).
Let's say B and B1 die.
Good example, but you should probably be running with at a minimum B, B1, and B2 (and three entire copies of A, C, D as well). You have to design your deployments in concert with how your underlying architecture works. Redis cluster instances do not have to take up an entire machine. Run a couple masters and a couple replicas per host. Running a cluster with 4 masters means you should run with 8 replicas (minimum). See the math section of https://github.com/mattsta/redis-cluster-playground for more examples.
It's worth stepping back and defining "Cluster" too. A "database cluster" has no meaning by itself. It doesn't specify redundancy, how availability works, or how replication works. A Riak cluster has nothing to do with a Redis cluster. You have to learn the operations on each type as you go.
(Redis is single-threaded, anyways. You probably don't want to run production and staging on the same Redis process.)
Every other database on the planet has database names pretty much.
I LOVE Redis but this is just a bonkers limitation IMHO...
More generally, you can always use key-prefixes if you want a name-based way to segregate data in the same redis+db instance.
This idea may of course be contrary to the expected use of Lua scripts in Redis, and an attempt for the RDBMS part of my brain to look at Lua scripts as stored procedures.
The big benefit to this is when balancing write-heavy workloads, when the slave would not be getting its share of the total load.
I believe this could be accomplished by running a second DB on each machine as a slave to the next in the cycle, and that's what I'll probably try when we scale up to needing a cluster. But having it be a supported scenario (or facilitated somehow) would make me feel much better.
(edit: Just a feature request of course, exciting to see this release! Thanks for all your hard work antirez!)
Something like:
SYNC 3
SET key value
[replies with success only after it's ACK'd on three cluster instances.]Redis have instead a master - replicas setup that can't usually resist severe partitions. In general only the side of the partition with the majority of masters survive assuming that there is at least a slave for every master that is not in the majority partition.
In practical terms this means that a few nodes going away usually result in the cluster being still available (unless you are really unlucky and all the replicas for a given hash slot go down at the same time), but that under severe partitions the system is likely unavailable.
The tradeoff makes Redis cluster able to work without help from the application, and without merge operations: this is very desirable because of the kind of complex-to-merge and big (millions of elements are common) data structures that a single key can hold in Redis.
Some variant of clustering is a very common feature among many different database platforms.
Redis adding clustering does not make it a step towards turning it into Riak any more than it is a step towards turning it into MySQL [1]