• 【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机器数量的增加也会使这个问题更加严重。

  • 相关阅读:
    Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源
    Spring Boot 如何给微信公众号返回消息
    Spring Boot2 系列教程(十九)Spring Boot 整合 JdbcTemplate
    Spring Boot2 系列教程(十八)Spring Boot 中自定义 SpringMVC 配置
    Spring Boot 开发微信公众号后台
    Spring Boot2 系列教程(十七)SpringBoot 整合 Swagger2
    Spring Boot2 系列教程(十六)定时任务的两种实现方式
    Spring Boot2 系列教程(十五)定义系统启动任务的两种方式
    Spring Boot2 系列教程(十四)CORS 解决跨域问题
    JavaScript二维数组
  • 原文地址:https://www.cnblogs.com/frankruby/p/14818197.html
Copyright © 2020-2023  润新知