哨兵模式是Redis集群管理的一种方式。

下面以Go语言为例介绍其使用方式。

使用举例

package main
import (
"fmt"
"strings"
"github.com/garyburd/redigo/redis" "github.com/FZambia/sentinel"
) var RedisConnPool *redis.Pool func InitRedisSentinelConnPool() {
redisAddr := "192.168.1.11:26378,192.168.1.22:26378"
redisAddrs := strings.Split(redisAddr, ",")
masterName := "master1" // 根据redis集群具体配置设置 sntnl := &sentinel.Sentinel{
Addrs: redisAddrs,
MasterName: masterName,
Dial: func(addr string) (redis.Conn, error) {
timeout := 500 * time.Millisecond
c, err := redis.DialTimeout("tcp", addr, timeout, timeout, timeout)
if err != nil {
return nil, err
}
return c, nil
},
} RedisConnPool = &redis.Pool{
MaxIdle: redisConfig.MaxIdle,
IdleTimeout: 240 * time.Second,
Dial: func() (redis.Conn, error) {
masterAddr, err := sntnl.MasterAddr()
if err != nil {
return nil, err
}
c, err := redis.Dial("tcp", masterAddr)
if err != nil {
return nil, err
}
return c, nil
},
TestOnBorrow: CheckRedisRole,
}
} func CheckRedisRole(c redis.Conn, t time.Time) error {
if !sentinel.TestRole(c, "master") {
return fmt.Errorf("Role check failed")
} else {
return nil
}
} func main(){
rc := RedisConnPool.Get()
defer rc.Close() for {
reply, err := redis.String(rc.Do("RPOP", "/queue/cmd"))
if err != nil {
if err != redis.ErrNil {
log.Println("Redis RPOP failed:", err)
} fmt.Println("reply:", reply)
break
}// if }// for
}

哨兵方式client端的实现原理

client查询集群中的master节点。

client查询Master

其代码如下:

// MasterAddr returns an address of current Redis master instance.
func (s *Sentinel) MasterAddr() (string, error) {
res, err := s.doUntilSuccess(func(c redis.Conn) (interface{}, error) {
return queryForMaster(c, s.MasterName)
})
if err != nil {
return "", err
}
return res.(string), nil
}

基本过程是:使用redis 服务器地址,创建连接,发送请求,返回Redis Master地址。

连接redis集群使用的是轮询方式(见doUntilSuccess函数)。

doUntilSuccess函数接收查询master的函数queryForMaster作为参数,queryForMaster的代码如下。

查询master节点

func queryForMaster(conn redis.Conn, masterName string) (string, error) {
res, err := redis.Strings(conn.Do("SENTINEL", "get-master-addr-by-name", masterName))
if err != nil {
return "", err
}
if len(res) < 2 {
return "", errors.New("redigo: malformed get-master-addr-by-name reply")
}
masterAddr := net.JoinHostPort(res[0], res[1])
return masterAddr, nil
}

轮询方式连接服务器doUntilSuccess

基本过程如下:

从Redis服务器地址中选择一台机器,尝试连接,并执行查询操作。如果成功,则直接返回结果。并将这台机器地址活跃性权重提升。

如果第一个地址失败,把这个地址从连接池中去掉,并降低活跃性权重。接着,尝试下一个地址。

如果所有地址都失败,则返回错误。

具体代码如下:

func (s *Sentinel) doUntilSuccess(f func(redis.Conn) (interface{}, error)) (interface{}, error) {
s.mu.RLock()
addrs := s.Addrs
s.mu.RUnlock() var lastErr error for _, addr := range addrs {
conn := s.get(addr)
reply, err := f(conn)
conn.Close()
if err != nil {
lastErr = err
s.mu.Lock()
pool, ok := s.pools[addr]
if ok {
pool.Close()
delete(s.pools, addr)
}
s.putToBottom(addr)
s.mu.Unlock()
continue
}
s.putToTop(addr)
return reply, nil
} return nil, NoSentinelsAvailable{lastError: lastErr}
}

参考

https://github.com/garyburd/redigo

https://github.com/FZambia/go-sentinel

https://godoc.org/github.com/FZambia/go-sentinel

https://redis.io/topics/sentinel-clients

redis sentinel哨兵的使用的更多相关文章

  1. Redis Sentinel哨兵配置

    概述 Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都 ...

  2. Redis的主从复制与Redis Sentinel哨兵机制

    1    Redis的主从复制 1.1   什么是主从复制 持久化保证了即使redis服务重启也不会丢失数据,因为redis服务重启后会将硬盘上持久化的数据恢复到内存中,但是当redis服务器的硬盘损 ...

  3. Redis Sentinel哨兵集群

    Redis Sentinel(哨兵集群)是一种高可用的redis部署方案.在集群中的redis-master服务挂掉时,无需人为干预,即可通过哨兵集群的自我调整,实现redis服务的持续可用. 哨兵集 ...

  4. Redis sentinel 哨兵模式集群方案配置

    第一个方案是创建 redis cluster,第二种方案就是用哨兵模式来进行主从替换以及故障恢复.兵模式集群方案配置 一.sentinel介绍 Sentinel作用: 1):Master状态检测 2) ...

  5. Redis sentinel 哨兵模式

    一.sentinel介绍 Sentinel作用: 1):Master状态检测 2):如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Maste ...

  6. Redis:Sentinel哨兵

    简介 Sentinel的作用就是主从切换:Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,R ...

  7. 【Redis】Redis Sentinel 哨兵模式搭建

    Redis Sentinel介绍 Redis Sentinel是Redis的官方高可用性解决方案 Redis Sentinel为Redis提供高可用性.实际上,这意味着使用Sentinel可以创建一个 ...

  8. Redis 5 配置 Redis sentinel(哨兵模式)

    先了解一下哨兵都 做了什么工作:Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务: * 监控(Monitoring): Sentin ...

  9. redis sentinel哨兵模式集群搭建教程

    1.环境说明 我们将使用192.168.220.128.192.168.220.129两台机器搭建sentinel交叉主从为例 当前我们已在192.168.220.128上按redis安装教程安装了r ...

随机推荐

  1. PAT乙级 1016. 部分A+B (15)

    题目传送:https://www.patest.cn/contests/pat-b-practise/1016 正整数A的“DA(为1位整数)部分”定义为由A中所有DA组成的新整数PA.例如:给定A ...

  2. 基于链路的OSPFMD5口令认证

    实验要求:掌握基于链路的OSPFMD5口令认证 拓扑如下: 配置如下: R1enable configure terminal interface s0/0/0ip address 192.168.1 ...

  3. python基于并发与socket实现远程文件传输程序

    FTP程序 Client: * bin/start.py 程序入口 * conf/配置文件存放 * core/ * auth.py 登陆,注册以及上传下载查看当前文件夹下文件以及删除功能存放 * cl ...

  4. jvm内存增长问题排查简例

    jvm内存增长问题排查 排查个jvm 内存占用持续增加的问题,纪录一下,引以为戒. 运维发现应用jvm内存占用在发布后回落,然后持续增高,,dump后分析一下: 占内存的大部分是这种名字相似的bean ...

  5. Ubuntu16.04通过GPT挂载硬盘

    一般而言,服务器上挂载的硬盘都是比较大的,传统的对硬盘进行分区需要在终端敲sudo fdisk进行操作,但是, 当挂载的硬盘的容量大于2T的时候,是无法通过sudo fdisk进行挂载的,这个时候必须 ...

  6. 九度OJ1451题-信封错装

    题目1451:不容易系列之一 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:2004 解决:1210 题目描述: 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了!做好“ ...

  7. mysql手动设置数据表的自增值

    设置表tablename的自增值从1开始自增值 alter table tablename auto_increment=1;

  8. 20155208徐子涵 2016-2017-2 《Java程序设计》第9周学习总结

    20155208徐子涵 2016-2017-2 <Java程序设计>第9周学习总结 教材学习内容总结 第十六章 整合数据库 16.1 JDBC入门 撰写应用程序是利用通信协议对数据库进行指 ...

  9. MySQL数据库一

    MySQL的基本命令: 进入数据库: mysql -u [username] -p[password]   (注:-u 和 用户名之间可以有空格 -p和password之间无空格)  mysql -u ...

  10. LeetCode - Is Graph Bipartite?

    Given an undirected graph, return true if and only if it is bipartite. Recall that a graph is bipart ...