C#两大知名Redis客户端连接哨兵集群的姿势
<h2 id="前言">前言</h2><p>前面利用《Docker-Compose搭建Redis高可用哨兵集群》,<br>
我们的思路是将Redis、Sentinel、Redis Client App链接到同一个网桥网络,这个网桥内的Redis Client App就可以使用ContainerIP访问网桥内任意redis节点。<br>
<img src="https://img2020.cnblogs.com/blog/587720/202008/587720-20200804175721666-951480883.jpg" alt="" loading="lazy"></p>
<p><code>同一网桥网络访问</code>规避了Docker上发生的NAT,端口映射的复杂性,但实际上并不是最常规的做法(今天咱们也不说Docker host形式部署Redis-Sentinel了)。</p>
<h2 id="redis-client-app独立组网遇到的问题">Redis Client App独立组网遇到的问题</h2>
<p>很多时候,Redis-Sentinel与Redis Client App独立组网,涉及Docker宿主机NAT转换和 Port映射。</p>
<blockquote>
<p>Sentinel,Docker或其他形式的网络地址转换或端口映射应谨慎混合。<br>
我实际测试发现,如果将前文Sentinel.conf中Master(ContainerIP,Port) 换成(宿主机IP,映射Port),<br>
确实会引起混乱,无法找到正确的Slaves, 无法正常故障转移。</p>
</blockquote>
<p><img src="https://img2020.cnblogs.com/blog/587720/202008/587720-20200804180101308-999342526.jpg" alt="" loading="lazy"></p>
<p>为了解决Redis-Sentinel在Docker环境下因为NAT,Forward Port导致的无法正确获知Slaves和正确故障转移的问题。<br>
Redis3.2之后可以<code>强制让Slave声明自己的(IP,Port);强制让Sentinel声明自己的(IP,Port)</code></p>
<pre><code> # 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>
</code></pre>
<p>上述配置可以写在Docker Command参数指定或通过Volume redis.conf 加载进redis容器</p>
<pre><code># 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>
</code></pre>
<p>sentinel.conf的配置只能通过Config加载进sentinel容器。</p>
<p>通过明牌方式通知 所有交互对象,redis实例就是在这个(IP,Port)上发生了NAT转化,Port映射,上述搭建Docker搭建Redis-sentinel才是常规实践。</p>
<h2 id="c两大客户端访问redis-sentinel的方式">C#两大客户端访问Redis-Sentinel的方式</h2>
<p>归根到底一张图:<br>
<img src="https://img2020.cnblogs.com/blog/587720/202008/587720-20200804180131703-2054662837.jpg" alt="" loading="lazy"></p>
<ol>
<li>Redis Client先询问Sentinels,Sentinel返回Master (IP,Port)</li>
<li>Redis Client再与以上Master (IP,Port)建立连接</li>
</ol>
<h3 id="redis-sentinel">Redis-Sentinel</h3>
<p>这里我们采用Docker-compose在单机上部署了Redis-Sentinel集群,<br>
1Master- 2 Slave- 3Sentinel,<br>
分别占据宿主机6380、6381、6382、 26379、26380、26381端口.</p>
<pre><code>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
</code></pre>
<p>进入任意Sentinel节点,使用<code>sentinel master mymaster</code>确认集群信息</p>
<p><img src="https://img2020.cnblogs.com/blog/587720/202008/587720-20200804180158355-540281904.jpg" alt="" loading="lazy"></p>
<p>添加测试键值: testKey:hello Redis-sentinel!</p>
<h3 id="stackexchangeredis--csrediscore连接redis哨兵">StackExchange.Redis & CSRedisCore连接Redis哨兵</h3>
<p>老牌StackExchange.Redis 今年才真正支持Sentinel, Github上有关Sentinel的Issue、PR历时久远,PR像便秘一样最近才关闭。<br>
https://github.com/StackExchange/StackExchange.Redis/pull/692#issuecomment-375298108<br>
https://github.com/StackExchange/StackExchange.Redis/pull/1067</p>
<p>CSRedisCore得到真传,很早就支持了,而且编程写法更简单,清晰。</p>
<p>话不多说:</p>
<pre><code>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-Sentinel
publicstatic voidUseStackExchangeRedis()
{
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 master
ConfigurationOptions 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($" The remote redis-sentinel test key value:{value}");
}
// CSRedisCore连接Redis-Sentinel
public staticvoid 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($" The remote redis-sentinel test key value:{value}");
}
}
}
</code></pre>
<p>执行输出:</p>
<p><img src="https://img2020.cnblogs.com/blog/587720/202008/587720-20200804180236744-1342186205.jpg" alt="" loading="lazy"></p>
<blockquote>
<p>本文长话短说,快速介绍两块C#常见的Redis客户端连接Redis哨兵集群的方式,各有千秋。<br>
StackExchange.Redis更能体现连接的实质过程: 先查询,再连接。<br>
CSRedisCore 小白写法,无感知。</p>
</blockquote>
<p>Github地址:https://github.com/zaozaoniao/Redis-sentinel-with-docker-compose</p>
<h2 id="总结输入">总结输入</h2>
<p>本文记录两个内容:</p>
<ol>
<li>Redis-Sentinel在Docker环境因NAT,Forward_Port触发的问题, 以及Redis官方给出的方案</li>
<li>C#两个Redis客户端如何感知Redis-Sentinel的Master查询节点</li>
</ol>
<ul>
<li>https://redis.io/topics/sentinel</li>
<li>https://redis.io/topics/replication</li>
</ul>
</div>
<div id="MySignature" role="contentinfo">
<HR style="FILTER: alpha(opacity=100,finishopacity=0,style=3)" width="80%" color=#987cb9 SIZE=3>
<div style="text-align:center;">
<p>本文来自博客园,作者:{有态度的马甲},转载请注明原文链接:https://www.cnblogs.com/JulianHuang/p/12687090.html</p>
<strong style="color: red; ">欢迎关注我的原创技术、职场公众号, 加好友谈天说地,一起进化</strong>
<div><imgstyle="width: 250px;height:250px;" src="https://blog-static.cnblogs.com/files/JulianHuang/QR.gif" /> </div>
</div><br><br>
来源:https://www.cnblogs.com/JulianHuang/p/12687090.html
頁:
[1]