【Redis 事务&主从复制 03】

一、Redis的事务

1、是什么?

一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不许加塞

2、目的

一个队列中,一次性,顺序行,排他性的执行一系列命令

3、如何操作

1)常用命令

discard 取消事务,放弃执行事务快内的所有命令

exec 执行所有事务块内的命令

multi 标记一个事务块的开始

unwatch 取消watch命令对所有key的监视

watch key[key...] 监视一个(或多个)key,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断

2)正常执行

 3)取消事务

 4)只要有一个命令错误,其他命令执行失败

 5)命令语法成功,逻辑错误,执行事务只会让错误的命令失败,其他命令成功

 4)5)之间的区别

单独命令时报错,这样整个事务的执行都会失败
单独的每一条命令是正确的,执行事务的时候只会让存在问题的命令失败,其他命令仍然会成功

6)watch监控  针对多个用户对key的修改,watch用来监控key修改,unwatch取消key的监控

4、阶段

|-- 开启:以MULTI开始一个事务

|-- 入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面

|-- 执行: 由exec命令触发事务

5、特性

|-- 单独的隔离操作:事务中所有命令都会序列化,按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断

|-- 没有隔离级别的概念:队列中的命令没有提交之前不会实际的被执行,因为事务提交前任何指令都不会被实际执行

|-- 不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚

二、Redis的发布订阅

进程间的一种消息通信模式:发送者pub发送消息,订阅者sub接受消息

三、Redis的主从复制,读写分离

1、是什么?

长说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slave机制,Master以写为主,Slave以读为主

2、能干什么?

读写分离

容灾恢复

3、如何操作

1)配从(库)不配主(库)

2)命令:从库配置:slaveof 主库IP 主库端口

  |-- 每次与master断开后,都需要重新连接,除非你配置进redis.conf文件

  |-- info replication  查看库信息(包含是master还是slave,主备状态等)

4、常用场景

场景1:一主二备

#案例

1>  拷贝多个redis.conf文件,分别为redis-6379.conf,redis-6380.conf,redis-6381.conf

2> 分别修改上面三个conf文件

daemonize yes

port 6379  (6380 /6381)

pidfile /var/run/redis6379.pid (redis6380.pid/redis6381.pid)

logfile "redis6379.log"  (redis6380.log/redis6381.log)

dbfilename dump6379.rdb  (dump6380.rdb/dump6381.rdb)

3> 分别启动三台redis

redis-server 127.0.0.1:6379
redis-cli -p 6379

redis-server 127.0.0.1:6380
redis-cli -p 6380

redis-server 127.0.0.1:6381
redis-cli -p 6381

4> 主机6379设置值,6380,6381设置备机,验证数据是否备份

//主机传值
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK

//设置6380 6381为备机
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6380> keys *
1) "k1"
2) "k3"
3) "k2"

127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6381> keys *
1) "k3"
2) "k1"
3) "k2"

//用keys * 查看结果的值,数据已经备份完成

5> info replication 查看各个服务器状态

//6379主机信息
127.0.0.1:6379> info replication
# Replication
role:master  //角色 master
connected_slaves:2  //连接2个slave
slave0:ip=127.0.0.1,port=6380,state=online,offset=13248,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=13248,lag=1
master_replid:668727d2394aa22a3b97b419ccc0f36c4a0b93e2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:13248
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:13248

//6380备机信息
127.0.0.1:6380> info replication
# Replication
role:slave  //角色 slave
master_host:127.0.0.1
master_port:6379
master_link_status:up  //连接状态 up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_repl_offset:13262
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:668727d2394aa22a3b97b419ccc0f36c4a0b93e2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:13262
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:12843
repl_backlog_histlen:420

//6381备机信息
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:13276
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:668727d2394aa22a3b97b419ccc0f36c4a0b93e2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:13276
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:12871
repl_backlog_histlen:406

6> 常见问题

|-- 主机挂掉备机数据是否丢失  -->不丢失,并且角色仍然是slave

127.0.0.1:6379> shutdown
not connected> exit

127.0.0.1:6380> keys *
1) "k1"
2) "k3"
3) "k2"

127.0.0.1:6381> keys *
1) "k3"
2) "k1"
3) "k2"

|-- 主机重启,备机会自动连接主机并同步数据

|-- 备机挂掉,需要重新连接主机

SLAVEOF 127.0.0.1 6379 

|-- 主机可读可写,从机只能读不能写

127.0.0.1:6379> set k9 v9
OK

127.0.0.1:6380> set k9 v99
(error) READONLY You can't write against a read only replica. 

127.0.0.1:6381> set k9 v999
(error) READONLY You can't write against a read only replica. 

//从上面结果可以看出,从机只能读不能写

场景2:备机传递

上一个slave可以是下一个slave的master,slave同样可以接受其他slaves的连接和同步请求,那么该slave就被当做链条中下一个master,可以有效的减轻master的写压力

通俗一点讲,79是主机,80既可以作为81的主机又可以作为79的备机

特点:

中途变更转向:会清除之前的数据,重新建立拷贝最新的

设置方式:slaveof 新主库IP 新主库端口

#案例

1> 设置81的主机为80

127.0.0.1:6381> SLAVEOF 127.0.0.1 6380

2> 79新建数据,80,81仍然可以数据传递

127.0.0.1:6379> set k7 v7
OK

127.0.0.1:6380> get k7
"v7"

127.0.0.1:6381> get k7
"v7"

//80,81仍然可以数据传递,获取79set的值,这叫薪火相传

3> info replication查看79,80,81的身份信息

//79
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1 //只连接一个slave
slave0:ip=127.0.0.1,port=6380,state=online,offset=2725,lag=1 //并且是80
master_replid:9a5a6b8f556368a0683a2c26247af61b9f98f333
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2725
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2725

//80
# Replication
role:slave  //角色仍然是slave
master_host:127.0.0.1
master_port:6379  //80的master是79
master_link_status:up
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_repl_offset:2725
slave_priority:100
slave_read_only:1  //80虽然是81的主机,但是仍然只有读的权限,没有写的权限
connected_slaves:1 //80也有一个连接他的slave 并且是81
slave0:ip=127.0.0.1,port=6381,state=online,offset=2725,lag=0
master_replid:9a5a6b8f556368a0683a2c26247af61b9f98f333
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2725
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:895
repl_backlog_histlen:1831

//81
127.0.0.1:6381> info replication
# Replication
role:slave  //角色slave
master_host:127.0.0.1
master_port:6380  //master是80

场景3:反客为主(备机升级主机)

主机挂掉,使当前数据库停止与其他数据库的同步,转成主数据库

#案例

1> 79主机,80,81都是79的slave

2> 79挂掉,设置80位主机,81位为80的备机

127.0.0.1:6380> SLAVEOF no one  //设置80为主机
OK
127.0.0.1:6380> set k8 v8
OK

127.0.0.1:6381> SLAVEOF 127.0.0.1 6380  //设置81为备机
OK
127.0.0.1:6381> get k8
"v8"

5、复制原理

1)slave启动成功连接到master后会发送一个sync命令

2)master接到命令后启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步

3)全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中

4)增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步

5)但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

6、哨兵模式

反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库

步骤

1)79为主,80,81是79的两个备

2)自定义的/back_redis_conf目录下新建sentinel.conf文件,名字绝不能错

3)配置sentinel.conf,内容为: sentinel monitor 被监控数据库名字(自己起名字) 127.0.0.1 6379 1  上面最后一个数字1,表示主机挂掉后salve投票看让谁接替成为主机,得票数多少后成为主机

[root@bogon bak_redis_conf]# touch sentinel.conf
[root@bogon bak_redis_conf]# vim sentinel.conf 
sentinel monitor host6379 127.0.0.1 6379 1

4)启动哨兵

redis-sentinel /opt/bak_redis_conf/sentinel.conf 

5)79挂掉,80,81会被投票新选master,谁的票多谁就是master

 

 6)验证80 数据是否传到81

127.0.0.1:6380> set k8 v8
OK
127.0.0.1:6381> get k8
"v8"

7)79重新启动,会被哨兵检测到重新设置成80的备机

127.0.0.1:6379> get k8
"v8"   
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:49336
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:5f5325be102aa5a98d8f9b9ba69a30a8fa52401c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:49336
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:48502
repl_backlog_histlen:835

原理:原先的主机挂掉以后,sentinel会检测到并根据投票选出新的master,原先的主机重新启动以后,也会被设置成新主机的备机

一组sentinel能同时监控多个master

7、复制的缺点:

由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。

原文地址:https://www.cnblogs.com/frankruby/p/14818197.html