可写的从服务器
从 Redis 2.6 版本开始,Redis 的从服务器在默认状态下只允许执行读命令。如果用户尝试对一个只读从服务器执行写命令,那么从服务器将返回以下错误信息:
- 127.0.0.1:12345> REPLICAOF 127.0.0.1 6379
- OK
- 127.0.0.1:12345> SET msg "hello world"
- (error) READONLY You can't write against a read only replica.
Redis 之所以将从服务器默认设置为只读服务器,是为了确保从服务器只能通过与主服务器进行数据同步来得到更新,从而保证主从服务器之间的数据一致性。
但在某些情况下,我们可能想要将一些不太重要或者临时性的数据储存在从服务器里面,又或者不得不在从服务器里面执行一些带有写性质的命令(比如 ZINTERSTORE
命令,它只能将计算结果储存在数据库里面,不能直接返回计算结果)。这时我们可以通过将 replica-read-only
配置选项的值设置为 no
来打开从服务器的写功能:
- replica-read-only <yes|no>
比如说,如果我们在启动服务器 127.0.0.1:12345
的时候,将 replica-read-only
配置选项的值设置为 no
:
- $ redis-server --port 12345 --replica-read-only no
那么即使它变成了一个从服务器,它也能够正常地执行客户端发送的写命令:
- 127.0.0.1:12345> REPLICAOF 127.0.0.1 6379
- OK
- 127.0.0.1:12345> SET msg "hello world again!"
- OK
- 127.0.0.1:12345> GET msg
- "hello world again!"
注解
使用可写从服务器的注意事项
在使用可写的从服务器时,用户需要注意以下几个方面:
在主从服务器都可写的情况下,程序必须将写命令发送到正确的服务器上面,不能把需要在主服务器执行的写命令发送给从服务器执行,也不能把需要在从服务器执行的写命令发送给主服务器执行,否则就会出现数据错误。
从服务器执行写命令得到的数据,可能会被主服务器发送的写命令覆盖。比如说,如果从服务器在执行了客户端发送的
SET msg "hello from client"
命令之后,又接收到了主服务器发送的SET msg "hello from master"
命令,那么客户端写入的msg
键将被主服务器写入的msg
键覆盖。因为这个原因,客户端在从服务器上面执行写命令时,应该尽量避免与主服务器发生键冲突,换句话说,用户应该让客户端和主服务器分别对从服务器数据库中不同的键进行写入,而不要让客户端和主服务器都去写相同的键。当从服务器与主服务器进行完整同步时,从服务器数据库包含的所有数据都将被清空,其中包括客户端写入的数据。
为了减少内存占用,降低键冲突发生的可能性,并确保主从服务器的数据同步操作可以顺利进行,客户端写入到从服务器的数据应该在使用完毕之后尽快删除。一个比较简单的方法是在客户端向从服务器写入数据的同时,为数据设置一个比较短的过期时间,使得这些数据可以在使用完毕之后自动被删除。