0

I want to mark a standalone Redis server (not a Redis-Cluster, not a Redis-Sentinel) as read-only. I have been googling for this for quite sometime but I don't seem to find a definite answer (Almost all answers point to Clustering or Sentinel). I was looking out for some config modification (CONFIG SET something).

NOTE: config set replica-read-only yes does not make the current redis-server read-only, but only its replicas.

My use-case basically is I am doing a migration wherein at some point I want to make the redis-server read-only. My application code can handle failures whenever a write call happens so that's not an issue.

Also, if this is not directly possible from redis server, is there something that I can do in the client code that'll have the same effect (I am using redis-py as the client library)? (Although this is less than ideal)

Things that I've tried

  • Played around with config set replica-read-only yes and other configs. They don't seem to be applying the current redis-server.
  • Tried marking a redis-server as a replica of itself (This was illogical, but just wanted to see if this worked), but turns out it deleted all keys in my local redis, so not something I can do.
Kamehameha
  • 5,423
  • 1
  • 23
  • 28

2 Answers2

1

There're several solution you can try:

  • You can use the rename-command config to disable write commands. If you only want to disable small number of commands, that's a good solution. However, since there're too many write commands, you might need to have too many configuration, and easy to miss some of them.

  • If you're using Redis 6.0, you can use Redis ACL to disable write commands for specific users.

  • You can setup a read-only Redis replica for your master, and ask clients to read from the replica.

for_stack
  • 21,012
  • 4
  • 35
  • 48
  • I really like the idea of the rename-command, I did not know this was a thing. I hacked together something on the client-side wherein I listen to a small set of write commands and then block them from being called. This seems to fit exactly into that paradigm, since it'll be more robust. – Kamehameha Sep 21 '20 at 03:29
  • I use redis-5 so point-2 is out, and due to restrictions in our infrastructure, I can't add a replica, so point-3 is out. Will definitely try this out. Thank you! (I'll wait for a day to see if there is a truly config solution of some sort `CONFIG write OFF` or something like that, and then mark this as the accepted answer!). – Kamehameha Sep 21 '20 at 03:31
  • It seems that `rename-command` only works from the .conf file and not from the redis-cli. So this means that I can't dynamically load this right? I'd have to restart the server after updating the file. – Kamehameha Sep 21 '20 at 04:58
  • 1
    @Kamehameha YES, seems you cannot dynamically load this config. – for_stack Sep 21 '20 at 07:55
1

Once the writes are done and you want to switch the node to read-only, couple of ways to do that:

  1. Modify the redis.conf to have "min-replicas-to-write 3". Since you don't have 3 replicas your node will stop accepting writes but will continue to serve reads, as shown below:

enter image description here

However, please note that after modifying redis.conf, you will have to restart your redis node for the changes to take effect.

  1. Another way is when you want to switch to readonly mode, at that time you create a replica and let it sync with the master and then kill the master node. Then replica will exist as read only.
Vikram Rawat
  • 1,472
  • 11
  • 16
  • Although I implemented the rename-command suggestion, this also seems to work well. Thank you! – Kamehameha Sep 21 '20 at 13:27
  • 2
    Hmm, `config set min-replicas-to-write 3` seems to work dynamically too, without the need to restart the redis-server! I'll play around this a little bit more, and I'll mark this as the answer in sometime since this approach won't need a restart! – Kamehameha Sep 21 '20 at 14:02
  • Whether a config command is run or a restart command is run, in both approaches a command needs to be run. Since in your case the command anyways causes write to fail on the client, there is not major benefit of config over restart command. Yes, you may miss out on interim reads but the restart happens within a second. Running a config is more convenient though than running a restart. – Vikram Rawat Sep 21 '20 at 14:31
  • My problem seems to be that whenever a redis-server is restarted, the existing connections from the client app seem to become stale momentarily, throwing ConnectionNotFound or timeout momentarily before starting to work again. Maybe there's something wrong with my setup (I am not 100% on that), That's why I am leaning to solutions which don't require a restart, and can be applied from the redis-cli – Kamehameha Sep 21 '20 at 14:35
  • Ok.. makes sense then. I will also recommend to test and fix the client app setup for better fault tolerance. Cheers. And thanks for sharing config command. – Vikram Rawat Sep 21 '20 at 14:37