Redis哨兵模式配置及go客户端自动切换主节点

哨兵模式介绍

哨兵(Sentinel)模式是Redis高可用的其中一种实现模式,其包含一个主节点(master)、多个从节点(replication,也称slave),以及多个哨兵节点(sentinel)。每个sentinel节点会对数据节点和其余sentinel节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果被标识的是“主节点”,它还会和其他的sentinel节点进行“协商”,当大多数sentinel节点都认为主节点不可达时,它们会选举一个sentinel节点来完成自动故障转移的工作,同时会将这个变化实时通知给Redis应用方。整个过程是自动的,不需要人工干预,解决了Redis的高可用问题。

哨兵模式服务端搭建(单机版)

在此采用单机版进行介绍,分布式版需要将IP地址改为对应的服务器IP即可。

节点说明IP地址redis端口号sentinel端口号
master127.0.0.1637926379
replica127.0.0.1638026380
replica127.0.0.1638126381
1. redis配置及启动

在这里插入图片描述
首先配置三个redis数据节点为主从模式,复制redis解压文件中的redis.conf三份,并重命名为redis_6379.conf、redis_6380.conf、redis_6381.conf。

修改主节点配置文件 redis_6379.conf:

port 6379
daemonize yes
pidfile "/var/run/redis_6379.pid"
logfile "6379.log"
dir "/usr/bin/sentinel/redis6379/"

修改从节点1的配置文件redis_6380.conf:

port 6380
daemonize yes
pidfile "/var/run/redis_6380.pid"
logfile "6380.log"
dir "/usr/bin/sentinel/redis6380/"
replicaof 127.0.0.1 6379

类似的,修改从节点2的配置文件redis_6381.conf:

port 6381
daemonize yes
pidfile "/var/run/redis_6381.pid"
logfile "6381.log"
dir "/usr/bin/sentinel/redis6381/"
replicaof 127.0.0.1 6379

接下来在命令行启动主节点和两个从节点:

redis-server  redis_6379.conf
redis-server  redis_6380.conf
redis-server  redis_6381.conf

连接端口号为6379的redis服务器,执行info replication可以查看主从节点信息,端口号6379的为master,端口号为6380、6381的为slave。

2. sentinel配置及启动

接下来配置sentinel,复制redis解压文件中的sentinel.conf三份,并重命名为redis_sentinel_26379.conf、redis_sentinel_26380.conf、redis_sentinel_26381.conf。
修改配置文件redis_sentinel_26379.conf:

port 26379
daemonize yes
pidfile "/var/run/redis_sentinel_26379.pid"
logfile "26379.log"
dir "/usr/bin/sentinel/redis6379/"
sentinel monitor mymaster 127.0.0.1 6379 2 
# mymaster是主节点的别名,监控的主节点是127.0.0.1:6379,
# 2代表判断主节点失败至少需要2个sentinel节点同意

类似的,修改配置文件redis_sentinel_26380.conf:

port 26380
daemonize yes
pidfile "/var/run/redis_sentinel_26380.pid"
logfile "26380.log"
dir "/usr/bin/sentinel/redis6380/"
sentinel monitor mymaster 127.0.0.1 6379 2 

类似的,修改配置文件redis_sentinel_26381.conf:

port 26381
daemonize yes
pidfile "/var/run/redis_sentinel_26381.pid"
logfile "26381.log"
dir "/usr/bin/sentinel/redis6381/"
sentinel monitor mymaster 127.0.0.1 6379 2

在命令行启动哨兵节点:

redis-sentinel  redis_sentinel_26379.conf
redis-sentinel  redis_sentinel_26380.conf
redis-sentinel  redis_sentinel_26381.conf

连接端口号为26379的哨兵节点,执行info sentinel可以查看哨兵信息。
在这里插入图片描述

3. 故障转移示例

执行 ps aux | grep redis 可以看到有单机版本有3个redis数据节点以及3个sentinel节点。
在这里插入图片描述
将此时的端口号为6379的进程杀死可以查看故障转移,执行 info sentinel 看到主节点已切换至端口号为6380的节点。此时会将主从节点信息的改动自动写入redis的配置文件以及sentinel配置文件。
在这里插入图片描述
至此介绍完了服务端的配置、启动、故障转移演示,实现原理后续继续发掘。

go客户端自动切换主节点

哨兵模式的客户端如果直接连接固定redis的IP地址和端口号,就不会自动切换主节点,因此,需要连接sentinel节点,由sentinel节点获取主节点的信息,实现服务端故障转移后,客户端能够自动连接到新的主节点上。
以go语言的redis client使用的redigo包为例,连接哨兵模式服务需要引入sentinel包,
sentinel包地址:https://github.com/FZambia/sentinel
其接口文档地址:https://godoc.org/github.com/FZambia/sentinel#Sentinel.Discover

客户端自动切换主节点的Demo如下,newSentinelPool函数实现了自动连接主节点,需要注意的是当主节点宕机时有主从节点切换的过程,此时会有几秒的连接失败,但服务端切换完成后,客户端可以自动连接。

package main

import (
    "errors"
    "fmt"
    "time"
    "github.com/gomodule/redigo/redis"
    "github.com/sentinel-master"
)

// Sentinel provides a way to add high availability (HA) to Redis Pool using
// preconfigured addresses of Sentinel servers and name of master which Sentinels
// monitor. It works with Redis >= 2.8.12 (mostly because of ROLE command that
// was introduced in that version, it's possible though to support old versions
// using INFO command).
//
// Example of the simplest usage to contact master "mymaster":

func newSentinelPool() *redis.Pool {
    sntnl := &sentinel.Sentinel{
        Addrs:      []string{":26379", ":26380", ":26381"},
        MasterName: "mymaster",
        Dial: func(addr string) (redis.Conn, error) {
            timeout := 500 * time.Millisecond
            c, err := redis.DialTimeout("tcp", addr, timeout, timeout, timeout)
            if err != nil {
                fmt.Println("newSentinelPool sntnl.Dial() error [", err, "]")
                return nil, err
            }
            return c, nil
        },
    }
    return &redis.Pool{
        MaxIdle:     3,
        MaxActive:   64,
        Wait:        true,
        IdleTimeout: 240 * time.Second,
        Dial: func() (redis.Conn, error) {
            masterAddr, err := sntnl.MasterAddr()
            if err != nil {
                fmt.Println("newSentinelPool Dial() masterAddr error [", err, "]")
                return nil, err 
            }
            fmt.Println("MasterAddr [", masterAddr, "]")
            c, err := redis.Dial("tcp", masterAddr)
            if err != nil {
                fmt.Println("connect master addr error [", err, "]")
                return nil, err 
            }
            return c, nil
        },
        TestOnBorrow: func(c redis.Conn, t time.Time) error {
            if !sentinel.TestRole(c, "master") {
                return errors.New("Role check failed")
            } else {
                return nil
            }
        },
    }
}

func main() {
    pool := newSentinelPool()
    conn := pool.Get()
    defer conn.Close()

    err := pool.TestOnBorrow(conn, time.Now())
    if err != nil {
        return
    }

    _,err = conn.Do("SET", "k", "value")
    if err != nil {
        fmt.Println("set error")
        return
    }
    v, err := conn.Do("GET", "k")
    if err != nil {
        fmt.Println("get error")
        return
    }
    fmt.Println("v:",v)
}

参考文献:
Redis高可用之哨兵模式Sentinel配置与启动(五)
redis 哨兵(sentinel)安装部署

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值