当前位置: 首页 > news >正文

C#两大知名Redis客户端连接哨兵集群的姿势

前言

前面《Docker-Compose搭建Redis高可用哨兵集群》,
我的思路是将Redis、Sentinel、Redis Client App链接到同一个网桥网络,这个网桥内的Redis Client App就可以使用ContainerIP访问网桥内任意redis节点。

同一网桥网络访问规避了Docker上发生的NAT,端口映射的复杂性,  但实际上并不是最常规做法。

Redis Client App独立组网遇到的问题

很多时候,Redis Client App与Redis-Sentinel独立组网,这样对Redis-Sentinel的访问就会涉及Docker宿主机NAT转换、Port映射。

(这里我们就不提Docker Host模式搭建Redis-Sentinel了)

资料显示 Sentinel,Docker或其他形式的网络地址转换或端口映射应谨慎混合,大意是说节点无法区分收到的信息是否是已经发生Nat转换或端口映射的结果。

为了解决Redis-Sentinel在Docker环境下因为NAT,Forward Port导致的无法正确获知Slaves和正确故障转移的问题。

Redis3.2之后可以强制让Slave声明自己的(IP,Port);强制让Sentinel声明自己的(IP,Port)

 # since Redis 3.2.2, to force a replica to announce an arbitrary pair of IP and port to the master. The two configurations directives to use are:
replica-announce-ip <ip>
replica-announce-port <port>

上述配置可以写在Docker Command参数指定或通过Volume redis.conf 加载进redis容器

# you can use the following two Sentinel configuration directives in order to force Sentinel to announce a specific set of IP and port:sentinel announce-ip <ip>
sentinel announce-port <port>

sentinel.conf的配置只能通过Config加载进sentinel容器。

通过明牌方式通知所有交互对象,redis实例就是在这个(IP,Port)上发生了NAT转换、Port映射。

C#两大客户端访问Redis-Sentinel的方式

归根到底一张图:

  1. Redis Client先询问Sentinels,Sentinel返回Master (IP,Port)

  2. Redis Client再与以上Master (IP,Port)建立连接

Docker部署Redis-Sentinel 并强制声明IP、Port

这里我们采用主动声明方式在Docker上部署了Redis-Sentinel集群, 1Master- 2 Slave- 3Sentinel, 分别占据宿主机6380、6381、6382、 26379、26380、26381端口.

CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS                  PORTS                                NAMES
484da8d832f1        redis                          "docker-entrypoint.s…"   2 hours ago         Up 2 hours              6379/tcp, 0.0.0.0:26380->26379/tcp   redis-sentinel-2
50599c15adba        redis                          "docker-entrypoint.s…"   2 hours ago         Up 2 hours              6379/tcp, 0.0.0.0:26379->26379/tcp   redis-sentinel-1
51ce90cc52d7        redis                          "docker-entrypoint.s…"   2 hours ago         Up 2 hours              6379/tcp, 0.0.0.0:26381->26379/tcp   redis-sentinel-3
d58d6973de28        redis                          "docker-entrypoint.s…"   2 hours ago         Up 2 hours              0.0.0.0:6381->6379/tcp               redis-slave-1
b88bd85ac109        redis                          "docker-entrypoint.s…"   2 hours ago         Up 8 seconds            0.0.0.0:6382->6379/tcp               redis-slave-2
3dc26c01a90d        redis                          "docker-entrypoint.s…"   2 hours ago         Up About an hour        0.0.0.0:6380->6379/tcp               redis-master

进入任意Sentinel节点,使用sentinel master mymaster确认集群信息

存在测试键值:testKey:hello Redis-sentinel!

StackExchange.Redis & CSRedisCore连接Redis哨兵

老牌StackExchange.Redis 今年才真正支持Sentinel, Github上有关Sentinel的Issue、PR历时久远,PR像便秘一样最近才关闭。
https://github.com/StackExchange/StackExchange.Redis/pull/692#issuecomment-375298108
https://github.com/StackExchange/StackExchange.Redis/pull/1067

CSRedisCore得到真传,很早就支持连接哨兵,而且编程写法更简单,清晰。

话不多说:

using StackExchange.Redis;
using System;namespace ConsoleApp
{class Program{static void Main(string[] args){var sw = new Stopwatch();sw.Start();UseStackExchangeRedis();sw.Stop();Console.WriteLine("连接+查询测试key,耗时"+sw.ElapsedMilliseconds);sw.Reset();sw.Start();UseCSRedisCore();sw.Stop();Console.WriteLine("连接+查询测试key,耗时" + sw.ElapsedMilliseconds);Console.ReadKey();}// StackExchange.Reids连接Redis-Sentinelpublic  static void  UseStackExchangeRedis(){ConfigurationOptions sentinelOptions = new ConfigurationOptions();sentinelOptions.EndPoints.Add("180.76.*.*", 26379);sentinelOptions.EndPoints.Add("180.76.*.*", 26380);sentinelOptions.EndPoints.Add("180.76.*.*", 26381);sentinelOptions.TieBreaker = "";sentinelOptions.CommandMap = CommandMap.Sentinel;sentinelOptions.AbortOnConnectFail = false;// Connect!ConnectionMultiplexer sentinelConnection = ConnectionMultiplexer.Connect(sentinelOptions);// Get a connection to the masterConfigurationOptions redisServiceOptions = new ConfigurationOptions();redisServiceOptions.ServiceName = "mymaster1";   //master名称redisServiceOptions.Password = "redis_pwd";     //master访问密码redisServiceOptions.AbortOnConnectFail = true;ConnectionMultiplexer masterConnection = sentinelConnection.GetSentinelMasterConnection(redisServiceOptions);var db  = masterConnection.GetDatabase();var value= db.StringGet("testKey");Console.WriteLine($"[Use StackExchange-Redis] The remote redis-sentinel test key value:{value}");}// CSRedisCore连接Redis-Sentinelpublic static  void UseCSRedisCore(){var csredis = new CSRedis.CSRedisClient("mymaster1,password=redis_pwd",new[] { "180.76.*.*:26379", "180.76.*.*:26380", "180.76.*.*:26381" });var value = csredis.Get("testKey");Console.WriteLine($"[Use CSRedisCore] The remote redis-sentinel test key value:{value}");}}
}

执行输出:

StackExchange.Redis更能体现连接的实质过程:先查询,再连接。
CSRedisCore 小白写法,无感知。

总结输入

本文记录两个内容:

1. Redis-Sentinel在Docker环境因NAT,Forward_Port触发的问题, 以及Redis官方给出的方案

2. C# Redis客户端连接Redis-Sentinel集群

Gthub:https://github.com/zaozaoniao/Redis-sentinel-with-docker-compose

本文纯手写+测试,期待你的反馈。

  • https://redis.io/topics/sentinel

  • https://redis.io/topics/replication


http://www.taodudu.cc/news/show-911422.html

相关文章:

  • 7-Zip介绍:一个强大的开源压缩工具
  • Coredns搭建DNS服务
  • 【年报文本分析】第五辑:Python+Pytorch训练大语言模型,使用自训练模型完成文本分类任务——金星晔等(2024)《经济研究》大语言模型方法的复现
  • Elasticsearch映射定义
  • Next.js+TS项目中的错误边界处理与渲染降级实践
  • 维修贝加莱 MAHLO 5PP320.1043-K08 控制器 主板 工控电脑 触摸屏深圳捷达工控维修
  • dotNET Core 3.X 请求处理管道和中间件的理解
  • 了解.NET中的垃圾回收
  • 数字化演化历史
  • 如何查找,修复和避免C#.NET中内存泄漏的8个最佳实践
  • ASP.NET Core技术研究-探秘依赖注入框架
  • 从项目到产品: 软件时代需要价值流架构师 | IDCF
  • 推荐一个集录屏、截图、音频于一体的软件给大家
  • WebAssembly增加Go语言绑定
  • .NET中的内存管理
  • .Net微服务实战之技术架构分层篇
  • .NET 下基于动态代理的 AOP 框架实现揭秘
  • Blazor WebAssembly 3.2.0 Preview 4 如期发布
  • C#/.Net Core/WPF框架初建(国际化、主题色)
  • ASP.NET Core 日志框架:Serilog
  • 树莓派销量突然猛增
  • C#黔驴技巧之实现统计结果排名
  • Istio Pilot架构解析
  • 当模板方法遇到了委托函数,你的代码又可以精简了
  • 为什么要用内插字符串代替string.format
  • iPhone上运行Linux也要来了
  • 谁说.NET不适合搞大数据、机器学习和人工智能
  • .NET Core技术研究-主机
  • 多角度让你彻底明白yield语法糖的用法和原理及在C#函数式编程中的作用
  • 哪种开源许可证最适合商业化?
  • 还不会docker+k8s?2020年,就要面对现实了...
  • 3分钟掌握Quartz.net分布式定时任务的姿势
  • ASP.NET Core 配置源:实时生效
  • Linq下有一个非常实用的SelectMany方法,很多人却不会用
  • .NET Core前后端分离快速开发框架(Core.3.1+AntdVue)
  • 如何选择好公司