赞
踩
数据库层面事务
在数据库层面,事务是指一组操作,这些操作要么全都被成功执行,要么全都不执行。
数据库事务的四大特性
Redis事务
Redis事务是一组命令的集合,一个事务中的所有命令都将被序列化,按照一次性、顺序性、排他性的执行一系列的命令。
MULTI
开始一个事务;EXEC
命令触发事务;
Multi、Exec、discard
事务从输入Multi
命令开始,输入的命令都会依次压入命令缓冲队列中,并不会执行,直到输入Exec
后,Redis会将之前的命令缓冲队列中的命令依次执行。组队过程中,可以通过discard
来放弃组队。
例子
127.0.0.1:6379> set t1 1 OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379(TX)> set id 12 QUEUED 127.0.0.1:6379(TX)> get id QUEUED 127.0.0.1:6379(TX)> incr t1 QUEUED 127.0.0.1:6379(TX)> incr t1 QUEUED 127.0.0.1:6379(TX)> get t1 QUEUED 127.0.0.1:6379(TX)> EXEC 1) OK 2) "12" 3) (integer) 2 4) (integer) 3 5) "3"
放弃事务
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set name z3
QUEUED
127.0.0.1:6379(TX)> set age 29
QUEUED
127.0.0.1:6379(TX)> incr t1
QUEUED
127.0.0.1:6379(TX)> DISCARD
OK
全体连坐
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set name z3
QUEUED
127.0.0.1:6379(TX)> get name
QUEUED
127.0.0.1:6379(TX)> incr t1
QUEUED
127.0.0.1:6379(TX)> get t1
QUEUED
127.0.0.1:6379(TX)> set email
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.
注意:
命令集合中含有错误的指令(注意是语法错误),均连坐,全部失败。
冤有头,债有主
127.0.0.1:6379> MULTI OK 127.0.0.1:6379(TX)> set age 11 QUEUED 127.0.0.1:6379(TX)> incr t1 QUEUED 127.0.0.1:6379(TX)> set email abc@163.com QUEUED 127.0.0.1:6379(TX)> incr email QUEUED 127.0.0.1:6379(TX)> get age QUEUED 127.0.0.1:6379(TX)> exec 1) OK 2) (integer) 5 3) OK 4) (error) ERR value is not an integer or out of range 5) "11"
注意:
运行时错误,即非语法错误,正确命令都会执行,错误命令返回错误。
概述
在现有企业中80%公司大部分使用的是Redis单机服务,在实际的场景当中单一节点的Redis容易面临风险。
面临问题:
- 机器故障。我们部署到一台 Redis 服务器,当发生机器故障时,需要迁移到另外一台服务器并且要保证数据是同步的。
- 容量瓶颈。当我们有需求需要扩容 Redis 内存时,从 16G 的内存升到 64G,单机肯定是满足不了。当然,你可以重新买个 128G 的新机器。
解决办法
要实现分布式数据库的更大的存储容量和承受高并发访问量,我们会将原来集中式数据库的数据分别存储到其他多个网络节点上。
注意:
Redis 为了解决这个单一节点的问题,也会把数据复制多个副本部署到其他节点上进行复制,实现 Redis的高可用,实现对数据的冗余备份从而保证数据和服务的高可用。
什么是主从复制
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。
主从复制的作用
编写配置文件
新建redis6379.conf
include /usr/local/redis-7.2.4/redis.config
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb
新建redis6380.conf
include /usr/local/redis-7.2.4/redis.config
pidfile /var/run/redis_6380.pid
port 6380
dbfilename dump6380.rdb
新建redis6381.conf
include /usr/local/redis-7.2.4/redis.config
pidfile /var/run/redis_6381.pid
port 6381
dbfilename dump6381.rdb
启动三台redis服务器
./redis-server ../redis6379.conf
./redis-server ../redis6380.conf
./redis-server ../redis6381.conf
查看系统进程
[root@localhost src]# ps -ef |grep redis
root 40737 1 0 22:05 ? 00:00:00 ./redis-server *:6379
root 40743 1 0 22:05 ? 00:00:00 ./redis-server *:6380
root 40750 1 0 22:05 ? 00:00:00 ./redis-server *:6381
root 40758 40631 0 22:05 pts/0 00:00:00 grep --color=auto redis
查看三台主机运行情况
#打印主从复制的相关信息
./redis-cli -p 6379
./redis-cli -p 6380
./redis-cli -p 6381
127.0.0.1:6379> info replication
127.0.0.1:6380> info replication
127.0.0.1:6381> info replication
配从库不配主库
语法格式:
slaveof <ip> <port>
示例:
在6380和6381上执行。
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
OK
在主机上写,在从机上可以读取数据
set k1 v1
主从复制可以分为3个阶段
复制过程大致分为6个过程
info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
4、发送ping命令
连接建立成功后从节点发送 ping 请求进行首次通信。
作用:
- 检测主从之间网络套接字是否可用。
- 检测主节点当前是否可以接受命令
权限验证。
如果主节点设置了 requirepass 参数,则需要密码验证,从节点必须配置 masterauth 参数保证与主节点相同的密码才能通过验证;如果验证失败复制将终止,从节点重新发起复制流程。
同步数据集。
主从复制连接正常通信后,对于首次建立复制的场景,主节点会把持有的数据全部发送给从节点,这部分操作是耗时最长的步骤。
主从同步策略
主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
例如
保存一个缓存
set name jjy
记录命令为
$3 \r \n
set \r \n
$4 \r \n
name \r \n
$5 \r \n
jjy \r \n
偏移量 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 |
---|---|---|---|---|---|---|---|---|---|
字节值 | $ | 3 | \r | \n | $ | 4 | n | a | m |
7.命令持续复制。
当主节点把当前的数据同步给从节点后,便完成了复制的建立流程。接下来主节点会持续地把写命令发送给从节点,保证主从数据一致性。
Redis主从复制缺点
当主机 Master 宕机以后,我们需要人工解决切换。
暴漏问题:
一旦主节点宕机,写服务无法使用,就需要手动去切换,重新选取主节点,手动设置主从关系。
主从切换技术
当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。
哨兵概述
哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。
哨兵作用
新建sentinel-26379.conf文件
#端口
port 26379
#守护进程运行
daemonize yes
#日志文件
logfile "26379.log"
sentinel monitor mymaster localhost 6379 2
参数:
sentinel monitor mymaster 192.168.92.128 6379 2 配置的含义是:该哨兵节点监控192.168.92.128:6379这个主节点,该主节点的名称是mymaster,最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移。
新建sentinel-26380.conf文件
#端口
port 26380
#守护进程运行
daemonize yes
#日志文件
logfile "26380.log"
sentinel monitor mymaster localhost 6379 2
新建sentinel-26381.conf文件
#端口
port 26381
#守护进程运行
daemonize yes
#日志文件
logfile "26381.log"
sentinel monitor mymaster localhost 6379 2
哨兵节点的启动
redis-sentinel sentinel-26379.conf
查看哨兵节点状态
[root@localhost src]# ./redis-cli -p 26379
127.0.0.1:26379>
127.0.0.1:26379>
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.66.100:6379,slaves=2,sentinels=3
监控阶段
注意:
- sentinel(哨兵1)----->向master(主)和slave(从)发起info,拿到全信息。
- sentinel(哨兵2)----->向master(主)发起info,就知道已经存在的sentinel(哨兵1)的信息,并且连接slave(从)。
- sentinel(哨兵2)----->向sentinel(哨兵1)发起subscribe(订阅)。
通知阶段
sentinel不断的向master和slave发起通知,收集信息。
故障转移阶段
通知阶段sentinel发送的通知没得到master的回应,就会把master标记为SRI_S_DOWN,并且把master的状态发给各个sentinel,其他sentinel听到master挂了,说我不信,我也去看看,并把结果共享给各个sentinel,当有一半的sentinel都认为master挂了的时候,就会把master标记为SRI_0_DOWN。
问题来了:
这时就要把master给换掉了,到底谁当Master呢。
投票方式
方式:
自己最先接到哪个sentinel的竞选通知就会把票投给它。
剔除一些情况:
概述
演示当主节点发生故障时,哨兵的监控和自动故障转移功能。
演示故障转移
使用kill命令杀掉主节点
ps aux |grep redis
kill -9 pid
查看哨兵节点信息
如果此时立即在哨兵节点中使用info Sentinel命令查看。
[root@localhost src]# ./redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1:6381,slaves=5,sentinels=3
注意:
会发现主节点还没有切换过来,因为哨兵发现主节点故障并转移,需要一段时间。
重启6379节点
[root@localhost src]# ./redis-cli info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6381
master_link_status:down
配置文件都会被改写
故障转移阶段,哨兵和主从节点的配置文件都会被改写
include /usr/local/redis/redis.conf
pidfile "/var/run/redis_6379.pid"
port 6379
dbfilename "dump6379.rdb"
# Generated by CONFIG REWRITE
daemonize yes
protected-mode no
appendonly yes
slowlog-max-len 1200
slowlog-log-slower-than 1000
save 5 1
user default on nopass ~* &* +@all
dir "/usr/local/redis"
replicaof 127.0.0.1 6381
结论
Redis有三种集群模式
哨兵模式的缺点
缺点:
Cluster模式概述
Redis集群是一个由多个主从节点群组成的分布式服务集群,它具有复制、高可用和分片特性。
Redis集群的优点
Redis的集群搭建最少需要3个master节点,我们这里搭建3个master,每个下面挂一个slave节点,总共6个Redis节点;
集群搭建
创建6个不同的redis节点,端口号分别为6379、6380、6381、6382、6383、6384。
注意:拷贝前必须删除dump.rdb和appendonly.aof文件
1、新建配置文件
创建redis6379.config,redis6380.config,redis6381.config,redis6382.config,redis6383.config,redis6384.config文件修改配置文件中端口号使其和文件端口号对应。
daemonize yes
dir /usr/local/redis-7.2.4/redis-cluster/6382/
bind 192.168.47.100
port 6382
dbfilename dump6382.rdb
cluster-enabled yes
cluster-config-file nodes-6382.conf
cluster-node-timeout 5000
appendonly yes
protected-mode no
参数:
- cluster-config-file : 集群持久化配置文件,内容包含其它节点的状态,持久化变量等,会自动生成在上面配置的dir目录下。每个节点在运行过程中,会维护一份集群配置文件;每当集群信息发生变化时(如增减节点),集群内所有节点会将最新信息更新到该配置文件;当节点重启后,会重新读取该配置文件,获取集群信息,可以方便的重新加入到集群中。集群配置文件由Redis维护,不需要人工修改。
- clouster-enabled: 开启集群
创建文件夹
mkdir -p /usr/local/redis-7.2.4/redis-cluster/6379/
mkdir -p /usr/local/redis-7.2.4/redis-cluster/6380/
mkdir -p /usr/local/redis-7.2.4/redis-cluster/6381/
mkdir -p /usr/local/redis-7.2.4/redis-cluster/6382/
mkdir -p /usr/local/redis-7.2.4/redis-cluster/6383/
mkdir -p /usr/local/redis-7.2.4/redis-cluster/6384/
启动六个节点
[root@bogon src]# ./redis-server ../redis6379.config
[root@bogon src]# ./redis-server ../redis6380.config
[root@bogon src]# ./redis-server ../redis6381.config
[root@bogon src]# ./redis-server ../redis6382.config
[root@bogon src]# ./redis-server ../redis6383.config
[root@bogon src]# ./redis-server ../redis6384.config
查看各个节点是否启动成功
[root@bogon src]# ps -ef | grep redis
root 3889 1 0 09:56 ? 00:00:03 ./redis-server 0.0.0.0:6379 [cluster]
root 3895 1 0 09:56 ? 00:00:03 ./redis-server 0.0.0.0:6380 [cluster]
root 3901 1 0 09:57 ? 00:00:03 ./redis-server 0.0.0.0:6381 [cluster]
root 3907 1 0 09:57 ? 00:00:02 ./redis-server *:6382 [cluster]
root 3913 1 0 09:57 ? 00:00:02 ./redis-server 0.0.0.0:6383 [cluster]
root 3919 1 0 09:57 ? 00:00:02 ./redis-server 0.0.0.0:6384 [cluster]
root 4247 2418 0 10:22 pts/0 00:00:00 grep --color=auto redis
配置集群
命令格式: --cluster-replicas 1 表示为每个master创建一个slave节点
注意:这里的IP为每个节点所在机器的真实IP
[root@localhost src]# ./redis-cli --cluster create 192.168.47.100:6379 192.168.47.100:6380 192.168.47.100:6381 192.168.47.100:6382 192.168.47.100:6383 192.168.47.100:6384 --cluster-replicas 1
验证集群
连接任意一个客户端
./redis-cli -h 192.168.47.100 -p 6379 -c
参数:
‐h : host地址
-p : 端口号
‐c : 表示集群模式
数据写测试
[root@bogon src]# ./redis-cli -p 6379 -c 127.0.0.1:6379> set name zhangsan -> Redirected to slot [5798] located at 192.168.47.100:6380 OK 192.168.47.100:6380> get name "zhangsan" 192.168.47.100:6380> [root@bogon src]# ./redis-cli -p 6383 -c 127.0.0.1:6383> get name -> Redirected to slot [5798] located at 192.168.47.100:6380 "zhangsan" 192.168.47.100:6380> [root@bogon src]# ./redis-cli -p 6383 -c 127.0.0.1:6383> readonly OK 127.0.0.1:6383> get name "zhangsan" 127.0.0.1:6383>
Redis Cluster将所有数据划分为16384个slots(槽位),每个节点负责其中一部分槽位。槽位的信息存储于每个节点中。只有master节点会被分配槽位,slave节点不会分配槽位。
槽位定位算法: k1 = 127001
Cluster 默认会对 key 值使用 crc16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。
HASH_SLOT = CRC16(key) % 16384
故障恢复
查看节点
192.168.66.103:8001> cluster nodes
杀死Master节点
lsof -i:8001
kill -9 pid
观察节点信息
修改配置文件
spring.data.redis.cluster.nodes=192.168.47.100:6381,192.168.47.100:6383,192.168.47.100:6380
注意
1、Redis集群需要至少3个节点才能保证高可用性。
2、应该尽量避免在Redis集群的运行过程中添加或删除节点,因为这可能导致数据迁移,进而影响Redis集群的整体性能。
Java编写的代码
@SpringBootTest
public class CluseterTest {
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Test
void string() {
// 保存字符串
redisTemplate.opsForValue().set("itbaizhan","itbaizhan123");
System.out.println(redisTemplate.opsForValue().get("itbaizhan"));
}
}
如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。