Want to read from replicas and only write to the master, to reduce master loads.
Create read-only clients using NewFailOverClient(opt)
with opt.SlaveOnly
set to true
.
IMPORTANT NOTE:
If this field is false
, go-redis will only choose the MASTER. Too bad!
https://github.com/go-redis/redis/blob/cae67723092cac2cb441bc87044ab9edacb2484d/sentinel.go#L227
if failover.opt.SlaveOnly {
addr, err = failover.RandomSlaveAddr(ctx)
} else {
addr, err = failover.MasterAddr(ctx)
if err == nil {
failover.trySwitchMaster(ctx, addr)
}
}
If set to true
, go-redis will find a random slave through Sentinel each time, which perfectly suits our purpose.
SlaveOnly: If there’re many replicas, it will randomly choose one. Does the “choose” action happen only when the Client sets up or it happens for every command (like GET)?
The “choose” action only happens on Client creation. After that, all commands are directed to the same replica.
c := NewFailoverClient()
err := c.FlushAll(c.Context()).Err()
if err != nil {
panic(err)
}
err = c.Set(c.Context(), "k1", "v1", 0).Err()
if err != nil {
panic(err)
}
roc := NewFailoverReadOnlyClient()
for i := 0; i < 3; i++ {
res, err := roc.Get(roc.Context(), "k1").Result()
if err != nil {
panic(err)
}
fmt.Println(res)
}
Listen for GET commands on each replica using
redis-cli -p 6380 -a password monitor | grep "get"
All directed to one replica.
c := NewFailoverClient()
err := c.FlushAll(c.Context()).Err()
if err != nil {
panic(err)
}
err = c.Set(c.Context(), "k1", "v1", 0).Err()
if err != nil {
panic(err)
}
for i := 0; i < 3; i++ {
roc := NewFailoverReadOnlyClient()
res, err := roc.Get(roc.Context(), "k1").Result()
if err != nil {
panic(err)
}
fmt.Println(res)
}
Requests are directed to different replicas.