What is the right way to benchmark the redis-cluster(released recently in 3.0 RC). AFAIK, redis-benchmark utility hits only one node of the cluster.
EDIT:(Details)
My single instance of redis without any clustering gives a throughput of ~90 k set/get operations but the cluster setup fails big time.
SETUP 1: 8 core machine running a cluster of 3 masters+ 3 slaves(all on the same machine)
I also run 3 benchmarking utilities on the same machine. The throughput drops to 25 k on each master node.
This makes me think that I am, perhaps, running one too many processes for the number of cores on my machine.
Setup 2: I update the setup to have 3 Masters and 0 slaves. Interestingly, this doesn't help the case either and the throughput is still 25 k on each machine
The benchmarking command that I am running is: redis-benchmark -p 7000 -n 10000000 -t set,get
Any help on this front would be appreciated.
As Josiah said, you are getting 2/3 errors. So to benchmark in the proper way, identify a key which is surely in each node (just connect with redis-cli and use GET/SET brute forcing names). Then use redis-benchmark using the key you found to be, for example, in node A, as an hash tag in order to generate only keys that will hash to that node. So you can do:
redis-benchmark -r 100000 -n 1000000 set 'key{your_hash_tag}:__rand_int__' __rand_int__
This way you'll generate different 100k random keys with names that will hash to the node you are testing. In the example above your_hash_tag is just the key name you found to be in the node you are testing.
First, it is not clear to me that you are actually benchmarking multiple Redis cluster masters with your description. You state, "The benchmarking command that I am running is: redis-benchmark -p 7000 -n 10000000 -t set,get". That will only actually benchmark a single Redis cluster master, specifically the one at port 7000. If you want to benchmark other servers, you have to provide different port numbers when running redis-benchmark multiple times (using the -p option).
Now, even if you do run different commands to hit the different master servers for your cluster, roughly 2/3 of the commands that you perform will result in errors instead of normal command execution simply because the redis-benchmark command is sending commands to a cluster server, and that cluster server does not necessarily hold the shards for the keys that are being operated on.
But what you have really highlighted is that there doesn't seem to be a readily-available solution for benchmarking Redis cluster. A proper benchmark would need to figure out which shards are where, calculate keys to operate on based on the servers and shards, then finally send commands to perform the benchmark, but also raise an error if a shard moves during the benchmark. As far as I know, the software to do this does not yet exist.
Updating this thread with my own answer so as not to leave the answer buried under the comments. When benchmarking the cluster, care must be taken to distribute the 'redis-benchmark' utility. Running them all from the same machine, and even worse from the same machine running the redis cluster, is a good way to lower the throughput. Running the 'redis-benchmark's from a different machine solved the throughput issue for me.
Also, as antirez pointed out, one should send the right keys to each node so that you are not dealing with 2/3 errors.
Related
Is it possible to create a Redis cluster with only 1 master and N slaves/replicas?
I tried it and it failed:
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 --cluster-replicas 2
*** ERROR: Invalid configuration for cluster creation.
*** Redis Cluster requires at least 3 master nodes.
*** This is not possible with 3 nodes and 2 replicas per node.
*** At least 9 nodes are required.
Is there a way to avoid this restriction of minimum 3 masters?
Redis Cluster doesn't support what you are asking for, but there is another H/A Redis mode, "Redis Sentinel":
https://redis.io/docs/manual/sentinel/
This article is worth reading as it illustrates some pros and cons of the two H/A modes:
Redis Sentinel Pros:
With three nodes, you can build up a fully functional Sentinel deployment. (Image 2)
Simplicity - it’s usually simple to maintain and configure.
Highly available, you can build a Redis Sentinel deployment that can survive certain failures without any need for human intervention.
Work as long as a single master instance is available; it can survive the failure of all slave instances.
Multiple slave nodes can replicate data from a master node.
Redis Sentinel Cons:
Not scalable; writes must go to the master, cannot solve the problem of read-write separation.
Slaves may serve reads, but because of asynchronous replication, outdated reads may result.
It doesn’t shard data, so master and slave utilization will be imbalanced.
The slave node is a waste of resources because it does not serve as a backup node.
Redis-Sentinel must be supported by the client. The client holds half of the magic.
We have 2 app/web servers running HA application, we need to setup redis with high availability/replication to support our app.
Considering the minimum sentinel setup requirement of 3 nodes.
We are planning to prepare the first app serve with redis master and 1 sentinel, the second app server will have the redis slave and 1 sentinel, we plan to add one additional server to hold the third sentinel node to achieve the 2 quorum sentinel setup.
Is this a valid setup ? what could be the risks ?
Thanks ,,,
Well it looks its not recommended to put the redis nodes on the app servers (where it is recommended to put the sentinel nodes there).
We ended with a setup for KeyDB (a fork from Redis) which claimed to be faster and support high availability/replication (and much more) to create two nodes within the app servers.
Of course We had to modify little in the client side to support some advance Lua scripts (There is some binary serialized data not getting replicated to the other node).
But after some effort, it worked ! as expected.
Hope this helps ...
Recently, I started to have some trouble with one of me Redis cluster. used_memroy and used_memory_rss increasing constantly.
According to some Googling, I found following discussion:
https://github.com/antirez/redis/issues/4570
Now I am wandering if it is safe to run SCRIPT FLUSH command on my production Redis cluster?
Yes - you can run the SCRIPT FLUSH command safely in a production cluster. The only potential side effect is blocking the server while it executes. Note, however, that you'll want to call it in each of your nodes.
We have a redis configuration with two redis servers. We also have 3 sentinels to monitor the two instances and initiate a fail over when needed.
We currently have a process where we periodically have to do a FLUSHALL on the redis server. This is a blocking operation that takes longer than the time we have allotted for the sentinels to timeout. In other words, we have our sentinel configuration with:
sentinel down-after-milliseconds OurMasterName 5000
and doing a redis-cli FLUSHALL on the server takes > 5000 milliseconds, so the sentinels initiate a fail over.
We acknowledge that doing a FLUSHALL isn't great and we also know that we could increase the down-after-milliseconds to but for the purposes of this question assume that neither of these are options.
The question is: how can we do a FLUSHALL (or equivalent operation) WITHOUT having our sentinels initiate a fail over due to the FLUSHALL blocking for greater than 5000 milliseconds? Has anyone encountered and solved this problem?
You could just create new instances: if you are using something like AWS or Azure than you have API for creating a new Redis cluster. Start it, load it with data and once ready just modify the DNS, again with API call -so all these can be handled by some part of your application. But on premises things can get more complex because it will require some automation with ansible/chef/puppet.
The next best option you currently have to is to delete keys in batches to reduce the amout of work to at once. You can build a list, assuming you don't have one, using scan Then delete in whatever batch size works for you.
Edit: as you are not interested in keeping data, disable persistence, delete the RDB file, then just restart the instance. This way you do t have to update sentinel like you would if you take the provision new hosts.
Out of curiosity, if you're just going to be flushing all the time and don't care about the data as you'll be wiping it, why bother with sentinel?
Is it a good practice to run redis in production with Supervisor?
I've googled around, but haven't seen many examples of doing so. If not, what is the proper way of running redis in production?
I personally just use Monit on Redis in production. If Redis crash Monit will restart it but more importantly Monit will be able to monitor (and alert when a threeshold is reach) the amount of RAM that Redis currently takes (which is the biggest issue)
Configuration could be something like this (if maxmemory was set to 1Gb in Redis)
check process redis
with pidfile /var/run/redis.pid
start program = "/etc/init.d/redis-server start"
stop program = "/etc/init.d/redis-server stop"
if 10 restarts within 10 cycles
then timeout
if failed host 127.0.0.1 port 6379 then restart
if memory is greater than 1GB for 2 cycles then alert
Well..it depends. If I were do use redis under daemon control I would use runit. I do use monit but only for monitoring. I like to see the green light.
However, for redis to exploit the true power, you dont run redis as a deamon esp a master. If a master goes down, you will have to switch a slave to a master. Quit simply, I just shoot the node in the head and I have a chef recipe bring up a new node.
But then again....it also depends on how often you snapshot. I do not snapshot thus no need for deamon control.
People use reids for brute force speed. that means not writing to disk and keep all data in ram. If a node goes down...and you dont snapshot...data is lost.