• 主从复制和读写分离


    MySQL 主从复制和读写分离:

    主从复制:主MySQL上的数据,新增,修改库,表,表里的数据,都会同步到从MySQL上。

    MySQL的主从复制的模式:(面试题)

    1,异步复制:(MySQL的默认复制就是异步复制,最常用。只要执行完之后,客户端提交事务,主MySQL会立即把结果返回给从服务器,主服务器并不关心从服务器是否已经接受,并且处理。)

    问题:主一旦崩溃,主MySQL的事务可能没有传到从MySQL,这个时候强行的把从提升为主,可能到新的主服务器数据不完整。(很少见。)

    2,全同步复制,主库执行完成一个事务,所有的从库都执行了该事务之后才会返回客户端。

    因为需要等待所有从库全部执行完成,性能必然下降。(对数据一致性,和数据完整性要求很好的场景。)

    3,半同步复制:介于异步和全同步复制之间。主库执行完一个客户端提交的事务之后,至少等待一个从库接受并处理完成之后才会返回给客户端。半同步在一定程度上提高了数据的安全性。也会有一定延迟。

    这个延迟一般是一个tcp/ip的时间:从发送到接受的时间,单位是毫秒ms

    时间<1ms: round-trip time RTT

    架构:主从复制和读写分离:

    mysql1 主

    mysql2 从

    mysql3 从

    test1 读写分离的服务器

    test2 客户端

    实验:

    主从复制

    主从服务器之间的时间也要同步:

    安装 ntp工具

    yum -y install ntp

    改ntp配置文件:

    数字越小,时间的精确度越高,设置fudge 8 时间层级是8 最高到15。

    从本地获取时间源,不从网络获取

    从服务器执行同步命令

    生成中会加一个定时任务

    每30分钟同步一次

    查看时间:

    改主配置文件:

    log-bin=master-bin #添加,主服务器开启二进制日志

    binlog_format = MIXED

    log-slave-updates=true

    #添加,允许slave从master复制数据时可以写入到自己的二进制日志

    进入服务器,新建一个用户,并授权:

    GRANT REPLICATION SLAVE ON . TO 'myslave'@'192.168.176.%' IDENTIFIED BY '123456';

    FLUSH PRIVILEGES;

    show master status;

    靠位置点进行同步:

    修改从数据库配置文件

    每个id不能一样:

    server-id = 2

    relay-log=relay-log-bin

    relay-log-index=slave-relay-bin.index

    relay_log_recovery = 1

    relay_log_recovery=1

    默认是0,1开启中继日志的复制。从服务器出现异常或者崩溃时,从服务器会从主服务器的二进制

    server-id = 3

    relay-log=relay-log-bin

    relay-log-index=slave-relay-bin.index

    relay_log_recovery = 1

    重启数据库

    从服务器分别进入数据库:

    mysql -u root -p123456;

    和主进行同步:

    CHANGE master to master_host='192.168.176.30',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604;

    启动同步:

    start slave;

    查看:

    show slave status\G;

    Slave_IO_Running: Yes #负责与主机的io通信

    Slave_SQL_Running: Yes #负责自己的slave mysql进程

    在主数据库创建库,表

    从库也会跟着改变

    面试题:如果slave io running no

    1,网络问题

    2,my.cnf 配置文件写错了

    3,

    4,防火墙和安全机制。

    主从复制是单向的,只能从主复制到从服务器。

    面试题:主从复制的延迟问题:

    1,网络延迟

    2,主从硬件设备(CPU主频,内存IO,硬件IO)。

    3,同步复制而不是异步复制。

    解决方案:

    1,硬件方面,主库一般来说不需要动的太多,从库硬件配置要更好。提升随机写的性能。硬盘可以换成固态的,升级cpu的核数,扩容内存。尽量使用物理机(不要用云服务器。)4核8G,硬盘。

    2,网络层面,主从服务器配置在一个局域网内,尽量避免跨网段和跨机房。

    3,架构方面:读写分离,把写入控制在主库,从库负责读,降低从库的压力

    4,配置方面 mysql配置。从配置文件的角度实现性能最大化

    追求安全性的配置:

    innodb_flush_log_at_trx_commit=1

    每次事务提交时都会刷新事务日志。已确保持久性,最高级别的数据安全性,但是会响应性能,默认就是1

    0就是事务提交时不会立刻刷新,而是每秒刷新一次。可以提高性能,但是发生故障会导致数据丢失。

    2 事务提交时,事务日志不会写入硬盘而是保持在系统缓存,不会进行刷新。一定的安全性和性能。内存要求比较高。

    sync_binlog=1

    1,也是默认值,每次提交事务之后,直接把二进制日志刷新,以确保日志的持久性。占用比较高的性能。但是安全性高。

    0,二进制日志写入到缓存,也不会刷新日志。故障发生也会丢失数据,内存的要求也提高了

    3,每3个事务执行一次刷新磁盘。提高性能,但是一旦崩溃,数据会大量丢失。

    追求性能化:

    sync_binlog=0

    innodb_flush_log_at_trx_commit=2

    logs-slave-updates=0

    从库的更新不会写入二进制日志(不建议)

    innodb_buffer_pool_size 300M 500G

    innodb存储引擎的缓冲池大小,设置的s值越高,可以提高innodb的性能。

    更多的数据和索引都可以缓存在内存中。减少磁盘的访问次数。对系统内存要求比较高。

    主从复制的一个工作过程:

    1,主节点是数据记录发生变化都会记录在二进制日志。

    2,slave节点会一定时间内对主库的二进制文件进行探测,看其是否发生变化,如果有变化,从库会开启一个I/O线程,请求主库的二进制事件。

    3,主库会给每一个I/O的线程启动一个dump。用于发送二进制事件给从库,从库通过I/O线程获取更新,slave_sql负责将更新写入到从库本地。实现主从一致。

    主从复制的问题:

    1,只能在主库上发生变化,任何同步到从。

    2,复制过程是串行化过程,在从库上复制是串行的,主库的并行更新不能在库上并行操作。

    3,主从复制的设计目的就是为在主库上写,在从库上查看。读写分离,实现高可用

    mysql主从复制

    若主从版本不一致,从的版本一定要高于主,保证可以向下兼容

    因为若主的版本更新,低版本的从无法兼容的

    读写分离:

    要实现读写分离,必须要实现主从复制。

    读写分离:所有的写入操作在主库,从库只负责读。(select)。如果有更新,是从主库复制到从库。

    为什么要有读写分离:

    1,数据库在写入数据时,比较耗时(mysql写一万条数据 3分钟)

    2,数据库在读的时候,速度很快(读一万,5秒)

    读写一旦分离,数据库的写入和读取是分开的,哪怕写入的数据量比较大,但是不影响查询的效率。

    在什么场景下需要读写分离:

    只有在某些程序在使用数据库过程中,更新少,但是查询比较多,这种情况可用考虑读写分离。

    读和查的需求差不多,也可以考虑读写分离。

    生产库一般都会做读写分离

    测试库一般不管。

    在工作中,数据库的读写不会在同一个库中完成。即不安全,也不能满足高可用,也不能实现高并发。工作中读会做读写分离。

    mysql读写分离的原理:

    1,根据脚本实现。在代码中实现路由分类。select insert 进行路由分类。这种方式是最多的。

    性能好,在代码中可用实现,不需要额外的硬件设备

    缺点:开发实现的,跟我们无关。如果大型的复制的应用,设计改动的代码非常多。

    2,基于中间代理层实现:

    mysql-proxy自带的开源项目,基于自带的lua脚本。这些lua脚本不是现成的,,要自己写,不熟悉他的内置变量写不出来的 atlas 360内部做自己代理工具。每天的读写请求承载量可用到几十亿条。支持事务,支持存储过程。

    3,Amoeba 陈思儒,之前在阿里就职。是由java开发的一个开源团建。不支持事务,也不支持存储过程。但是Amoeba还是用的最多的功能比较强大的软件。

    实验:

    mysql1 主

    mysql2 从

    mysql3 从

    test1 读写分离的服务器 Amooeba

    test2 客户端

    修改java环境

    查看java环境:java -version

    基于 jdk1.5开发的,官方推荐的

    更换java环境

    cd /opt/

    cp jdk-6u14-linux-x64.bin /usr/local/

    cd /usr/local/

    chmod +x jdk-6u14-linux-x64.bin

    ./jdk-6u14-linux-x64.bin

    //按yes,按enter

    mv jdk1.6.0_14/ /usr/local/jdk1.6

    vim /etc/profile

    在最后一行添加

    export JAVA_HOME=/usr/local/jdk1.6

    export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib

    export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin

    export AMOEBA_HOME=/usr/local/amoeba

    export PATH=$PATH:$AMOEBA_HOME/bin

    使文件立即生效:source /etc/profile

    java -version

    安装amoeba

    在opt目录下创建amoeba目录

    mkdir /usr/local/amoeba

    解压

    tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/

    赋权

    chmod -R 755 /usr/local/amoeba/

    执行:

    /usr/local/amoeba/bin/amoeba

    显示 amoeba start|stop说明安装成功

    在三台数据库给用户amoeba赋权

    grant all on *.* to amoeba@'192.168.176.%' identified by '123456';

    flush privileges;

    在amoeba服务器修改配置文件:

    cd /usr/local/amoeba/conf/

    配置用户信息:

    配置数据库信息:

    备份

    cp amoeba.xml amoeba.xml.bak

    改配用户信息:

    vim amoeba.xml

    --30行--

    amoeba

    --32行--

    123456

    --115行--

    master

    --117-去掉注释-

    master

    slaves

    修改数据库信息:

    cp dbServers.xml dbServers.xml.bak

    vim dbServers.xml

    --23行--注释掉 作用:默认进入test库 以防mysql中没有test库时,会报错

    --26--修改

    amoeba

    --28-30--去掉注释

    123456

    --45--修改,设置主服务器的名Master

    --48--修改,设置主服务器的地址

    192.168.233.21

    --52--修改,设置从服务器的名slave1

    --55--修改,设置从服务器1的地址

    192.168.233.22

    --58--复制上面6行粘贴,设置从服务器2的名slave2和地址

    192.168.233.23

    --65行--修改

    --71行--修改

    slave1,slave2

    启动Amoeba软件:

    /usr/local/amoeba/bin/amoeba start &

    查看8066端口是否开启

    netstat -anpt | grep java

    测试读写分离:

    客户端安装 mariadb

    yum install -y mariadb-server mariadb

    systemctl start mariadb.service

    修改三台mysql生成日志文件

    最后一行添加:

    general_log=ON

    general_log_file=/usr/local/mysql/data/mysql_general.log

    三台库打开日志

    tail -f /usr/local/mysql/data/mysql_general.log

    在客户端对表进行写入时三个日志都会有显示

    查看表只有一台从库有记录,而且会轮询记录:

  • 相关阅读:
    REST API URI 设计的 7 条规则
    Raspberry Pi 4B树莓派学习笔记
    数字孪生3d车间、虚拟车间、数字化三维车间的案例比较
    python每日一题【剑指 Offer 12. 矩阵中的路径】
    “从部署到优化,打造高效会议管理系统“
    如何部署SpringBoot工程
    DAY1-深度学习100例-卷积神经网络(CNN)实现mnist手写数字识别
    短视频剪辑矩阵系统开发解决的市场工具难点?
    和外星人如何交流
    如此简单的k8s,快速玩转ingress
  • 原文地址:https://blog.csdn.net/weixin_51694382/article/details/134390447