Mysql主从搭建Django读写分离

9 篇文章 0 订阅
3 篇文章 0 订阅

Mysql主从

Mysql主从原理:

  1. master会将变动记录到二进制日志(BinLog)里面
  2. 然后master会有一个I/O线程将二进制发送到salve(从库)
  3. 此时slave也会有一个I/O线程吧master发送的二进制写入到relay日志里面
  4. 最后salve有一个SQL线程,按照relay日志处理slave的数据

操作步骤

一、准备好两台mysql的服务器(再次使用docker模拟两台机器)

环境mysql版本ip地址端口号
主库(master)5.7172.16.209.100:33307
从库(salve)5.7172.16.209.100:33306

二、用docker拉起两个mysql容器,步骤如下

# 主库
mkdir /home/mysql  # 创建挂载主目录
mkdir /home/mysql/conf.d  #创建挂载配置文件
mkdir /home/mysql/data/  # 创建挂载数据文件

touch /home/mysql/my.cnf  # 创建配置文件

# 从库
mkdir /home/mysql2  # 创建挂载主目录
mkdir /home/mysql2/conf.d  #创建挂载配置文件
mkdir /home/mysql2/data/  # 创建挂载数据文件
touch /home/mysql2/my.cnf

三、修改配置文件

####主库的配置文件,server-id和开启binlog日志
[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
# 主要是两个
# 主库--start-- 同一局域网内注意要唯一,通过id号找到从库
server-id=100
# 开启二进制日志功能,可以随便取(关键),因为主从就是依赖bin-log日志
log-bin=mysql-bin



#############从库的配置
[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
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave-bin
## relay_log配置中继日志
relay_log=edu-mysql-relay-bin

[client]
default-character-set=utf8
[mysql]
default-character-set=utf8

四、拉起来两个Mysql容器

#启动主库容器(挂载外部目录,端口映射成33307,密码设置为123456)
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 33307:3306 --name mysql-master -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
#启动从库容器(挂载外部目录,端口映射成33306,密码设置为123456)
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 33306:3306 --name mysql-slave -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

这时两个容器都跑起来了

image-20210209142022545

Navicate测试连接

image-20210209142339008

但是现在还不能同步,同步的方法也比较简单,就是创建一个用户,远程连上master,然后从master上拿到日志数据

五、创建用户并授权

1.进入到master容器

docker exec -it mysql-master /bin/bash
mysql -uroot -p123456

image-20210210092429817

2.创建用户并授权

#在主库创建用户并授权
##创建test用户
create user 'test'@'%' identified by '123';
##授权用户
grant all privileges on *.* to 'test'@'%' ;
###刷新权限
flush privileges;
#查看主服务器状态(显示如下图)
show master status;
# 可以看到日志文件的名字,和现在处在哪个位置,也就是file和position

image-20210210095926654

记录一下增长一下,复制后时候需要指定复制文件,和复制位置

六、连接从库,配置连接主库

docker exec -it mysql-slave /bin/bash
mysql -uroot -p123456

1.配置详解

change master to 
master_host='MySQL主服务器IP地址', 
master_user='之前在MySQL主服务器上面创建的用户名', 
master_password='之前创建的密码', 
master_log_file='MySQL主服务器状态中的二进制文件名', 
master_log_pos='MySQL主服务器状态中的position值';

# 命令如下
change master to master_host='ip地址',master_port=33307,master_user='test',master_password='123',master_log_file='mysql-bin.000001',master_log_pos=0;

# master_log_pos数字代表的是从master那个位置开始复制,0或其实位置

#启用从库
start slave;
#查看从库状态(如下图)
show slave status\G;
####这两个是yes表示配成功
   Slave_IO_Running: Yes
   Slave_SQL_Running: Yes  # 可能会出现这个问题 NO
   
   
# 如果出现问题,要看last_error 然后拍错解决就好了

image-20210210114628185

七、测试

1.在主库上创建数据库test1

create database test1;
use test1;

2.创建表

create table tom(id int not null,name varchar(100)not null,age tinyint);

3.插入数据

insert tom(id,name,age) values(1,"tom",18),(2,"jerry",19),(3,"lary",18);

这时候从库中也有了相应的数据

image-20210210122350342

八、Django实现读写分离

1.基于主从已经搭建完成

2.在Django中settings.py中配置

#1  在setting中配置
DATABASES = {
    # 主库--只写
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'test1',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '101.133.225.166',
        'PORT': 33307,
        'ATOMIC_REQUEST':True,  # 代表一次请求在一次事务中
    },
    # 从库--只读
    'db1': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'test1',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '101.133.225.166',
        'PORT': 33306,
    },
}

3.读写分离的操作

3.1 手动指定

在使用orm操作的时候,指定使用的库.using(指定的库)

这里是写操作,因为默认是default所以一般不带using

res = models.Book.object.using('default').create(name="《海子》", price=33)

读操作(使用从库)

res=models.Book.objects.using('db1').all().first()
3.2 自动指定(自定义一个py文件)
# db_router.py

class Router1:  # 名字可以随便指定,但是一定要有下面两个方法
    def db_for_read(self, model, **hints):
        return 'db1'
    def db_for_write(self, model, **hints):
        return 'default'

配置完成后在settings.py中配置

# setting.py
# 在setting中注册
# 注册一下
DATABASE_ROUTERS = ['db_router.Router1',]

这样注册之后就会自动的分配读写

3.3更细粒度

做完分库分表,只希望在指定库中读,指定库中存储

class Router1:
    def db_for_read(self, model, **hints):
        if model._meta.model_name == 'book':
            # 也就是如果表名==book去db1中读,其余的去default
            return 'db1'
        else:
            return 'default'

    def db_for_write(self, model, **hints):
        return 'default'
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值