Go语言:go-redis客户端对sentinel模式下(非集群cluster)redis-server主从切换的支持

 通过调用NewFailoverClient函数可以创建一个能支持redis-server主从切换(sentinel模式下)的client, 基本用法如下:

redis主从节点

  • 主127.0.0.1:6388
  • 从127.0.0.1:6398

假如有3个sentinel实例依次为:127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381;sentinel的配置如下,

sentinel monitor mymaster 127.0.0.1 6388 2
sentinel down-after-milliseconds mymaster 6000
sentinel failover-timeout mymaster 18000
sentinel parallel-syncs mymaster 1

redissentinel.go 

package main

import (
        "fmt"
        "github.com/go-redis/redis"
        "time"
)

func main() {
        client := redis.NewFailoverClient(&redis.FailoverOptions{
                MasterName:    "mymaster",
                SentinelAddrs: []string{"127.0.0.1:26379", "127.0.0.1:26380", "127.0.0.1:26381"},
                Password:      "",
                DB:            0,
        })

        for {
                reply, err := client.Incr("pvcount").Result()
                fmt.Printf("reply=%v err=%v\n", reply, err)
                time.Sleep(1 * time.Second)
        }

}

实验1:redis节点主从切换 

运行redissentinel.go,并在执行过程中,shutdown redis主节点127.0.0.1:6388,可以看到在reply等于93和94之间,客户端监测到了主从切换,并重新连接到新的主节点,这段时间大致等于sentinel配置down-after-milliseconds的时长。

[root@dev example]# go run redissentinel.go
redis: 2020/10/30 00:09:53 sentinel.go:379: sentinel: discovered new sentinel="93db6069e9bde858a99b873048891912eecd45d4" for master="mymaster"
redis: 2020/10/30 00:09:53 sentinel.go:379: sentinel: discovered new sentinel="48ee106539cf267a79a84db621a01ee01b73ca5e" for master="mymaster"
redis: 2020/10/30 00:09:53 sentinel.go:332: sentinel: new master="mymaster" addr="127.0.0.1:6388"
reply=1 err=
reply=2 err=
reply=3 err=
reply=4 err=
reply=5 err=
reply=6 err=
...
reply=83 err=
reply=84 err=
reply=85 err=
reply=86 err=
reply=87 err=
reply=88 err=
reply=89 err=
reply=90 err=
reply=91 err=
reply=92 err=
reply=93 err=
reply=0 err=EOF
reply=0 err=dial tcp 127.0.0.1:6388: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6388: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6388: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6388: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6388: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6388: connect: connection refused
redis: 2020/10/30 00:11:33 sentinel.go:332: sentinel: new master="mymaster" addr="127.0.0.1:6398"
reply=94 err=
reply=95 err=
reply=96 err=
reply=97 err=
reply=98 err=
reply=99 err=
reply=100 err=

实验2:sentinel实例全部挂掉后,redis的读写操作

如果把3个sentinel实例全部 kill掉,则go-redis会记录一条日志,而对redis的读写操作仍然正常。

reply=233 err=
reply=234 err=
reply=235 err=
reply=236 err=
reply=237 err=
redis: 2020/10/30 22:06:45 pubsub.go:159: redis: discarding bad PubSub connection: EOF                                                                                                   
reply=238 err=
reply=239 err=
reply=240 err=

实验3:sentinel实例部分挂掉后(剩余实例数目多于配置的quorum),redis实例的主从切换

如果只kill掉1个sentinel,则剩余两个sentinel还能正常监测redis主从切换。例如下面是kill掉127.0.0.1:26379之后,再kill redis主节点127.0.0.1:6388的实验:

reply=322 err=
reply=323 err=
reply=324 err=
reply=325 err=
reply=326 err=
reply=327 err=
reply=328 err=
reply=329 err=
reply=330 err=
reply=0 err=EOF
redis: 2020/10/30 22:08:19 sentinel.go:313: sentinel: GetMasterAddrByName name="mymaster" failed: EOF
redis: 2020/10/30 22:08:19 sentinel.go:313: sentinel: GetMasterAddrByName name="mymaster" failed: dial tcp 127.0.0.1:26379: connect: connection refused
redis: 2020/10/30 22:08:19 sentinel.go:287: sentinel: GetMasterAddrByName master="mymaster" failed: dial tcp 127.0.0.1:26379: connect: connection refused
redis: 2020/10/30 22:08:19 sentinel.go:379: sentinel: discovered new sentinel="9a023490096f5f87db1c7f445d883f56e75275db" for master="mymaster"
reply=0 err=dial tcp 127.0.0.1:6388: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6388: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6388: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6388: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6388: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6388: connect: connection refused
redis: 2020/10/30 22:08:24 sentinel.go:332: sentinel: new master="mymaster" addr="127.0.0.1:6398"
reply=331 err=
reply=332 err=
reply=333 err=
reply=334 err=

实验4:sentinel实例都正常的情况下,进行redis实例迁移

当3个sentinel都正常运行的情况下,动态增减从节点对客户端没有影响。例如增加一个从节点127.0.0.1:6378再把原从节点127.0.0.1:6388 shutdown,客户端没有影响。进而把主节点127.0.0.1:6398 shutdown,迫使主从切换,结果证明客户端能够切换到新的主节点127.0.0.1:6378上。

reply=525 err=
reply=526 err=
reply=527 err=
reply=528 err=
reply=529 err=
reply=530 err=
reply=531 err=
reply=0 err=EOF
reply=0 err=dial tcp 127.0.0.1:6398: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6398: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6398: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6398: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6398: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6398: connect: connection refused
reply=0 err=dial tcp 127.0.0.1:6398: connect: connection refused
redis: 2020/10/30 22:43:19 sentinel.go:332: sentinel: new master="mymaster" addr="127.0.0.1:6378"
reply=532 err=
reply=533 err=
reply=534 err=
reply=535 err=
reply=536 err=
reply=537 err=

小结:

通过上面的实验证明,go-redis的NewFailoverClient对sentinel模式下的redis应用是稳定可靠的。

 

你可能感兴趣的:(go,go,redis,sentinel)