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

  • 相关阅读:
    IDEA效率快捷键
    常用文件/文件夹操作
    git log状态下退出方法
    ImageList 构造函数
    ImageList 控件
    【转】图像分割代码合集
    【转】图像分割论文及代码资源汇总
    SLIC 算法
    c/c++内存分配详解
    c++内存分配
  • 原文地址:https://www.cnblogs.com/frankruby/p/14818197.html
Copyright © 2011-2022 走看看