在Rancher中添加Mysql-Master-Slave,使得django数据库读写分离。
Posted on 2018-09-30 16:43 哈哈丶大傻瓜 阅读(1503) 评论(0) 编辑 收藏 举报1.拉取mysql镜像
docker pull deoj/mysql:v1
2.(1)在Rancher中创建Master容器:
添加容器拉去本地镜像,以及开放端口:
添加外部配置文件,以及数据持久化:
(2)在Rancher中创建Slave-1、Slave-2容器:
添加容器拉去本地镜像,以及开放端口:
添加外部配置文件,以及数据持久化:
如图:
3.(1)进入master容器中:
(2) show databases; #查看数据库test有没有创建成功
红色标记证明创建成功,然后执行如下代码来查看master状态;
show master status;
其中红色标记的参数需要在配置文件中用到先记录下来。
下面是master的配置文件:
[mysqld]
server-id = 2
port = 3302
binlog-ignore-db = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
#default-storage-engine = InnoDB
log-bin = mysql-bin-master
binlog_cache_size = 1M
binlog_format = mixed
expire_logs_days = 7
#log-error = /var/log/mysql/error.log
# By default we only accept connections from localhost
bind-address = 0.0.0.0
#bind-address = 192.168.1.126
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
replicate-wild-ignore-table = mysql.%
sync_binlog = 1
*因为我的图片是第二天截取的,docker重启过,导致参数不一致,在配置时填写当前状态的参数即可。
(3)进入slave容器中:
change master to master_host='192.168.1.126', master_user='root', master_password='1', master_port=3302, master_log_file='mysql-bin-master.000006', master_log_pos=126891, master_connect_retry=30;
执行上面的代码来添加master到slave中。
start slave;
开启slave模式;
show slave status \G;
查看slave状态,是否添加成功:
截图中,红色框框包含了master的一些参数,橘黄色框框yes,yes表示slave运行状态(前提是执行了slave start;),如果为no,no则slave没有运行。
下面是slave的配置文件:
[mysqld] server-id = 4 port = 3304 binlog-ignore-db= mysql pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql default-storage-engine = InnoDB log-bin = mysql-bin-slave-2 #log-error = /var/log/mysql/error.log # By default we only accept connections from localhost bind-address = 0.0.0.0 # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci binlog_cache_size = 1M binlog_format = mixed expire_logs_days = 7 slave_skip_errors = 1062 relay_log = mysql-relay-bin-2 log_slave_updates = 1 read_only = 1
4.(1)进入django项目settings.py中,添加master-slave数据库(我添加了2个slave):
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test', 'USER': 'root', 'PASSWORD': '1', 'HOST': '192.168.1.126', 'PORT': '3302', }, 'slave-1': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test', 'USER': 'root', 'PASSWORD': '1', 'HOST': '192.168.1.126', 'PORT': '3303', }, 'slave-2': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test', 'USER': 'root', 'PASSWORD': '1', 'HOST': '192.168.1.126', 'PORT': '3304', }, }
DATABASE_ROUTERS = ['ergaleng.myrouter.Router',]
(2)在settings.py同级目录下创建myrouter.py文件(需要将该文件引入到settings.py不然不能用里面的类):
class Router(object): def db_for_read(self, model, **hints): """ 读取随即一个数据库 :param model: :param hints: :return: """ try: import random print("into slave") return random.choice(['slave-1','slave-2']) except: return 'default' def db_for_write(self, model, **hints): """ 写入时选择主数据库 :param model: :param hints: :return: """ print("into default") return 'default' def allow_relation(self, obj1, obj2, **hints): return None def allow_migrate(self, db, app_label, model=None, **hints): return None
*其中,代码逻辑就是将读操作与写操作分离,当涉及到读操作时,数据库在slave-1和slave-2中随机选择,当涉及写操作时,数据库选择default (master)。
(3)进入django容器中,进行数据库表创建:
python manage.py makemigrations
python manage.py migrate #默认default
因为配置了数据库主从复制,所以在master中创建的数据会自动同步到分数据库中。
执行 python manage.py shell 进入shell中,
root@python-2:/# cd data/ root@python-2:/data# python manage.py shell Python 3.6.6 (default, Sep 5 2018, 03:40:52) [GCC 6.3.0 20170516] on linux Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from flow import models >>> models.User.objects.create(username="hello") into default <User: hello> >>> models.User.objects.all()[0] into slave <User: hehe> >>>
如上结果,说明基于Docker 的 Mysql主从架构已经设置完成。
(4)用 nginx+vue+django-restframework +uwsgi进行实际项目下的测试结果如下,橘黄色为读操作(读操作:查操作),红色框框为写操作(写操作:创建、更新、删除操作):