基于Docker做MySQL主从搭建与Django的读写分离
基于Docker做MySQL主从搭建
主从的作用:写数据数据时使用主库,从库只用来读数据,这样做能够减少数据库压力,主从搭建可以一主一从,也可以是一主多从。
mysql主从配置的流程
如图:
1.master会将变动记录到二进制日志(binlog)里面(主库要开启binlog日志);
2.master有一个I/O线程将二进制日志发送到slave;
3.slave有一个I/O线程把master发送的二进制写入到relay log日志里面;
4.slave有一个SQL线程,按照relay log 日志处理slave的数据;
搭建步骤
第一步:拉取MySQL镜像
docker pull mysql:5.7
第二步:创建一些文件夹,存放MySQL配置
# 主库配置
mkdir /home/mysql
mkdir /home/mysql/conf.d
mkdir /home/mysql/data
vim /home/mysql/my.cnf
"""
[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
server-id=100
log-bin=mysql-bin
"""
# 从库配置
mkdir /home/mysql2
mkdir /home/mysql2/conf.d
mkdir /home/mysql2/data/
vim /home/mysql2/my.cnf
"""
[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
server-id=101
log-bin=mysql-slave-bin
relay_log=edu-mysql-relay-bin
"""
第三步:启动两个docker容器
# 运行主库的容器
docker run -di -v /home/mysql/data/:/var/lib/mysql -v /home/mysql/conf.d:/etc/mysql/conf.d -v /home/mysql/my.cnf:/etc/mysql/my.cnf -p 3306:3306 --name mysql-master -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
# 运行从库的容器
docker run -di -v /home/mysql2/data/:/var/lib/mysql -v /home/mysql2/conf.d:/etc/mysql/conf.d -v /home/mysql2/my.cnf:/etc/mysql/my.cnf -p 3307:3306 --name mysql-slave -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
第四步:连接主库
mysql -h 10.0.0.200 -P 3306 -uroot -p123456
# 创建test用户
create user 'test'@'%' identified by '123';
# 授权用户
grant all privileges on *.* to 'test'@'%' ;
# 刷新权限
flush privileges;
# 查看主服务器状态(显示如下图)
show master status;
第五步:连接从库
# 连接
mysql -h 10.0.0.200 -P 3307 -uroot -p123456
# 连接主库
change master to master_host='10.0.0.200',master_port=3306,master_user='test',master_password='123',master_log_file='mysql-bin.000003',master_log_pos=0;
# 开启从库
start slave;
# 查看从库状态
show slave status\G;
第六步:测试
# 在主库上创建数据库test1
create database test1;
# 在从库上查看是否同步成功
show database;
django读写分离
第一步:配置文件配置
# 配置两个数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '10.0.0.200', # mysql的ip地址
'PORT': 3306, # mysql端口号
'USER': 'test', # mysql用户名
'PASSWORD': '123', # mysql密码
'NAME': 'test1', # mysql库名称
},
'default2': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '10.0.0.200', # mysql的ip地址
'PORT': 3307, # mysql端口号
'USER': 'root', # mysql用户名
'PASSWORD': '123456', # mysql密码
'NAME': 'test1', # mysql库名称
}
}
第二步:读写分离
# 方式一:手动读写分离
# 主库用于写
Book.objects.using('default').create(name='西游记')
# 从库用于读
res = Book.objects.using('default2').all()
print(res)
# 方式二:自动读写分离
# 第一步:写一个类
class AuthRouter(object):
# 读,返回在配置文件中用于读的数据库的键
def db_for_read(self, model, **hints):
return 'default2'
# 写,返回在配置文件中用于写的数据库的键
def db_for_write(self, model, **hints):
return 'default'
# 第二步:在配置文件中配置
DATABASE_ROUTERS = ['django_test.db_router.AuthRouter', ] # 类的路径