Python开发之:Django基于Docker实现Mysql数据库读写分离、集群、主从同步详解 | 原力计划...
作者 | Pythonicc
責編 | 王曉曼
出品 | CSDN博客
簡介
1、什么是數據庫讀寫分離
讀寫分離,基本的原理是讓主數據庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從數據庫處理SELECT查詢操作。數據庫復制被用來把事務性操作導致的變更同步到集群中的從數據庫。
2、為什么要搞數據庫讀寫分離
在實際的生產環境中,對數據庫的讀和寫都在同一個數據庫服務器中,是不能滿足實際需求的。無論是在安全性、高可用性還是高并發等各個方面都是完全不能滿足實際需求的。因此,通過主從復制的方式來同步數據,再通過讀寫分離來提升數據庫的并發負載能力。
3、配置主從同步的基本步驟
有很多種配置主從同步的方法,可以總結為如下的步驟:
在主服務器上,必須開啟二進制日志機制和配置一個獨立的ID
在每一個從服務器上,配置一個唯一的ID,創建一個用來專門復制主服務器數據的賬號
在開始復制進程前,在主服務器上記錄二進制文件的位置信息
如果在開始復制之前,數據庫中已經有數據,就必須先創建一個數據快照(可以使用mysqldump 導出數據庫,或者直接復制數據文件)
配置從服務器要連接的主服務器的IP地址和登陸授權,二進制日志文件名和位置
實踐階段
1、測試環境
Mysql5.7.29主服務器:ubuntu16
Mysql5.7.29從服務器:ubuntu16上的docker容器
WEB框架:Django1.8
2、docker容器安裝(若在不同服務器搭建數據庫,此步可省略)
docker三個核心概念: Repository(倉庫) -> Image(鏡像) -> Container(容器)
卸載可能存在的舊版本
sudo?apt-get?remove?docker?docker-engine?docker-ce?docker.io更新apt包
sudo?apt-get?update安裝以下包以使apt可以通過HTTPS使用存儲庫(repository):
sudo?apt-get?install?-y?apt-transport-https?ca-certificates?curl?software-properties-common添加GPG密鑰
curl?-fsSL?https://download.docker.com/linux/ubuntu/gpg?|?sudo?apt-key?add?-設置stable存儲庫
sudo?add-apt-repository?"deb?[arch=amd64]?https://download.docker.com/linux/ubuntu?$(lsb_release?-cs)?stable"再次更新apt包
sudo?apt-get?update安裝最新版本的Docker CE(社區免費版)
sudo?apt-get?install?-y?docker-ce驗證docker: sudo docker version 或 sudo dockerinfo
查看docker服務是否啟動
systemctl?status?docker經典的Hello world
運行 docker 命令時需要 root 權限或者加 sudo
sudodocker pull hello-world拉取dockerHub上的hello-world鏡像
sudodocker images查看鏡像信息
可以看到已存在hello-world鏡像
**字段解釋**REPOSITORY:?來自于哪個倉庫;TAG:?鏡像的標簽信息,比如?5.7、latest?表示不同的版本信息;IMAGE?ID:?鏡像的?ID,?如果您看到兩個?ID?完全相同,那么實際上,它們指向的是同一個鏡像,只是標簽名稱不同罷了;CREATED:?鏡像最后的更新時間;SIZE:?鏡像的大小,優秀的鏡像一般體積都比較小生成該鏡像的實例容器(鏡像與容器的關系就像類和實例類對象)
sudo?docker?run?hello-world有以上輸出,表示docker安裝成功。
Docker服務相關命令
1、開啟Docker服務
systemctlstart docker
2、停止Docker服務
systemctlstop docker
3、重啟Docker服務
systemctlrestart docker
4、開機自啟Docker服務
systemctlenable docker
創建Mysql容器
1、家目錄下創建mysql_slave目錄作為容器掛載數據卷。
mkdirmysql_slave
2、進入mysql_slave目錄
cdmysql_slave
3、創建data目錄
mkdirdata
4、將宿主機的mysql配置文件目錄拷到當前數據卷目錄下
cp-a /etc/mysql/mysql.conf.d ./
5、將配置文件拷貝過來后,編輯mysql.conf.d目錄下的mysqld.cnf 文件
6、宿主機中的mysql做為主服務器,其server-id設為1,從服務器只要不是1都行,這邊取2
server-id= 2
7、創建容器(如果沒有該鏡像,則自動從dockerHub拉取該鏡像并創建容器)
dockerrun -id
-p3308:3306
–name=mysql-slave
-eMYSQL_ROOT_PASSWORD=mysql
-v/root/mysql_slave/data:/var/lib/mysql
-v/root/mysql_slave/mysql.conf.d:/etc/mysql/mysql.conf.d
mysql:5.7.29
8、參數解釋:
-p 指定映射的端口,左邊為宿主機端口,右邊為容器端口,這樣就可以通過映射的3308端口在宿主機以外的外部機器訪問該容器中的mysql
-id表示該容器作為守護進程在后臺運行,創建后馬上運行,但是不會進入shell終端,退出后也不會真正退出
–name 指定實例容器的名稱
-e 指定數據庫密碼
-v 指定要掛載的目錄或文件,必須寫絕對路徑,左邊為宿主機路徑,右邊為容器路徑
mysql:5.7.29指定要創建的容器的鏡像及其版本,由于宿主機中mysql是5.7.29版本,所以我們這里創建mysql5.7.29的容器
查看運行中的容器
docker?psMysql主從同步配置
宿主機中導出mysql主服務器sql文件
mysqldump-uroot -pmysql --all-databases --lock-all-tables > ~/master_db.sql
參數解釋:
-u :用戶名
-p :示密碼
–all-databases :導出所有數據庫
–lock-all-tables :執行操作時鎖住所有表,防止操作時有數據修改
~/master_db.sql:導出的備份數據(sql文件)位置,可自己指定
在宿主機中根據映射的端口將sql文件導入容器數據庫中
mysql?-uroot?-pmysql?-h127.0.0.1?--port=3308?<?~/master_db.sql編輯設置mysqld的配置文件,設置log_bin和server-id
sudo?vim?/etc/mysql/mysql.conf.d/mysqld.cnf重啟mysql服務
sudo?service?mysql?restart登入mysql,創建用于從服務器同步數據使用的帳號并刷新緩存
mysql?–uroot?–pmysqlGRANT?REPLICATION?SLAVE?ON?*.*?TO?'slave'@'%'?identified?by?'slave';FLUSH?PRIVILEGES;獲取主服務器的二進制日志信息(File為使用的日志文件名字,Position為使用的文件位置,這兩個參數須記下,配置從服務器時會用到)
SHOW?MASTER?STATUS;進入docker容器配置mysql從服務器
執行以下命令進入指定名稱的容器的shell終端
docker?exec?-it?mysql-slave?bash進入容器中的mysql數據庫并設置連接到master主服務器
mysql?-uroot?-pmysql change?master?to?master_host='192.168.254.137',?master_user='slave',?master_password='slave',master_log_file='mysql-bin.000001',?master_log_pos=590;參數解釋:
master_host:主服務器宿主機Ubuntu的ip地址
master_log_file:前面查詢到的主服務器日志文件名
master_log_pos:前面查詢到的主服務器日志文件位置
開啟同步,查看同步狀態
Django項目搭建
1、項目創建
django-admin?startproject?test22、應用創建
python?manage.py?startapp?booktest3、模板定義
為應用booktest下的視圖index創建模板index.html,目錄結構如下圖:
打開templtes/booktest/index.html文件,定義代碼如下:
<html> <head><title>案例</title> </head> <body> <a?href="/create/">創建</a> <ul> {%for?book?in?list%}<li>{{book.btitle}}--<a?href="/delete{{book.id}}/">刪除</a></li> {%endfor%} </ul> </body> </html>4、編輯設置文件
添加應用名稱
定義模板文件路徑
注釋原有的sqlite連接配置,寫入如下代碼:
DATABASES?=?{'default':?{'ENGINE':?'django.db.backends.mysql','NAME':?'test2',??#?數據庫名字,'USER':?'root',??#?數據庫登錄用戶名'PASSWORD':?'mysql',??#?數據庫登錄密碼'HOST':?'192.168.254.137',??#?數據庫所在主機'PORT':?'3306',??#?數據庫端口},'slave':?{'ENGINE':?'django.db.backends.mysql','NAME':?'test2',??#?數據庫名字,'USER':?'root',??#?數據庫登錄用戶名'PASSWORD':?'mysql',??#?數據庫登錄密碼'HOST':?'192.168.254.137',??#?數據庫所在主機'PORT':?'3308',??#?數據庫端口}, }5、模型類編寫
打開booktest/models.py文件,定義模型類源碼如下
from?django.db?import?models#?定義圖書模型類BookInfo class?BookInfo(models.Model):btitle?=?models.CharField(max_length=20)??#?圖書名稱bpub_date?=?models.DateField()??#?發布日期bread?=?models.IntegerField(default=0)??#?閱讀量bcomment?=?models.IntegerField(default=0)??#?評論量isDelete?=?models.BooleanField(default=False)??#?邏輯刪除#?定義英雄模型類HeroInfo class?HeroInfo(models.Model):hname?=?models.CharField(max_length=20)??#?英雄姓名hgender?=?models.BooleanField(default=True)??#?英雄性別isDelete?=?models.BooleanField(default=False)??#?邏輯刪除hcomment?=?models.CharField(max_length=200)??#?英雄描述信息hbook?=?models.ForeignKey('BookInfo')??#?英雄與圖書表的關系為一對多,所以屬性定義在英雄模型類中6、遷移
安裝pymysql pip?install?pymysql安裝成功之后,在test2/_init_.py文件中加上如下代碼: import?pymysql pymysql.install_as_MySQLdb()生成遷移文件 python?manage.py?makemigrations執行遷移文件在數據庫生成表 python?manage.py?migrate打開數據庫的命令行,查看當前所有表如下圖:
7、測試數據
在數據庫命令行中,復制如下語句執行,向booktest_bookinfo表中插入測試數據:
insert?into?booktest_bookinfo(btitle,bpub_date,bread,bcomment,isDelete)?values ('射雕英雄傳','1980-5-1',12,34,0), ('天龍八部','1986-7-24',36,40,0), ('笑傲江湖','1995-12-24',20,80,0), ('雪山飛狐','1987-11-11',58,24,0);再復制如下語句執行,向booktest_heroinfo表中插入測試數據:
insert?into?booktest_heroinfo(hname,hgender,hbook_id,hcomment,isDelete)?values ('郭靖',1,1,'降龍十八掌',0), ('黃蓉',0,1,'打狗棍法',0), ('黃藥師',1,1,'彈指神通',0), ('歐陽鋒',1,1,'蛤蟆功',0), ('梅超風',0,1,'九陰白骨爪',0), ('喬峰',1,2,'降龍十八掌',0), ('段譽',1,2,'六脈神劍',0), ('虛竹',1,2,'天山六陽掌',0), ('王語嫣',0,2,'神仙姐姐',0), ('令狐沖',1,3,'獨孤九劍',0), ('任盈盈',0,3,'彈琴',0), ('岳不群',1,3,'華山劍法',0), ('東方不敗',0,3,'葵花寶典',0), ('胡斐',1,4,'胡家刀法',0), ('苗若蘭',0,4,'黃衣',0), ('程靈素',0,4,'醫術',0), ('袁紫衣',0,4,'六合拳',0);8、視圖編寫
打開booktest/views.py文件,定義視圖代碼如下:
from?django.shortcuts?import?render,redirect from?booktest.models?import?* from?datetime?import?date#查詢所有圖書并顯示 def?index(request):#使用從服務器進行讀操作list=BookInfo.objects.using('slave').all()return?render(request,'booktest/index.html',{'list':list})#默認使用主服務器進行寫操作 #創建新圖書 def?create(request):book=BookInfo()book.btitle?=?'流星蝴蝶劍'book.bpub_date?=?date(1995,12,30)book.save()#轉向到首頁return?redirect('/')#邏輯刪除指定編號的圖書 def?delete(request,id):book=BookInfo.objects.get(id=int(id))book.delete()#轉向到首頁return?redirect('/')9、url路由配置
打開test2/urls.py文件,配置url如下:
from?django.conf.urls?import?include,?url from?django.contrib?import?adminurlpatterns?=?[url(r'^admin/',?include(admin.site.urls)),#引入booktest的url配置url(r'^',include('booktest.urls')), ]在booktest應用下創建urls.py文件,代碼如下:
from?django.conf.urls?import?url from?booktest?import?viewsurlpatterns=[url(r'^$',views.index),url(r'^delete(\d+)/$',views.delete),url(r'^create/$',views.create), ]10、運行
python?manage.py?runserver?127.0.0.1html界面中點擊創建或刪除后,由主服務器執行寫操作,由從服務器同步主服務器數據執行讀操作,可以看到渲染的數據在增加或減少
版權聲明:本文為CSDN博主「Pythonicc」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Pythonicc/article/details/105072170
?
推薦閱讀
實操來了!一文告訴你如何用 Streamlit 和 Heroku 開發 Web
避坑!使用 Kubernetes 最易犯的 10 個錯誤
雷軍:4G 手機已清倉,全力轉 5G;QQ音樂播放中途插語音廣告引熱議;Wine 5.9 發布 | 極客頭條
15 歲黑進系統,發挑釁郵件意外獲 Offer,不惑之年捐出全部財產,Twitter CEO 太牛了!
必讀!53個Python經典面試題詳解
贈書 | 1月以來 Tether 增發47億 USDT,美元都去哪兒了?
總結
以上是生活随笔為你收集整理的Python开发之:Django基于Docker实现Mysql数据库读写分离、集群、主从同步详解 | 原力计划...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解析云原生与云计算本质区别,别再傻傻分不
- 下一篇: Docker容器资源管理,你真的学会了吗