zoukankan      html  css  js  c++  java
  • 在Rancher中添加Mysql-Master-Slave,使得django数据库读写分离。

    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进行实际项目下的测试结果如下,橘黄色为读操作(读操作:查操作),红色框框为写操作(写操作:创建、更新、删除操作):

  • 相关阅读:
    上机小笔记
    机器人搬重物(BFS)
    排序汇总
    棋盘(BFS)
    权限控制:分配权限1
    asp.net identity 基础概念篇-理解什么是声明
    EntityFramework中几种更改数据的方式
    CodeFirst迁移时出现的中文乱码问题
    javascript Function()
    C#操作数据库(二)【操作SQL Server数据库的常用的类介绍】
  • 原文地址:https://www.cnblogs.com/BigStupid/p/9732471.html
Copyright © 2011-2022 走看看