ladenedge
ladenedge

Reputation: 13419

How do I write to a slave using StackExchange.Redis?

I'm using StackExchange.Redis to talk to a pair of Redis servers, a master and a slave. When I fail the master, I am unable to write to the slave.

I have IServer.AllowSlaveWrites set to true, and I have the slave-read-only config setting set to no on both servers. (Confirmed by INFO.)

When the master is still in the client's server pool (but offline), I get:

RedisConnectionException: SocketFailure on <master_ip>/Subscription

If I take the master out of the server pool entirely, I get:

RedisConnectionException: No connection is available to service this operation: SET ...

In the first case, it seems to be trying to talk to the master, and giving up on failure. In the second, it's talking to the slave but can't execute write operations.

How do I get my client to write to a slave server without a master present?

(See also How does StackExchange.Redis use multiple endpoints and connections?)

Upvotes: 1

Views: 2551

Answers (3)

Chen
Chen

Reputation: 1

Here is my code:

IServer ser = RedisConn.GetServer("192.168.1.1", 6379);
ser.AllowSlaveWrites = true;
ser.Execute("set",new object[2] { "test",1});

Upvotes: 0

Erdogan Gulsoy
Erdogan Gulsoy

Reputation: 21

I recently had a similar issue. Here is how I fixed it:

IConnectionMultiplexer con = ConnectionMultiplexer.Connect("127.0.0.1:6379");
IDatabase db = con.GetDatabase();
db.Execute("ZINTERSTORE", key, 2, first, second, "WEIGHTS", 0, 1);

As you can see above db.Execute method would do the trick.

Upvotes: 0

ladenedge
ladenedge

Reputation: 13419

It turns out the library is hardcoded to not allow write operations to slaves.

In the constructor of Message (Message.cs, line 170), there is the following code:

bool masterOnly = IsMasterOnly(command);
if (masterOnly) SetMasterOnly();

IsMasterOnly() returns true for all write commands. SetMasterOnly() overrides any master/slave flags the user supplied in favor of CommandFlags.DemandMaster. When the system tries to write to a slave, this flag triggers the RedisConnectionException quoted above.

I'm not sure why this hardcoded override is in there, as the AllowSlaveWrites flag and the slave_read_only config value already protect from accidental slave writes (see WriteMessageToServer()).

In any case, removing these lines from Message.cs seems to allow for the expected operation.

Upvotes: 3

Related Questions