单机模式是最简单的,redis启动后,业务调用即可。
优点:
缺点:
大多数企业都是基于Linux服务器来部署项目,而且Redis官方也没有提供Windows版本的安装包
https://redis.io/download/
http://www.redis.cn/
tar -xzf redis-6.2.6.tar.gz
make && make install
默认的安装路径是在 /usr/local/bin
目录redis-cli:是redis提供的命令行客户端
redis-server:是redis的服务端启动脚本
redis-sentinel:是redis的哨兵启动脚本
解压的目录下
备份一份redis.conf配置文件。并且进行修改配置redis-conf 文件# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes
# 密码,设置后访问Redis必须输入密码
requirepass 123321
# 监听的端口
port 6379
# 工作目录,默认是当前目录,也就是运行redis-server时的命令,日志、持久化等文件会保存在这个目录
dir .
# 数据库数量,设置为1,代表只使用1个库,默认有16个库,编号0~15
databases 1
# 设置redis能够使用的最大内存
maxmemory 512mb
# 日志文件,默认为空,不记录日志,可以指定日志文件名
logfile "redis.log"
解压的目录下
进行启动:redis-server redis.conf
ps -ef |grep redis
vi /etc/systemd/system/redis.service
[Unit]
Description=redis-server
After=network.target
[Service]
Type=forking
#ExecStart= 服务地址 和配置文件
ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
然后重载系统服务:systemctl daemon-reload
# 启动
systemctl start redis
# 停止
systemctl stop redis
# 重启
systemctl restart redis
# 查看状态
systemctl status redis
2.2.5.RELEASE
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-pool2artifactId>
dependency>
spring:
redis:
# Redis服务器地址
host: 192.168.0.121
# Redis服务器端口
port: 6379
# Redis服务器密码
password: root
# 选择哪个库,默认0库
database: 0
# 连接超时时间
timeout: 10000ms
lettuce:
pool:
max-active: 8 # 最大连接
max-idle: 8 #最大空闲连接
min-idle: 0 # 最小空闲连接
max-wait: 100 # 连接等待时间
@SpringBootTest
public class RedisDemoLettuce {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void testString(){
ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
ops.set("name", "zhangsan");
System.out.println(ops.get("name")); //zhangsan
}
@Test
public void testHash(){
HashOperations<String, String, String> opsHash = stringRedisTemplate.opsForHash();
opsHash.put("user:001","name","zhangsan");
opsHash.put("user:001","age","13");
String name = opsHash.get("user:001", "name");
String age = opsHash.get("user:001", "age");
System.out.println(name+age); //zhangsan 13
}
}
主从模式:将一台Redis服务器的数据,复制到其他的Redis服务器。数据的复制是单向的,只能由主节点到从节点。主节点负责读写、从节点只负责读操作。
为什么要开启读写分离?
优点:
缺点:
在一台虚拟机上进行测试,一共三个节点,一主两从。
mkdir tmp-redis 7001 7002 7003
# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes
# 密码,设置后访问Redis必须输入密码
requirepass 123321
# 监听的端口
port 6379
# 数据库数量,设置为1,代表只使用1个库,默认有16个库,编号0~15
databases 1
# 设置redis能够使用的最大内存
maxmemory 512mb
echo 7001 7002 7003 | xargs -t -n 1 cp redis-6.2.4/redis.conf
第一:修改每个实例的端口、工作目录
修改每个文件夹内的配置文件,将端口分别修改为7001、7002、7003,将rdb文件保存位置都修改为自己所在目录(在/tmp目录执行下列命令):
sed -i -e 's/6379/7001/g' -e 's/dir .\//dir \/tmp\/7001\//g' 7001/redis.conf
sed -i -e 's/6379/7002/g' -e 's/dir .\//dir \/tmp\/7002\//g' 7002/redis.conf
sed -i -e 's/6379/7003/g' -e 's/dir .\//dir \/tmp\/7003\//g' 7003/redis.conf
第二:修改每个实例的声明IP
虚拟机本身有多个IP,为了避免将来混乱,我们需要在redis.conf文件中指定每一个实例的绑定ip信息,格式如下:
# redis实例的声明 IP
replica-announce-ip 192.168.150.101
# 一键修改
printf '%s\n' 7001 7002 7003 | xargs -I{} -t sed -i '1a replica-announce-ip 192.168.75.111' {}/redis.conf
有临时和永久两种模式:
修改配置文件(永久生效)
slaveof
使用redis-cli客户端连接到redis服务,执行slaveof命令(重启后失效):
slaveof
注意:在5.0以后新增命令replicaof,与salveof效果一致。
# 第1个
redis-server 7001/redis.conf
# 第2个
redis-server 7002/redis.conf
# 第3个
redis-server 7003/redis.conf
全量同步:主从第一次连接时会执行全量同步,将master节点所有的数据拷贝给slave节点。
简述全量同步的流程?
增量同步的过程:
slave请求增量同步
master检查replid是否一致?
发送offset后的命令
执行命令
简述全量同步和增量同步区别?
什么时候执行全量同步?
什么时候执行增量同步?
哨兵Sentinel也是一个集群,哨兵节点是特殊的redis节点,不存储数据。
访问redis集群的数据都是通过哨兵集群的,哨兵监控整个redis集群。
Redis的Sentinel最小配置是 一主一从。
哨兵基于主从模式,主从有的优点,哨兵全部都有。
哨兵的作用:
哨兵的优点:
哨兵的缺点:
这里我们搭建一个三节点形成的Sentinel集群,来监管之前的Redis主从集群
节点 | IP | PORT |
---|---|---|
s1 | 192.168.150.101 | 27001 |
s2 | 192.168.150.101 | 27002 |
s3 | 192.168.150.101 | 27003 |
mkdir s1 s2 s3
port 27001
sentinel announce-ip 192.168.150.101
sentinel monitor mymaster 192.168.150.101 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/tmp/s1"
解读:
port 27001
:是当前sentinel实例的端口sentinel monitor mymaster 192.168.150.101 7001 2
:指定主节点信息
mymaster
:主节点名称,自定义,任意写192.168.150.101 7001
:主节点的ip和端口2
:选举master时的quorum值echo s2 s3 | xargs -t -n 1 cp s1/sentinel.conf
sed -i -e 's/27001/27002/g' -e 's/s1/s2/g' s2/sentinel.conf
sed -i -e 's/27001/27003/g' -e 's/s1/s3/g' s3/sentinel.conf
# 第1个
redis-sentinel s1/sentinel.conf
# 第2个
redis-sentinel s2/sentinel.conf
# 第3个
redis-sentinel s3/sentinel.conf
尝试让master节点7001宕机,查看sentinel日志:
可以看到哨兵日志:
默认30秒后,才会更新日志,才会认为下线了:
在Sentinel集群监管下的Redis主从集群,其节点会因为自动故障转移而发生变化,Redis的客户端必须感知这种变化,及时更新连接信息。Spring的RedisTemplate底层利用lettuce实现了节点的感知和自动切换。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
spring:
redis:
sentinel:
master: mymaster # 指定master名称
nodes: # 指定redis-sentinel集群信息
- 192.168.150.101:27001
- 192.168.150.101:27002
- 192.168.150.101:27003
@Bean
public LettuceClientConfigurationBuilderCustomizer configurationBuilderCustomizer(){
return configBuilder -> configBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}
这里的ReadFrom是配置Redis的读取策略,包括下面选择:
Redis3.0之前的集群模式,用ShardedJedis实现分片是客户端实现分片,客户端自己计算数据的key应该在哪个机器上存储,这个方法的好处是降低了服务器集群的复杂性,客户端自己分片,服务器节点之间是没有联系的,缺点也很明显,就是客户端要实时的知道当前所有节点的信息,因为当增加一个节点时得动态的重新分片啊。
Redis3.0之后的集群模式,用Cluster是用服务端节点实现的数据分片,即客户端随意与集群中的任何节点通信,节点负责计算某个key在哪个机器上,把计算结果反馈给客户端,客户端再去指定的节点存储查询数据,这是一个重定向的过程。
很容易添加或者删除节点,并且无论是添加删除或者修改某一个节点,都不会造成集群不可用的状态。使用哈希槽的好处就在于可以方便的添加 或 移除节点,当添加或移除节点时,只需要移动对应槽和数据移动到对应节点就行。
优点:
缺点:
集群配置:三个master节点、三个slave节点
IP | PORT | 角色 |
---|---|---|
192.168.150.101 | 7001 | master |
192.168.150.101 | 7002 | master |
192.168.150.101 | 7003 | master |
192.168.150.101 | 8001 | slave |
192.168.150.101 | 8002 | slave |
192.168.150.101 | 8003 | slave |
port 6379
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /tmp/6379/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /tmp/6379
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.150.101
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /tmp/6379/run.log
echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf
会将配置文件中的6379 分别改为 7001 7002 7003 8001 8002 8003
# 进入/tmp目录
cd /tmp
# 修改配置文件
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf
# 一键启动所有服务
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf
通过ps查看状态:
ps -ef | grep redis
如果要关闭所有进程,可以执行命令:
ps -ef | grep redis | awk '{print $2}' | xargs kill
或者(推荐这种方式):
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown
我们使用的是Redis6.2.4版本,集群管理以及集成到了redis-cli中,格式如下:
Redis5.0以后:
redis-cli --cluster create --cluster-replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003
命令说明:
redis-cli --cluster
或者./redis-trib.rb
:代表集群操作命令create
:代表是创建集群--replicas 1
或者--cluster-replicas 1
:指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1)
得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同masterredis-cli -p 7001 cluster nodes
redis-cli
加上-c
参数才可以:redis-cli -c -p 7001
# 连接
redis-cli -c -p 7001
# 存储数据
set num 123
# 读取数据
get num
# 再次存储
set a 1
Redis会把每一个master节点映射到0~16383共16384个插槽(hash slot)上,查看集群信息时就能看到:
数据key不是与节点绑定,而是与插槽绑定。redis会根据key的有效部分计算插槽值,分两种情况:
• key中包含"{}",且“{}”中至少包含1个字符,“{}”中的部分是有效部分
• key中不包含“{}”,整个key都是有效部分
例如:key是num,那么就根据num计算,如果是{itcast}num,则根据itcast计算。计算方式是利用CRC16算法得到一个hash值,然后对16384取余,得到的结果就是slot值。
RedisTemplate底层同样基于lettuce实现了分片集群的支持,而使用的步骤与哨兵模式基本一致:
spring:
redis:
cluster:
nodes: # 指定分片集群的每一个节点信息
- 192.168.150.101:7001
- 192.168.150.101:7002
- 192.168.150.101:7003
- 192.168.150.101:8001
- 192.168.150.101:8002
- 192.168.150.101:8003