项目中考虑到容灾、性能以及容量,一般会使用集群方式搭建redis。而当redis主服务器存在故障,为了redis仍能正常运行,可以搭建redis哨兵,通过选举方式重新建立主从关系。本文简单讲述主从建立和哨兵的配置。本机测试redis为redis-x64-3.2.100(windows下载地址:https://github.com/microsoftarchive/redis/releases),使用一台机器运行测试。
1.1 下载解压
下载完成后进行解压,然后复制两份作为从成员,构成一主二从。
1.2 主从配置
主redis配置:编辑文件夹下redis.windows.conf文件,设置bind和port,因为我是本机测试,默认设置bind 127.0.0.1,port 6379
从redis配置:同样编辑文件夹下redis.windows.conf文件,设置bind和port。由于我是一台机器设置两个从redis,所以bind都是127.0.0.1,port分别是6380和6381。做完以上操作,如何标志这两redis是从关系呢?所以,还需要在配置文件中加上一行配置。注意:两个从redis都是相同的配置语句,因为都从属于同一个主redis。
slaveof 127.0.0.1 6379
1.3 主从redis启动
在文件加中使用cmd进入命令窗口,输入redis-server redis.windows.conf即可启动(redis-server.exe和redis.windows.conf文件在相同文件夹下),依次启动主和从redis。
redis-server redis.windows.conf
2.1 哨兵配置
在三个redis文件加中创建redis.windows.sentinel.conf文件,设置绑定的port为26379、26380和26381,设置哨兵监视的主服务器(注意:3个哨兵都只配置监视的主redis的ip和端口,也就是127.0.0.1:6379这一个,不是分别写其所在redis的ip和端口)
哨兵1配置
#哨兵1端口 port 26379 #mymaster 即命名的主redis,后续客户端连接哨兵的时候将会使用, #主服务器ip:127.0.0.1 端口 6379 ##2表示在sentinel集群中最少需要有两个节点检测到redis主节点出故障就进行主从切换 sentinel monitor mymaster 127.0.0.1 6379 2
哨兵2配置
#哨兵2端口 port 26380 #mymaster 即命名的主redis,后续客户端连接哨兵的时候将会使用, #主服务器ip:127.0.0.1 端口 6379 ##2表示在sentinel集群中最少需要有两个节点检测到redis主节点出故障就进行主从切换 sentinel monitor mymaster 127.0.0.1 6379 2
哨兵3配置
#哨兵3端口 port 26381 #mymaster 即命名的主redis,后续客户端连接哨兵的时候将会使用, #主服务器ip:127.0.0.1 端口 6379 ##2表示在sentinel集群中最少需要有两个节点检测到redis主节点出故障就进行主从切换 sentinel monitor mymaster 127.0.0.1 6379 2
2.2 启动哨兵
在文件加中使用cmd进入命令窗口,输入redis-server redis.windows.sentinel.conf –sentinel即可启动(redis-server.exe和redis.windows.sentinel.conf文件在相同文件夹下),依次启动3个哨兵。
redis-server redis.windows.sentinel.conf --sentine
启动后会显示从成员和主成员
3 测试功能
将主redis关闭,可发现哨兵会重新选举主服务器,然后继续保持主从关系,重新启动关闭的redis,该redis将变成从成员。
4 代码连接redis
在.net core环境下,使用进行连接测试,采用哨兵的连接方式。
class program { static void main(string[] args) { var csredis = new csredis.csredisclient("mymaster", new string[] { "127.0.0.1:26379", "127.0.0.1:26380", "127.0.0.1:26381" }); redishelper.initialization(csredis); while (true) { try { redishelper.set("time", datetime.now.tostring("yyyy-mm-dd hh:mm:ss"));//设置值。默认永不过期 console.writeline(redishelper.get<string>("time")); system.threading.thread.sleep(1000); } catch(exception e) { console.writeline(e.message); } } } }