代码已上传至Github,有兴趣的同学可以下载来看看:https://github.com/ylw-github/SpringBoot-Redis-Demo
在上一篇博客《分布式系列教程(03) -分布式Redis缓存(二)》主要讲解了SpringBoot是如何整合Redis的。接下来主要继续讲解Redis的事务、主从复制以及哨兵机制。
本文目录结构:
l________1.1 SpringBoot操作Redis事务
附:阅读前可以参考之前我写过的博客:
1.Redis事务
Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:
- 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
- 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
一个事务从开始到执行会经历以下三个阶段:
- 开始事务
- 命令入队
- 执行事务
以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令:
127.0.0.1:6379> MULTI OK 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days" QUEUED 127.0.0.1:6379> GET book-name QUEUED 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series" QUEUED 127.0.0.1:6379> SMEMBERS tag QUEUED 127.0.0.1:6379> EXEC 1) OK 2) "Mastering C++ in 21 days" 3) (integer) 3 4) 1) "Mastering Series" 2) "Programming" 3) "C++"
1.1 SpringBoot操作Redis事务
直接贴核心代码:(Github版本:7b94bc1830ad5ffb1f0bcb41fe6c9acd9402fcc3
)
public void setStringTransactoin(String key, Object object){ stringRedisTemplate.setEnableTransactionSupport(true); // 开启事务 stringRedisTemplate.multi(); try { // 如果是String 类型 String value = (String) object; stringRedisTemplate.opsForValue().set(key, value); //int i = 1/0;//如果解注释这一句,抛异常,会回滚到初始状态 } catch (Exception e) { // 回滚 stringRedisTemplate.discard(); } finally { // 提交 stringRedisTemplate.exec(); } }
2.Redis主从复制
redis的复制功能是支持多个数据库之间的数据同步。
一类是主数据库(master)一类是从数据库(slave),主数据库可以进行读写操作,当发生写操作的时候自动将数据同步到从数据库,而从数据库一般是只读的,并接收主数据库同步过来的数据。
一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。
优点:通过redis的复制功能可以很好的实现数据库的读写分离,提高服务器的负载能力。主数据库主要进行写操作,而从数据库负责读操作。
2.1 主从复制过程
1.当一个从数据库启动时,会向主数据库发送sync命令,
2.主数据库接收到sync命令后会开始在后台保存快照(执行rdb操作),并将保存期间接收到的命令缓存起来
3.当快照完成后,redis会将快照文件和所有缓存的命令发送给从数据库。
4.从数据库收到后,会载入快照文件并执行收到的缓存的命令。
2.2 如何实现主从复制?
1.修改从Redis服务器(slave)的 redis.conf文件
vi /usr/local/redis/etc/redis.conf # 修改内容: # slaveof 192.168.162.131 6379 --- 主redis服务器ip和端口 # masterauth 123 --- 主redis服务器配置了密码,则需要配置
2.启动主Redis服务器(master),启动后,可以看到是没有任何数据的:
/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379 -a "123" keys *
2.启动从Redis服务器(slave),启动后,可以看到是没有任何数据的:
/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379 -a "123" keys *
3.现在向主Redi服务写入数据
4.从Redis服务器获取name
可以看到,slave服务器从主服务器复制内容过来了。
5.尝试向从服务器写内容,发现是不能写入的(只读),提示:(error) READONLY You can’t write against a read only slave.
3.Redis哨兵机制
Redis的哨兵(sentinel音标:[ˈsentɪnl]
) 系统用于管理多个 Redis 服务器,该系统执行以下三个任务:
- 监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
- 提醒(Notification):当被监控的某个 Redis出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master; 当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用Master代替失效Master。
特点:
- 哨兵(sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master。
- 每个哨兵(sentinel) 会向其它哨兵(sentinel)、master、slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方已挂(所谓的”主观认为宕机” Subjective Down,简称sdown)。
- 若“哨兵群”中的多数sentinel,都报告某一master没响应,系统才认为该master"彻底死亡"(即:客观上的真正down机,Objective Down,简称odown),通过一定的vote算法,从剩下的slave节点中,选一台提升为master,然后自动修改相关配置。
- 虽然哨兵(sentinel) 释出为一个单独的可执行文件 redis-sentinel ,但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动哨兵(sentinel)。
- 哨兵(sentinel) 的一些设计思路和zookeeper非常类似
单个哨兵(sentinel):
3.1 哨兵模式配置
接着前面的环境
Redis服务器ip | 定义 |
192.168.162.131 | 主Redis服务器 |
192.168.162.132 | 从Redis服务器 |
192.168.162.133 | 哨兵服务器 |
首先在哨兵服务器(192.168.162.133)搭建环境,参考《分布式系列教程(02) -分布式Redis缓存(简介&安装&基础)》
继续下面操作:
1.拷贝到etc目录
cp sentinel.conf /usr/local/redis/etc
2.修改sentinel.conf配置文件
sentinel monitor mymast 192.168.110.133 6379 1 #主节点 名称 IP 端口号 选举次数 sentinel auth-pass mymast 123
3. 修改心跳检测 30毫秒、做多多少合格节点
sentinel down-after-milliseconds mymaster 30 sentinel parallel-syncs mymaster 2
4. 启动哨兵模式,可以看到主Redis和从Redis
/usr/local/redis/bin/redis-server /usr/local/redis/etc/sentinel.conf --sentinel &
5.现在把主Redis服务器关掉
/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379 -a "123" shutdown
6.可以看到哨兵服务器控制台打印,从Redis现在晋升为master了:
7.在从Redis服务器,查看详情,可以看到现在变为master,并且有读写权限
info replication
8.启动主Redis,查看详情,可以看到主Redis变为了从Redis了:
info replication
如果还是操作失败,可以参考博文:《Sentinel 哨兵》
总结