把客户端访问数据时的查询请求和写请求分别给不同的数据库服务器处理。
减轻单台数据库服务器的并发访问压力
提高数据库服务器硬件利用率
人肉分离: 做不同的数据操作时,访问指定的数据库服务器
使用mysql中间件提供的服务实现:mycat mysql-proxy maxscale
单点故障(当从库挂掉的时候,主库会承担用户的所有读写请求。当主库挂掉的时候,从库无法提供任何服务)
当访问量大时,会成为网络瓶颈
– 为客户端提供统一的数据库接口
• 多台 MySQL 服务器
– 分别提供读、写服务,均衡流量
– 通过主从复制保持数据一致性
• 由 MySQL 代理面向客户端
– 收到 SQL 写请求时,交给服务器 A 处理
– 收到 SQL 读请求时,交给服务器 B 处理
– 具体区分策略由服务设置
1. 已搭建好 MySQL 主从复制
– 基于上一个实验的结果
– 其中 Slave 为只读
2. 添加一台 MySQL 代理服务器
– 部署 / 启用 maxscale
3. 客户端通过代理主机访问 MySQL 数据库
– 访问代理服务器
master51> grant all on webdb.* to webuser@"%" identified by " 123456";
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
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 本机查看记录)
• 什么是多实例
– 在一台物理主机上运行多个数据库服务• 为什么要使用多实例
– 节约运维成本
– 提高硬件利用率
在192.168.4.50配置多实例,停滞mysqld服务
663 rpm -qa | grep -i mysql
664 systemctl stop mysqld
666 systemctl disable mysqld
]# 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
]# 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.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
]# mysqld_multi start 编号
]# mysqld_multi start 1 【mysqld1指定的编号】
]# netstat -utnlp | grep :3307
在数据库服务器本机连接对应的多实例服务
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
mysqld_multi --user=root --password=密码 stop 编号
]# mysqld_multi --user=root --password=123456 stop 1
连接池: 当接收到客户端的连接请求后,检查是否有资源响应客户端的连接请求。
SQL接口: 把sql传递给mysqld线程处理
分析器: 检查执行的sql命令是否有语法错误,和是否有访问权限。
优化器:优化执行的sql命令,已最节省资源的方式执行sql命令
查询缓存: 缓存曾经查找到的记录,缓存空间从物理内存划分出来的。
存储引擎: 是表的处理器,不同的存储引擎有不同的功能和数据存储方式。Myisam innodb
文件系统: 存储表中记录的磁盘
管理工具: 安装服务软件后,提供的命令
mysqldump
mysqlbinlog
mysqladmin
数据服务器接收到查询请求后,先从查询缓存里查找记录,若查询缓存里有查找记录,直接从缓存提取数据给客户端,
反之到表去查询记录,把查到的记录先存放到查询缓存里在返回给客户端。
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_cache
mysqld -----> 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=bob
pc2 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、网络架构有问题(有数据传输瓶颈)