• mysql主从复制与读写分离


    一,主从复制

            1,为什么要做主从复制

            单台mysql在安全性,高可用和高并发方面都无法满足实际的需求,所以可以选择配置多台主从数据库服务器以实现读写分离。

            2,主从复制的原理

            主从复制是为了保证数据的完整性,由slave角色复制master角色的数据并存放在二进制日志。

            主从复制有三个进程:主的dump进程,从的io进程和sql进程。其中当有数据写入主的时候,会被存储为二进制日志,从服务器的io进程会每隔一段时间定时访问主的dump进程,主的dump进程监听到访问后会发送二进制日志给io,从会将二进制日志存储为中继日志,最后由sql将中继日志捞出并执行到自己数据库内部。

            slave无法执行master上并行更新的操作。

            3,主从复制类型:

                    异步复制:master只要完成就会返回给客户端,不关心从库是否已经处理数据。

                    同步复制:等从完成同步之后才向客户端返回结果。

                    半同步复制:只要有一个从完成同步数据,master就返回给客户端。

            

            4,主从复制的搭建

    master服务器:Master 服务器:192.168.10.15

    Slave1 服务器:192.168.10.14

    Slave2 服务器:192.168.10.16

    1. 一,安装mysql
    2. 安装环境
    3. yum -y install pcre-devel zlib-devel gcc gcc-c++ make ncurses ncurses-devel bison cmake
    4. 创建运行用户
    5. useradd -M -s /sbin/nologin mysql
    6. 编译安装
    7. cd /opt
    8. tar -xf mysql-boost-5.7.20.tar.gz
    9. cd /opt/mysql-5.7.20/
    10. 编译
    11. cmake \
    12. -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
    13. -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
    14. -DSYSCONFDIR=/etc \
    15. -DSYSTEMD_PID_DIR=/usr/local/mysql \
    16. -DDEFAULT_CHARSET=utf8 \
    17. -DDEFAULT_COLLATION=utf8_general_ci \
    18. -DWITH_EXTRA_CHARSETS=all \
    19. -DWITH_INNOBASE_STORAGE_ENGINE=1 \
    20. -DWITH_ARCHIVE_STORAGE_ENGINE=1 \
    21. -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
    22. -DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
    23. -DMYSQL_DATADIR=/usr/local/mysql/data \
    24. -DWITH_BOOST=boost \
    25. -DWITH_SYSTEMD=1
    26. 安装
    27. make && make install
    28. 修改mysql配置文件
    29. vim /etc/my.cnf
    30. 清除所有,写入下面内容
    31. [client]
    32. port = 3306
    33. socket=/usr/local/mysql/mysql.sock
    34. [mysqld]
    35. user = mysql
    36. basedir=/usr/local/mysql
    37. datadir=/usr/local/mysql/data
    38. port = 3306
    39. character-set-server=utf8
    40. pid-file = /usr/local/mysql/mysqld.pid
    41. socket=/usr/local/mysql/mysql.sock
    42. bind-address = 0.0.0.0
    43. skip-name-resolve
    44. max_connections=2048
    45. default-storage-engine=INNODB
    46. max_allowed_packet=16M
    47. server-id = 1
    48. sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES
    49. 更改mysql安装目录和配置文件的属主属组
    50. chown -R mysql:mysql /usr/local/mysql/
    51. chown mysql:mysql /etc/my.cnf
    52. 设置环境变量
    53. echo 'export PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH' >> /etc/profile
    54. source /etc/profile
    55. 初始化数据库
    56. cd /usr/local/mysql/bin/
    57. ./mysqld \
    58. --initialize-insecure \
    59. --user=mysql \
    60. --basedir=/usr/local/mysql \
    61. --datadir=/usr/local/mysql/data
    62. 添加mysqld系统服务
    63. cp /usr/local/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/
    64. systemctl daemon-reload
    65. systemctl start mysqld.service
    66. systemctl enable mysqld
    67. 使用mysql -uroot -p登陆后在里面修改登陆密码为123456
    68. ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
    69. FLUSH PRIVILEGES;
    1. 二,搭建主从复制
    2. 进行时间同步
    3. 主服务器:
    4. yum install ntp -y
    5. vim /etc/ntp.conf 在末尾添加
    6. server 127.127.80.0
    7. fudge 127.127.80.0 stratum 8
    8. service ntpd start
    9. 从服务器:
    10. yum install ntp ntpdate -y
    11. service ntpd start /usr/sbin/ntpdate 192.168.10.15
    12. crontab -e
    13. */30 * * * * /usr/sbin/ntpdate 192.168.80.10
    14. mysql设置
    15. 主服务器:
    16. vim /etc/my.cnf
    17. server-id = 11 #修改id,需要三台机器都不一样
    18. log-bin=master-bin #添加
    19. binlog_format = MIXED
    20. log-slave-updates=true #添加
    21. systemctl restart mysqld
    22. mysql -u root -p123456
    23. GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.10.%' IDENTIFIED BY '123456';
    24. FLUSH PRIVILEGES;
    25. show master status;
    26. 记住展示的file日志名和position偏移量
    27. 从服务器:
    28. vim /etc/my.cnf
    29. server-id = 22
    30. relay-log=relay-log-bin #添加
    31. relay-log-index=slave-relay-bin.index #添加
    32. relay_log_recovery = 1 #可选项,若从服务器当即后relay-log损坏导致一部分中继日志没有处理,就选择放弃未执行的relay-log并从主服务器从新获取。
    33. systemctl restart mysqld
    34. mysql -u root -p123456
    35. master_host='192.168.10.15',master_user='myslave',master_password='123456',master_log_file='在主查询的日志名',master_log_pos=在主查询的偏移量;
    36. start slave;
    37. show slave status\G
    38. 在显示的内容确保下面两项是yes
    39. Slave_IO_Running: Yes
    40. Slave_SQL_Running: Yes

    二,读写分离

            1,什么是读写分离

            读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。

            2,为什么要读写分离

            因为数据库的“写”(写10000条数据可能要3分钟)操作是比较耗时的,但是数据库的“读”(读10000条数据可能只要5秒钟)。所以读写分离,解决的是,数据库的写入,影响了查询的效率。

            3,什么时候要进行读写分离

            数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。

            4,什么时候要读写分离

            数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。

            5,mysql支持的复制类型

                    (1)STATEMENT:基于语句的复制。在服务器上执行sql语句,在从服务器上执行同样的语句,mysql默认采用基于语句的复制,执行效率高。
                    (2)ROW:基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。
                    (3)MIXED:混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

            6,实现方式

                    (1)基于程序代码内部实现

                    在代码中根据 select、insert 进行路由分类,这类方法也是目前生产环境应用最广泛的。优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支;缺点是需要开发人员来实现,运维人员无从下手。但是并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的Java应用,如果在程序代码中实现读写分离对代码改动就较大。

                    (2)基于中间代理层实现

                    代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有以下代表性程序。

                    MySQL-Proxy。MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行SQL 判断。

                    Atlas。是由奇虎360的Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。

                    Amoeba。由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。

            7,读写分离的搭建

            因为amoeba入门门槛最低,所以这次使用amoeba。

            继续主从复制搭建的环境,需要额外准备两台虚拟机:

                    Amoeba 服务器:192.168.10.13,安装jdk1.6和amoeba

                    客户端 服务器:192.168.10.13,安装mysql

    1. amoeba服务器:
    2. 安装java(java推荐1.51.6,高版本不推荐使用)
    3. cd /opt/
    4. cp jdk-6u14-linux-x64.bin /usr/local/
    5. cd /usr/local/
    6. chmod +x jdk-6u14-linux-x64
    7. ./jdk-6u14-linux-x64.bin
    8. 一直回车,最后yes
    9. mv jdk1.6.0_14/ /usr/local/jdk1.6
    10. vim /etc/profile #末尾写入
    11. export JAVA_HOME=/usr/local/jdk1.6
    12. export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
    13. export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
    14. export AMOEBA_HOME=/usr/local/amoeba
    15. export PATH=$PATH:$AMOEBA_HOME/bin
    16. source /etc/profile
    17. java -version
    18. 安装amoeba
    19. mkdir /usr/local/amoeba
    20. tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
    21. chmod -R 755 /usr/local/amoeba/
    22. /usr/local/amoeba/bin/amoeba
    23. 出现amoeba start|stop说明安装成功
    24. 配置读写分离
    25. 先在Master、Slave1、Slave2 的mysql上开放权限给 Amoeba 访问
    26. grant all on *.* to test@'192.168.10.%' identified by '123456';
    27. 回到amoeba配置服务
    28. cd /usr/local/amoeba/conf/
    29. cp amoeba.xml amoeba.xml.bak
    30. vim amoeba.xml
    31. --30行--
    32. <property name="user">amoeba</property>
    33. --32行--
    34. <property name="password">123456</property>
    35. --115行--
    36. <property name="defaultPool">master</property>
    37. --117-去掉注释-
    38. <property name="writePool">master</property>
    39. <property name="readPool">slaves</property>
    40. cp dbServers.xml dbServers.xml.bak
    41. vim dbServers.xml
    42. --23行--注释掉 作用:默认进入test库 以防mysql中没有test库时,会报错
    43. <!-- <property name="schema">test</property> -->
    44. --26--修改
    45. <property name="user">test</property>
    46. --28-30--去掉注释
    47. <property name="password">123456</property>
    48. --45--修改,设置主服务器的名Master
    49. <dbServer name="master" parent="abstractServer">
    50. --48--修改,设置主服务器的地址
    51. <property name="ipAddress">192.168.10.15</property>
    52. --52--修改,设置从服务器的名slave1
    53. <dbServer name="slave1" parent="abstractServer">
    54. --55--修改,设置从服务器1的地址
    55. <property name="ipAddress">192.168.10.14</property>
    56. --58--复制上面6行粘贴,设置从服务器2的名slave2和地址
    57. <dbServer name="slave2" parent="abstractServer">
    58. <property name="ipAddress">192.168.10.16</property>
    59. --65行--修改
    60. <dbServer name="slaves" virtual="true">
    61. --71行--修改
    62. <property name="poolNames">slave1,slave2</property>
    63. /usr/local/amoeba/bin/amoeba start&
    64. 通过查看8066端口是否运行来看amoeba是否成功启动
    65. 客户机:
    66. yum install -y mariadb-server mariadb
    67. systemctl start mariadb.service

  • 相关阅读:
    redis 与Python交互取出来的是bytes类型
    如何选择合适的 AWS 区域对网站性能和成本?
    【机器学习】特征选择之包裹式特征选择法
    Day12力扣打卡
    Springboot整合之Shiro和JWT技术实现无感刷新
    论文阅读 CVPR2022《Rethinking Semantic Segmentation:A Prototype View》
    java 数据类型的分类
    后端php项目和数据库启动
    CSS Position(定位)
    好久没回来看看了
  • 原文地址:https://blog.csdn.net/qq_61855329/article/details/132661732