Redis——主从和哨兵机制
一、主从和哨兵机制:
1)主从:配置多态主从服务器,解决高可用问题;一台主服务器对应多台从服务器,从服务器自动拷贝主服务器的数据;
2)哨兵:配置哨兵模式,用于解决主服务器挂掉,需要再次手动配置从服务器作为主服务的操作;
哨兵会自动选择一台数据偏移量最大的从服务器,作为新得主服务器;
二、主从服务器配置:
1)创建两文件夹:分别存放两个服务器得数据卷和配置文件;
2)在配置文件中配置主服务器得密码:
masterauth 123456
3)使用docker启动两个容器:分别映射两个端口;
docker run -v /usr/local/docker/redis-master/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/docker/redis-master/conf/data:/data --name myredis-master -p 6379:6379 -d redis redis-server /usr/local/etc/redis/redis.conf
docker run -v /usr/local/docker/redis-slave/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/docker/redis-slave/conf/data:/data --name myredis-slave -p 6380:6379 -d redis redis-server /usr/local/etc/redis/redis.conf
4)在从服务器中使用命令连接主服务器;
slaveof 主服务器的ip地址 端口号
断开复制:slaveof no one
5)查看连接状态:
info replication
1、从服务器信息查看;
2、主服务器信息查看:
6)主从复制流程:
1、从节点保存主节点信息;
2、主从建立socket连接;
3、从节点发送ping命令,等待主节点返回pong回应;
4、权限验证;
5、主从连接正常后,开始同步数据集,首次建立复制,是全量复制的方式;
6、持续的主从复制,后续主节点发生数据变更,会继续给从节点发送命令,此处采用增量复制;
PS:
主节点和从节点都会记录一个叫复制偏移量的值,来确定从哪开始继续复制;
通过在主从节点执行info repplication 对比offset的值即可;
三、哨兵Redis Sentinel:
工作原理:
1、每个哨兵节点通过定时监控发现主节点出现故障;
2、多个哨兵节点对主节点的故障达成一致,则选择出一个哨兵节点作为领导者负责本次故障转移处理;
//达成一致得条件时超过半数,则至少需要三台服务器,配置三个哨兵;
3、哨兵全自动完成主服务器转移;
三、哨兵配置:
//配置哨兵需要三台服务器;//在redis.conf中设置slave-read-only no;不然无法写入
docker run -v /usr/local/docker/mymaster/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/docker/mymaster/conf/data:/data --name mymaster -p 6379:6379 -d redis redis-server /usr/local/etc/redis/redis.conf docker run -v /usr/local/docker/myslave1/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/docker/myslave1/conf/data:/data --name myslave1 -p 6380:6379 -d redis redis-server /usr/local/etc/redis/redis.conf docker run -v /usr/local/docker/myslave2/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/docker/myslave2/conf/data:/data --name myslave2 -p 6381:6379 -d redis redis-server /usr/local/etc/redis/redis.conf
1)从官网下载一个sentinel.conf;
2)配置:
1、打开保护模式:protected-mode no
2、定期检测时间(默认30秒):sentinel down-after-milliseconds mymaster 30000
3、故障转移后,每次向新的节点发起复制操作得从节点数;
4、故障转移失败,再次转移时间时这个时间得两倍;
5、设置这节点地址:地址不要127.0.0.1,远程会无法访问;2表示故障判断需要2个哨兵达成一致;
6、设置主节点密码;
7、设置哨兵端口:
3)启动:
docker run -v /usr/local/docker/redis-sentinel/sentinel1.conf:/usr/local/etc/redis/sentinel.conf --name redis-sentinel1 -p 26379:26379 -d redis redis-sentinel /usr/local/etc/redis/sentinel.conf docker run -v /usr/local/docker/redis-sentinel/sentinel2.conf:/usr/local/etc/redis/sentinel.conf --name redis-sentinel2 -p 26380:26379 -d redis redis-sentinel /usr/local/etc/redis/sentinel.conf docker run -v /usr/local/docker/redis-sentinel/sentinel3.conf:/usr/local/etc/redis/sentinel.conf --name redis-sentinel3 -p 26381:26379 -d redis redis-sentinel /usr/local/etc/redis/sentinel.conf
//自动恢复需要一定的处理时间,并不是即刻生效;
4)进入:/usr/local/bin
docker exec -it redis-sentinel1 bash
./redis-cli -p 26379
5)查看哨兵信息:
Sentinel masters
Sentinel master <master name>
Sentinel slaves <master name>
四、在spring中配置哨兵:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 哨兵配置 --> <bean id="sentinelConfig" class="org.springframework.data.redis.connection.RedisSentinelConfiguration"> <!-- 配置master主服务的名称 --> <property name="master"> <bean class="org.springframework.data.redis.connection.RedisNode"> <property name="name" value="mymaster"/> </bean> </property> <!-- 配置哨兵服务 --> <property name="sentinels"> <set> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="192.168.80.135"/> <constructor-arg name="port" value="26379"/> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="192.168.80.135"/> <constructor-arg name="port" value="26380"/> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="192.168.80.135"/> <constructor-arg name="port" value="26381"/> </bean> </set> </property> </bean> <!-- 配置redis连接池对象 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 最大空闲数 --> <property name="maxIdle" value="50" /> <!-- 最大连接数 --> <property name="maxTotal" value="100" /> <!-- 最大等待时间 --> <property name="maxWaitMillis" value="20000" /> </bean> <!-- stringRedisSerializer序列化器 --> <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/> <!-- 配置redis连接工厂 --> <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <!-- 连接池配置 --> <property name="poolConfig" ref="poolConfig" /> <!-- 连接主机 --> <!--<property name="hostName" value="192.168.80.135" />--> <!-- 端口 --> <!--<property name="port" value="6379" />--> <!--哨兵配置--> <constructor-arg name="sentinelConfig" ref="sentinelConfig"/> <!-- 密码 --> <property name="password" value="java1234" /> </bean> <!-- 配置redis模板对象 --> <bean class="org.springframework.data.redis.core.RedisTemplate"> <!-- 配置连接工厂 --> <property name="connectionFactory" ref="connectionFactory" /> <!--配置序列化器--> <property name="keySerializer" ref="stringRedisSerializer"/> <!--<property name="valueSerializer" ref="stringRedisSerializer"/>--> </bean> <!--配置监听器的实现类--> <bean id="messageListener" class="com.qf.listener.MyMessageListener"/> <!-- 配置消息监听容器 --> <bean id="messageListenerContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer" destroy-method="destroy"> <!-- redis连接工厂 --> <property name="connectionFactory" ref="connectionFactory"/> <!-- 配置监听配置 --> <property name="messageListeners"> <map> <!-- 配置监听器 --> <entry key-ref="messageListener"> <!-- 配置监听的渠道 --> <bean class="org.springframework.data.redis.listener.ChannelTopic"> <!-- --> <constructor-arg name="name" value="channel1"/> </bean> </entry> </map> </property> </bean> </beans>