一、MySQL读写分离

1.1 什么是数据读写分离

把客户端访问数据时的查询请求和写请求分别给不同的数据库服务器处理。

1.2 为什么要对数据做读写分离

减轻单台数据库服务器的并发访问压力
提高数据库服务器硬件利用率

1.3 实现数据读写分离的方式

人肉分离:  做不同的数据操作时,访问指定的数据库服务器
使用mysql中间件提供的服务实现:mycat   mysql-proxy   maxscale

1.4 使用中间件提供的服务做数据读写分离的缺点

单点故障(当从库挂掉的时候,主库会承担用户的所有读写请求。当主库挂掉的时候,从库无法提供任何服务)
当访问量大时,会成为网络瓶颈

二、配置数据读写分离

2.1  拓扑结构

  • 添加一个 MySQL 代理

         – 为客户端提供统一的数据库接口

mysql 多读多写效率 mysql一写多读_数据库服务器

2.2 读写分离的原理

• 多台 MySQL 服务器
– 分别提供读、写服务,均衡流量
– 通过主从复制保持数据一致性
• 由 MySQL 代理面向客户端
– 收到 SQL 写请求时,交给服务器 A 处理
– 收到 SQL 读请求时,交给服务器 B 处理
– 具体区分策略由服务设置

2.3 配置数据读写分离

2.3.1 基本构建思路

1. 已搭建好 MySQL 主从复制
– 基于上一个实验的结果
– 其中 Slave 为只读
2. 添加一台 MySQL 代理服务器
– 部署 / 启用 maxscale
3. 客户端通过代理主机访问 MySQL 数据库
– 访问代理服务器

2.3.2  配置一主一从  主从同步结构,并在客户端测试配置

master51> grant  all  on  webdb.*  to webuser@"%"  identified by " 123456";

2.3.3  配置数据读写分离服务器

2.3.3.1环境准备

setenforce  0
 systemctl  stop  firewalld
 yum repolist
 ping  -c  2  192.168.4.51
 ping  -c  2  192.168.4.52


下载软件包 maxscale-2.1.2-1.rhel.7.x86_64.rpm

2.3.3.2 配置数据读写分离服务器56
1 装包

yum -y install maxscale-2.1.2-1.rhel.7.x86_64.rpm

2 修改配置文件

vim  /etc/maxscale.cnf
   9 [maxscale]     //服务运行后开启线程的数量
  10 threads=auto
#定义数据库服务器
  18 [名称]    
  19 type=server
  20 address=数据库服务器的ip地址
  21 port=3306
  22 protocol=MySQLBackend#定义监控的数据库服务器
  36 [MySQL Monitor]
  37 type=monitor
  38 module=mysqlmon
  39 servers=数据库服务器列表
  40 user=监视数据库服务器时连接的用户名
  41 passwd=密码
  42 monitor_interval=10000#不定义只读服务
  53 #[Read-Only Service]
  54 #type=service
  55 #router=readconnroute
  56 #servers=server1
  57 #user=myuser
  58 #passwd=mypwd
  59 #router_options=slave#定义读写分离服务
  64 [Read-Write Service]
  65 type=service
  66 router=readwritesplit
  67 servers=数据库服务器列表
  68 user=用户名 #验证连接代理服务访问数据库服务器的用户是否存在
  69 passwd=密码
  70 max_slave_connections=100%#定义管理服务
  76 [MaxAdmin Service]
  77 type=service
  78 router=cli#不指定只读服务使用的端口号
  86 #[Read-Only Listener]
  87 #type=listener
  88 #service=Read-Only Service
  89 #protocol=MySQLClient
  90 #port=4008#定义读写分离服务使用的端口号
  92 [Read-Write Listener]
  93 type=listener
  94 service=Read-Write Service
  95 protocol=MySQLClient
  96 port=4006  #设置使用的端口#定义管理服务使用的端口
  98 [MaxAdmin Listener]
  99 type=listener
 100 service=MaxAdmin Service
 101 protocol=maxscaled
 102 socket=default
 port=4016         #不设置使用的默认端口

3 根据配置文件的设置,在2台数据库服务器上添加授权用户

mysql>grant replication slave, replication client on *.* to scalemon@'%'  identified by  '123qqq...A'; 
mysql> grant select on mysql.* to maxscale@"%" identified by  '123qqq...A';
mysql> select  user from mysql.user  where  user  in ("scalemon","maxscale");

4 启动服务

]# maxscale  -f /etc/maxscale.cnf
]# pkill  -9 maxscale   //停止服务

5 查看服务进程和端口

[root@host56 ~]# ps -C maxscale
   PID TTY          TIME CMD
 25957 ?        00:00:00 maxscale[root@host56 ~]# netstat -utnlp | grep -i  maxscale
 tcp6       0      0 :::4016                 :::*                    LISTEN      25957/maxscale
       
 tcp6       0      0 :::4006                 :::*                    LISTEN      25957/maxscale

2.3.4 测试配置

1.在本机访问管理管端口查看监控状态

]#maxadmin  -P端口  -u用户   -p密码
 ]#maxadmin -P4016  -uadmin   -pmariadb MaxScale>list  servers


 
2.客户端访问数据读写分离服务

]#which  mysql
 ]#mysql  -h读写分离服务ip   -P4006   -u用户名  -p密码]# mysql -h192.168.4.56 -P4006 -uwebuser -p123456
 mysql>  select  @@hostname
 mysql>  执行插入或查询 ( 在51 和 52 本机查看记录)

二、mysql多实例

2.1 多实例介绍

• 什么是多实例
– 在一台物理主机上运行多个数据库服务

• 为什么要使用多实例
– 节约运维成本
– 提高硬件利用率

2.2 配置多实例

2.1.1 环境准备

在192.168.4.50配置多实例,停滞mysqld服务
  663  rpm  -qa  | grep  -i mysql
  664  systemctl  stop mysqld
  666  systemctl  disable mysqld

2.1.2 安装提供多多实例服务的mysql数据库服务软件

]# tar -zxvf mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz ]# mv mysql-5.7.20-linux-glibc2.12-x86_64  /usr/local/mysql
]# vim  /etc/profile              //把mysql多实例bin下的命令成为系统命令
 export PATH=/usr/local/mysql/bin:$PATH
 :wq
 ]# source  /etc/profile
 ]# echo  $PATH

2.1.3 创建主配置文件

]# mv /etc/my.cnf  /etc/my.cnf.bak
 ]#vim  /etc/my.cnf
 [mysqld_multi]   #启用多实例 
 mysqld = /usr/local/mysql/bin/mysqld_safe   #服务启动调用的进程   
 mysqladmin = /usr/local/mysql/bin/mysqladmin   #管理命令路径
 user = root   #调用启动程序的用户名
 [mysqld1]   #实例编号
 port=3307  #监听端口
 datadir=/dataone   #数据库目录    socket  = /data3307/mysql.sock       #sock文件
pid-file =  /data3307/mysqld.pid         #pid号文件
 log-error = /data3307/mysqld.err       [mysqld2]
 port           = 3308      
 datadir = /data3308     socket  = /data3308/mysql.sock         #sock文件
pid-file =  /data3308/mysqld.pid         #pid号文件
 log-error = /data3308/mysqld.err        #错误日志
 :wq

2.1.4 根据配置文件的设置,做相应的配置

2.1.4.1 创建数据库目录

]#mkdir   /data3307
 ]#mkdir   /data3308

2.1.4.2 创建进程运行的所有者和组 mysql

]# useradd mysql

2.1.4.3 初始化授权库

]#mysqld  --user=mysql  --basedir=软件安装目录  --datadir=数据库目录   --initialize
]# mysqld  --user=mysql  --basedir=/usr/local/mysql --datadir=/data3307   --initialize  
 2018-07-21T09:55:03.752482Z 1 [Note] A temporary password is generated for root@localhost: lfy9t&_mondL    ]# ls /data3307 
]#mysqld  --user=mysql  --basedir=/usr/local/mysql --datadir=/data3308   --initialize 
2018-07-21T09:57:54.500857Z 1 [Note] A temporary password is generated for root@localhost: (:sKl_<?#3py
 ]# ls /data3300

2.1.5 启动服务

]# mysqld_multi start 编号
 ]# mysqld_multi  start  1     【mysqld1指定的编号】
 ]# netstat -utnlp  | grep :3307

2.1.6 访问多实例服务

在数据库服务器本机连接对应的多实例服务

mysql  -uroot  -p初始密码  -S  sock文件
]#mysql  -uroot  -p'oA7ghN;+(mia'  -S  /data3307/mysql.sock

附:使用初始密码登录后,要求修改登录密码

mysql> alter user  user()  identified by "123456";
 mysql> 执行SQL命令
 MySQL>quit
 ]# ls /data3307

2.1.7 停止指定的实例服务

mysqld_multi --user=root  --password=密码  stop   编号
 ]# mysqld_multi --user=root --password=123456 stop 1

2.1.8 启动实例服务2  连接服务  存储数据   断开连接  停止服务

三、mysql调优

3.1 mysql体系结构 (由8个功能模块组成)

mysql 多读多写效率 mysql一写多读_mysql_02

连接池: 当接收到客户端的连接请求后,检查是否有资源响应客户端的连接请求。
 
SQL接口: 把sql传递给mysqld线程处理

分析器: 检查执行的sql命令是否有语法错误,和是否有访问权限。

优化器:优化执行的sql命令,已最节省资源的方式执行sql命令

查询缓存: 缓存曾经查找到的记录,缓存空间从物理内存划分出来的。

存储引擎: 是表的处理器,不同的存储引擎有不同的功能和数据存储方式。Myisam   innodb

文件系统: 存储表中记录的磁盘

管理工具: 安装服务软件后,提供的命令 
        mysqldump  
        mysqlbinlog
        mysqladmin

3.2 mysql服务处理查询请求过程

数据服务器接收到查询请求后,先从查询缓存里查找记录,若查询缓存里有查找记录,直接从缓存提取数据给客户端,

反之到表去查询记录,把查到的记录先存放到查询缓存里在返回给客户端。

3.3 mysql调优

3.3.1 如何优化mysql数据库服务器(那些原因会导致数据库服务器处理客户端的连接请求慢)

1.硬件配置低,导致处理速度慢。 CPU  内存  存储磁盘
                                                               接口   转速    15000/s
uptime     free  -m      top  --> 0.0 wa

2.网络带宽窄   网络测速软件

3.提供服务软件的版本低,导致性能低下:

4.调整MySQL服务运行时参数
4.1 并发连接数量

Max_used_connections/max_connections=0.85
   500/x=0.85  * 100%   = 85%show  global  status  like "Max_used_connections";
 set  global   max_connections  =   数字;

4.2 连接超时时间

show   variables   like   "%timeout%";
 connect_timeout  客户端与服务器建立连接时tcp三次握手超时是时间
 wait_timeout  户端与服务器建立连接后,等待执行sql命令的超时时间。

4.3 可以重复使用的线程的数量  thread

show   variables   like   "%thread%";
 thread_cache_size = 9

4.4 所有线程同时打开表的数量

show   variables   like   "%open%";
 table_open_cachemysqld  -----> disk ---->x.ibd ----> memory  ----> disk

5.修改与查询相关参数  (字节)   mysqld

5.1 常用SQL语句使用的缓存空间

select   *  from   t1;   read_buffer_size
select   *  from   t1  order  by   字段名;sort_buffer_size
 select   *  from   t1  group  by   字段名;read_rnd_buffer_size
 name ----> index
 select  * from  t1  where  name="jim"; key_buffer-size

5.2 与查询缓存相关参数的设置

show   variables   like   "%cache%";
 show   variables   like   "query_cache%";query_cache_wlock_invalidate | OFF  关


当对myisam存储引擎的表执行查询时,若检查到有对表做写的 sql操作,不从查询缓存里查询数据返回给客户端,而是

等写操作完成后,重新查询数据返回给客户端。

pc1   select    name  from t1  where name="bob";
 mysqld --->  name=bobpc2 select    name  from t1  where name="bob";
 mysqld->  name= bob;pc3  update  t1  set  name="jack" wehre  name="bob"; //pc1,pc2,pc3并发访问时,如果query_cache_wlock_invalidate=OFF   ,会先修改然后再从数据库里面重新查询数据返回给客户端。

5.3 查看查询缓存的统计信息
show   global   status   like   "qcache%";
Qcache_hits        10     记录在查询缓存里查询到数据的次数     
Qcache_inserts   100   记录在查询缓存里查找数据的次数  
Qcache_lowmem_prunes    清理查询缓存空间的次数

4、程序编写sql查询语句太复杂导致,数据库服务器处理速度慢。
开启数据库服务器的慢查询日志,记录超过指定时间显示查询结果的sql命令。                                           10s

[mysqld]
slow_query_log=on

5、网络架构有问题(有数据传输瓶颈) 

3.3.2 MySQL调优总结

mysql 多读多写效率 mysql一写多读_数据库服务器_03