二、redis简介在我们日常的Java Web开发中,无不都是使用数据库来进行数据的存储,由于一般的系统任务中通常不会存在高并发的情况,所以这样看起来并没有什么问题,可是一旦涉及大数据量的需求,比如一些商品抢购的情景,或者是主页访问量瞬间较大的时候,单一使用数据库来保存数据的系统会因为面向磁盘,磁盘读/写速度比较慢的问题而存在严重的性能弊端,一瞬间成千上万的请求到来,需要系统在极短的时间内完成成千上万次的读/写操作,这个时候往往不是数据库能够承受的,极其容易造成数据库系统瘫痪,最终导致服务宕机的严重生产问题。所以在当今云计算、大数据盛行的时代,对性能有了更多的需求,主要体现在以下四个方面:
- 低延迟的读写速度:应用快速地反应能极大地提升用户的满意度
- 支撑海量的数据和流量:对于搜索这样大型应用而言,需要利用PB级别的数据和能应对百万级的流量
- 大规模集群的管理:系统管理员希望分布式应用能更简单的部署和管理
- 庞大运营成本的考量:IT部门希望在硬件成本、软件成本和人力成本能够有大幅度地降低
为了克服上述的问题,Java Web项目通常会引入NoSQL技术,这是一种基于内存的数据库,并且提供一定的持久化功能。
Redis是现在最受欢迎的NoSQL数据库之一,Redis是一个使用ANSI C编写的开源、包含多种数据结构、支持网络、基于内存、可选持久性的键值对存储数据库,其具备如下特性:
- 基于内存运行,性能高效
- 支持分布式,理论上可以无限扩展
- key-value存储系统
- 开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
Redis 在 Java Web 主要有两个应用场景:
- 存储 缓存 用的数据;
- 需要高速读/写的场合使用它快速读/写;
三、环境部署缓存
- 在日常对数据库的访问中,读操作的次数远超写操作,比例大概在 1:9 到 3:7,所以需要读的可能性是比写的可能大得多的。当我们使用SQL语句去数据库进行读写操作时,数据库就会去磁盘把对应的数据索引取回来,这是一个相对较慢的过程。
- 如果我们把数据放在 Redis 中,也就是直接放在内存之中,让服务端直接去读取内存中的数据,那么这样速度明显就会快上不少,并且会极大减小数据库的压力,但是使用内存进行数据存储开销也是比较大的,限于成本的原因,一般我们只是使用 Redis 存储一些常用和主要的数据,比如用户登录的信息等。
redis下载:Download | Redis
可以查看 README.md 来获取编译的帮助,我们先进行编译 make USE_SYSTEMD=yes(在编译时可能会遇到依赖,根据提示解决即可):
make成功:
make install:
可以使用源码包里的脚本来创建实例及其配置文件:
进入脚本文件修改,将此处的判断注释掉:
成功建立redis实例。此时要是再建立一个redis实例,只需更改端口号即可:
当我们想删除这个实例时:
常用命令 含义
config get * 查看配置
select 1 选择数据库
flushdb 清空当前数据库
flushall 清空所有数据库
move key 1 移动key
del key 删除
rename oldkey newkey 改名
expire key 10 设置过期时间
persist key 设置持久化
persist key 查询
persist key 判断是否存在
默认情况下redis只能监听本机的回环接口,外部无法访问,若是想外部访问,就要进行以下设置(将回环接口改为本机的所有接口):
进入redis实例可以查看它的信息:
可以看到此时的状态是master没有slave:
此时我们来添加slave:
将刚刚编译好的包传给server2:
在server2上make install 安装二进制程序 :
创建实例:
更改监听端口:
此时进到server2的redis实例中发现也是master:
此时我们更改配置文件使server2变成slave(注:redis变成slave后就是只读的,只有master可写):
再用redis-cli 进入实例查看此时server2的redis6379已经成为了slave:
在server1已经识别到了slave:
测试:
我们在server1定义一个key:
在server2查询:
此时我们的redis主从已经配置完成。redis作为slave接入master时,会放弃本机所有的数据。
redis常用指令: config get * //查看配置 select 1 //选择数据库,总共16个,默认为0 flushdb //清空当前数据库 flushall //清空所有数据库 move key 1 //移动key del key //删除 rename oldkey newkey //改名 expire key 10 //设置过期时间 persist key //设置持久化,默认单位为s keys user* //查询 exists key //判断是否存在
redis内存临时文件:
四、redis的主从切换(高可用):高可用主从切换原理:
哨兵模式:当slave发现自己的master变为FAIL状态时,便尝试进行Failover,以期成为新的master。由于挂掉的master可能会有多个slave,从而存在多个slave竞争成为master节点的过程,其过程如下:
1、slave发现自己的master变为FAIL
2、将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST信息
3、其他节点收到改信息,只有master响应,判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个epoch只发送一次ack
4、尝试failover的slave收集FAILOVER_AUTH_ACK
5、其他slave投票超过半数后变成新master
6、广播通知其他集群节点此时的master。
介绍主从模式下,当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这种方式并不推荐,实际生产中,我们优先考虑哨兵模式。这种模式下,master宕机,哨兵会自动选举master并将其他的slave指向新的master。
监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器。
哨兵可以有多个,一般为了便于决策选举,使用奇数个哨兵。哨兵可以和redis机器部署在一起,也可以部署在其他的机器上。多个哨兵构成一个哨兵集群,哨兵直接也会相互通信,检查哨兵是否正常运行,同时发现master宕机哨兵之间会进行决策选举新的master
哨兵模式的作用通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器;
当哨兵监测到master宕机,会自动将slave切换到master,然后通过发布订阅模式通过其他的从服务器,修改配置文件,让它们切换主机;
然而一个哨兵进程对Redis服务器进行监控,也可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。
min-slaves-to-write=2 :此参数保证在master至少有两个slave可以用,当不满足此条件时,master就不允许客户端再写入数据,以防止通信出故障时客户端写入的数据丢失。
热生效:
永久生效:
再将server3配置为slave。
接下来做redis的高可用:
我们设置哨兵在前台运行(注:要在启动之前把配置文件复制到slave上):
在server2、3上直接启动,在server1上显示2、3已经添加成功:
再开启一个shell连接server1,再看sentinel.conf 已经变更了:
我们关闭server1上的redis:
在server2上可以看到已经重新选举server2为master:
我们用redis远程连接server3,可以看到master为server2:
我们再把server1的redis启动起来:
可以看到server1自动被添加到slave中:



