1. 程式人生 > >實戰互聯網公司數據存儲解決方案

實戰互聯網公司數據存儲解決方案

學生 執行c 對數 代表性 god 用戶 技術 myisam 指定

a. 網站架構圖:2

b. 普通數據之間的同步方案:2

d. 數據庫的同步方案:2

e互聯網公司從初期到後期的數據庫架構拓展3

f. 數據庫主從復制解決的問題3

① 負載均衡 3

② 數據備份 3

③ 數據分布 3

④ 升級測試 3

g. 主從復制原理 畫圖 ,每個人必須會,面試必備:3

h. 主從同步的應用場景及切換從庫不丟數據多方案介紹5

主從復制條件9

① .3個線程,主庫IO,從庫IO和SQL及作用9

② master.info(從庫)作用9

③ .relay-log 作用9

④ 異步復制9

⑤ .binlog作用(如果需要級聯需要開啟Binlog)9

設置server-id,此處ID不可以相同否則最後出現IO錯誤

9

1 row in set (0.00 sec)11

2.5、添加新slave服務器 17

問題一:18

問題二:18

問題三:18

問題四:18

問題五:19

問題六:19

1)選擇一個不對外提供服務的從庫,這樣可以確保和主庫更新最接近,專門做數據備份用21

2)開啟從庫的binlog功能。21

a.網站架構圖:

想一想如果上面網站數據庫掛掉了,能多久恢復!你們公司數據是怎麽保障不丟失一致性的!

b.普通數據之間的同步方案:

① nfs網絡文件共享

② samba共享數據

③ 定時任務結合rsync scp

④ inotify+rsync觸發式實時數據同步

⑤ ftp數據同步

⑥ ssh key+scp/rsync

⑦ svn git版本管理

⑧ 文件級別也可以利用mysqlmongodb等軟件作為容器實現。

⑨ 程序向兩個服務器同時寫入數據,雙寫就是一個同步機制 特點:簡單、方便、效率和文件系統級別要差一點,但是同步的節點可以提供訪問。 軟件的自身同步機制(mysqloraclemongdbttserverredis.)文件放到數據庫,同步到從庫,再把文件拿出來。

⑩ DRBD文件系統級別(基於塊設備復制,直接復制block

c.

d.數據庫的同步方案:

1.自身同步機制: mysql replicationmysql主從復制(邏輯的SQL重寫)物理復制方法<===drbd

(從庫不提供讀寫) oracle dataguard(物理的磁盤塊,邏輯的SQL語句重寫)9i從庫不提供腹瀉的,11g的從庫實現了readonly

2.第三方drbd

e.互聯網公司從初期到後期的數據庫架構拓展

f.數據庫主從復制解決的問題

① 負載均衡

② 數據備份

③ 數據分布

④ 升級測試

g. 主從復制原理 畫圖 ,每個人必須會,面試必備:

mysql的主從復制是一個異步的復制過程(雖然一般情況下感覺是實時的),數據將從一個mysql數據庫(我們稱之為master)復制到另一個mysql數據庫(我們稱之為slave),在master與slave之間實現整個主從復制的過程是由三個線程參與完成的,其中有兩個線程(SQL線程和IO線程)在slave端,另外一個線程(I/O線程)在master端,要實現mysql的主從復制,首先必須打開master端的binlog記錄功能,否則就無法實現,因為整個復制過程實際上就是slave從master端獲取binlog日誌,然後在slave上以相同順序執行獲取的binlog日誌中所記錄的各種SQL操作.

背下來:

(1)master將改變記錄到二進制日誌(binary log)中(這些記錄叫做二進制日誌事件,binary log events);
(2) slavemasterbinary log events拷貝到它的中繼日誌(relay log)
(3) slave重做中繼日誌中的事件,將更改應用到自己的數據上。

詳細過程:

1)在Slave 服務器上執行sart slave命令開啟主從復制開關,開始進行主從復制。

2)此時,Slave服務器的IO線程會通過在master上已經授權的復制用戶權限請求連接master服務器,並請求從執行binlog日誌文件的指定位置(日誌文件名和位置就是在配置主從復制服務時執行change
master命令指定的)之後開始發送binlog日誌內容

3)Master服務器接收到來自Slave服務器的IO線程的請求後,其上負責復制的IO線程會根據Slave服務器的IO線程請求的信息分批讀取指定binlog日誌文件指定位置之後的binlog日誌信息,然後返回給Slave端的IO線程。返回的信息中除了binlog日誌內容外,還有在Master服務器端記錄的IO線程。返回的信息中除了binlog中的下一個指定更新位置。

4)當Slave服務器的IO線程獲取到Master服務器上IO線程發送的日誌內容、日誌文件及位置點後,會將binlog日誌內容依次寫到Slave端自身的Relay Log(即中繼日誌)文件(Mysql-relay-bin.xxx)的最末端,並將新的binlog文件名和位置記錄到master-info文件中,以便下一次讀取master端新binlog日誌時能告訴Master服務器從新binlog日誌的指定文件及位置開始讀取新的binlog日誌內容

5)Slave服務器端的SQL線程會實時檢測本地Relay Log 中IO線程新增的日誌內容,然後及時把Relay LOG 文件中的內容解析成sql語句,並在自身Slave服務器上按解析SQL語句的位置順序執行應用這樣sql語句,並在relay-log.info中記錄當前應用中繼日誌的文件名和位置點

h.主從同步的應用場景及切換從庫不丟數據多方案介紹

單向的主從復制圖,此架構只能在master端進行數據寫入(生產環境可以使用)

雙向的主主同步邏輯圖,此架構可以在master1端或master2端進行數據寫入(生產環境不建議使用)

線性級聯單向雙主同步邏輯圖,此架構只能在master1端進行數據寫入(生產環境可以使用)

環狀級聯單向多主同步邏輯圖,任意一個都可以寫入數據(生產環境不建議使用)

環狀級聯單向多主多從同步邏輯圖,此架構只能在任意一個master端進行數據寫入(生產環境不建議使用)

i.常見互聯網生產實戰大並發數據庫解決方案,根據企業業務拆分業務應用到不同的從庫思想

越是想玩牛b的架構,維護起來越難。維護成本越高, 所以95%的公司都是一主,宕機後手工提升一臺從電腦為主,因為80%都是讀多寫少,主庫做好監控,即使宕機也不會影響到什麽

j.主從復制的小結:

    1. 主從復制是異步的邏輯的SQL語句級的復制
    2. 復制時,主庫有一個I/O線程,從庫有兩個線程,I/O和SQL線程
    3. 實現主從復制的必要條件是主庫要開啟記錄binlog功能
    4. 作為復制的所有Mysql節點的server-id都不能相同
    5. binlog文件只記錄對數據庫有更改的SQL語句(來自主庫內容的變更),不記錄任何查詢(selectshow)語句

k.主從復制實戰演示:

主從復制條件

1、開啟Binlog功能

2、主庫要建立賬號

3、從庫要配置master.info(CHANGE MASTER to...相當於配置密碼文件和Master的相關信息)

4start slave 開啟復制功能

主要必須記住掌握理解的知識點:

① .3個線程,主庫IO,從庫IOSQL及作用

② master.info(從庫)作用

③ .relay-log 作用

④ 異步復制

⑤ .binlog作用(如果需要級聯需要開啟Binlog

l.實戰案例一:企業剛安裝好的數據庫進行單向的主從復制圖,此架構只能在master端進行數據寫入(小企業裏生產環境最常用的情況

實驗拓撲:

在備庫上做備份,這樣減輕數據庫服務壓力

主庫配置:vim /etc/my.cnf

Log-bin=mysql-bin //打開二進制日誌

Server-id=40 //配置servere id 通常建議大家使用ip地址最後一位來作為id號,這樣便於維護和管理

設置server-id,此處ID不可以相同否則最後出現IO錯誤

/etc/init.d/mysqld start //重啟mysql進程

Mysql> reset master; //清空掉所有二進制日誌,讓數據庫回到初始化狀態

Mysql>grant replication slave,replication client on *.* to rep1@172.16.10.% identified by ‘123’;

Mysql> flush privileges;

show master status;

備庫配置:vim /etc/my.cnf

Server-id=60

Mysql>change master to master_host=’172.16.10.40’, #這是主庫的IP(域名也可以需要做解析) master_user=’rep1’, #這是主庫上創建用來復制的用戶rep1 master_password=’123’, #rep的密碼

master_log_file=’mysql-bin.000001’,#這裏是show master status時看到的查詢二進制日誌文件名稱,這裏不能多空格

master_log_pos=0; #這裏是show master status時看到的二進制日誌偏移量,不能多空格

Mysql>Start slave;

查看主從復制狀態

Mysql>show slave status\G

mysql> show slave status\G

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 172.16.10.40

Master_User: rep1

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 349

Relay_Log_File: localhost-relay-bin.000002

Relay_Log_Pos: 495

Relay_Master_Log_File: mysql-bin.000001

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Replicate_Do_DB:

Replicate_Ignore_DB:

Replicate_Do_Table:

Replicate_Ignore_Table:

Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

Last_Errno: 0

Last_Error:

Skip_Counter: 0

Exec_Master_Log_Pos: 349

Relay_Log_Space: 655

Until_Condition: None

Until_Log_File:

Until_Log_Pos: 0

Master_SSL_Allowed: No

Master_SSL_CA_File:

Master_SSL_CA_Path:

Master_SSL_Cert:

Master_SSL_Cipher:

Master_SSL_Key:

Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

Last_IO_Errno: 0

Last_IO_Error:

Last_SQL_Errno: 0

Last_SQL_Error:

Replicate_Ignore_Server_Ids:

Master_Server_Id: 40

1 row in set (0.00 sec)

mysql>

在這裏主要是看:

Slave_IO_Running:Yes,這是I/O線程狀態,I/O線程負載從從庫去主庫讀取binlog日誌,並寫入從庫的中繼日誌中,狀態為Yes表示I/O線程工作正常。

Slave_SQL_Running:Yes 這個是SQL線程狀態,SQL線程負載讀取中繼日誌(relay-log)中的數據並轉換為SQL語句應用到從庫數據庫中,狀態為Yes表示I/O線程工作正常

Seconds_Behind_Master:0 這個是在復制過程中,從庫比主庫延遲的描述,這個參數很重要,但企業裏更準確地判斷主從延遲的方法為:在主庫寫時間戳,然後從庫讀取時間戳進行比較,從而認定是否延遲。

slaveI/OSQL線程都已經開始運行,而且Seconds_Behind_Master不再是NULL。日誌的位置增加了,意味著一些事件被獲取並執行了。如果你在master上進行修改,你可以在slave上看到各種日誌文件的位置的變化,同樣,你也可以看到數據庫中數據的變化。

你可查看masterslave上線程的狀態。在master上,你可以看到slaveI/O線程創建的

查看連接的線程,每一個線程代表一個從庫連接: show processlist\G

2為處理slaveI/O線程的連接。

測試結果:

在主庫上創建數據庫表插入數據,然後看看從庫是否同步:

查看數據庫show databases

創建數據庫create database Myschool;

實例創建學生信息表

Create table stu(

Stunum varchar(6),

Stuname varchar(20),

Stuage tinyint(2),

);

insert into stu values(‘001‘,‘luliechu‘,‘18‘);

m.從庫提升主庫步驟

mysql主從復制中,需要將備庫(從庫)提升為主庫,需要取消其從庫角色,可以通過執行以下命令:

① stop slave;

② reset slave all;

③ RESET SLAVE ALL是清除從庫的同步復制信息,包括連接信息和二進制文件名、位置

④ 從庫上執行這個命令後,使用show slave status將不會有輸出

n.實戰案例二: 運行一段時間後有數據的數據庫之間進行復制,采用級聯方式(並發量業務量大的互聯網公司解決方案)

實驗拓撲

因為主庫和分發主庫已經運行了一段時間,有大量的數據存在,所以在這種情況下,對於新加入的從庫172.16.10.70,必須要做的是先把主庫數據同步到新從庫哪裏,然後再到分發庫裏同步二進制日誌到從庫

主庫配置:vim /etc/my.cnf

Log-bin=mysql-bin //打開二進制日誌

Server-id=40

Service mysqld start //重啟mysql進程

Mysql> reset master;

Mysql>grant replication slave,replication client on *.* to rep1@172.16.10.% identified by ‘123’;

Mysql> flush privileges;

分發庫配置:vim /etc/my.cnf

Log-bin=mysql-bin //打開二進制日誌

Server-id=60

Relay_log=mysql_relay-bin

Log_slave_updates=1

Read_only=1 ead-only參數選項可以讓從服務器只允許來自服務器線程或具有SUPER權限的數據庫用戶進行更新,可以確保從服務器不接受來自用戶端的非法用戶更新。

read-only參數具有允許數據庫更新的條件為:

具有SUPER權限的用戶可以更新,不受read-only參數影響,例如:管理員root

來自從服務器線程可以更新,不受read-only參數影響,例如:rep用戶

在生產環境中,可以在從庫Slave中使用read-only參數,確保從庫數據不被非法更新。

Service mysqld start //重啟mysql進程

Mysql> reset master; //清空掉所有二進制日誌,讓數據庫回到數據化狀態

Mysql>change master to master_host=’172.16.10.40’, master_user=’rep1’, master_password=’tianyun’, master_log_file=’mysql-bin.000001’, master_log_pos=0;

Mysql>Start slave;

註意事項:我這種配置是給他作為一個分發主庫來做的,但是它開啟二進制日誌其實也沒有用的,這個日誌並不是它自身的

初始化備庫(使其和當前主庫數據一致)

在這種操作情況下需要同時開兩個窗口,先鎖表,然後另一個窗口進行備份和查看二進制日誌,等這兩部看到操作完成後,再把表解鎖

分發Master上配置:

Mysql>flush tables with read lock; 一邊窗口

另外一邊窗口# mysqldump -uroot -p"123" --lock-all-tables --all-databases>all.sql #mysql -e ‘show master status’

# mysql -u root -p123 -e ‘show master status‘

操作完之後可以回到另一邊窗口過來解鎖,使其可以工作了

Mysql>unlock tables;

將完備下來的數據庫文件拷到從庫2

#rsync -av all.sql 172.16.10.70:/

在從庫2上操作

Slave2:

Mysql>source /all.sql

mysql> quit;

# /etc/init.d/mysqld stop

Shutting down MySQL. SUCCESS!

vim /etc/my.cnf

從庫2的配置:

vim /etc/my.cnf

Server-id=70

Read_only=1

Service mysqld start //重啟mysql進程

Mysql> reset master;

mysql> change master to master_host=‘172.16.10.60‘, master_user=‘rep1‘, master_password=‘123‘, master_log_file=‘mysql-bin.000001‘, master_log_pos=1432;

註意事項:master_log_file=‘mysql-bin.000001‘, master_log_pos=1432;

這兩個東西絕對不是亂填的,而是剛才分發庫上查到的,非常重要,否則會出大問題!

mysql> start slave;

Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 172.16.10.60

Master_User: rep1

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 1432

Relay_Log_File: localhost-relay-bin.000002

Relay_Log_Pos: 253

Relay_Master_Log_File: mysql-bin.000001

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

可以看到已經成功萬無一失了。

測試,在主庫上做數據庫的增刪改,看看另外兩臺數據庫數據是否同步一致:

不想敲sql語句的可以利用數據庫圖形化工具操作,我這裏為了方便快速測試,用它在主庫40上創建了數據庫和表以及插入了數據

查看其它兩臺是否同步:

----------------------------------------------很明顯數據完全一致,整個實驗成功完成--------------------------

小結:

為了開始復制,你可以運行:

mysql> START SLAVE;

運行SHOW SLAVE STATUS查看輸出結果:

slave服務器上運行該語句:

mysql> show processlist \G

2.5、添加新slave服務器

假如master已經運行很久了,想對新安裝的slave進行數據同步,甚至它沒有master的數據。

此時,有幾種方法可以使slave從另一個服務開始,例如,從master拷貝數據,從另一個slave克隆,從最近的備份開始一個slaveSlavemaster同步時,需要三樣東西:

(1)master的某個時刻的數據快照;

(2)master當前的日誌文件、以及生成快照時的字節偏移。這兩個值可以叫做日誌文件坐標(log file coordinate),因為它們確定了一個二進制日誌的位置,你可以用SHOW MASTER STATUS命令找到日誌文件的坐標;

(3)master的二進制日誌文件。

可以通過以下幾中方法來克隆一個slave

(1) 冷拷貝(cold copy)

停止master,將master的文件拷貝到slave;然後重啟master。缺點很明顯。

(2) 熱拷貝(warm copy)

如果你僅使用MyISAM表,你可以使用mysqlhotcopy拷貝,即使服務器正在運行。

(3) 使用mysqldump

使用mysqldump來得到一個數據快照可分為以下幾步:

<1>鎖表:如果你還沒有鎖表,你應該對表加鎖,防止其它連接修改數據庫,否則,你得到的數據可以是不一致的。如下:

mysql> FLUSH TABLES WITH READ LOCK;

<2>在另一個連接用mysqldump創建一個你想進行復制的數據庫的轉儲:

shell> mysqldump --all-databases --lock-all-tables >dbdump.db

<3>對表釋放鎖。

mysql> UNLOCK TABLES;

  • o.Mysql主從復制延遲問題原因及解決方法

問題一:

一個主庫的從庫太多,導致復制延遲。

建議從庫數量3-5 為宜,要復制的從節點數量過多,會導致復制延遲

問題二:

從庫硬件比主庫差,導致復制延遲

查看masterslave的系統配置,可能會因為機器配置的問題,包括磁盤IOCPU、內存等各方面因素造成復制的延遲,一般發生在高並發大數據量寫入場景。

問題三:

SQL語句過多

假如一條SQL語句,執行時間是20秒,那麽從庫執行完畢,到從庫上能查到數據也至少是20秒,這樣就延遲20秒了

SQL語句的優化一般要作為常規工作不斷的監控和優化,如果是單個SQL的寫入時間長,可以修改後分多次寫入,通過查看慢查詢日誌或show full processlist 命令找出執行時間長的查詢語句或者打的事務。

問題四:

主從復制的設計問題

例如,主從復制單線程,因為主庫寫並發太大,來不及傳送到從庫就會導致延遲。

更高版本的MySQL可以支持多線程復制,門戶網站會開發自己多線程同步功能。

問題五:

主從庫之間的網絡延遲。

主庫的網卡、網線、連接的交換機等網絡設備都可能成為復制的瓶頸,導致復制延遲,另外,跨公網主從復制很容易導致主庫復制延遲

問題六:

主庫讀寫壓力大,導致復制延遲

主庫硬件要搞好一點,架構的前端要加buffer以及緩存層。

通過read-only參數讓從庫只讀訪問

read-only參數選項可以讓從服務器只允許來自服務器線程或具有SUPER權限的數據庫用戶進行更新,可以確保從服務器不接受來自用戶端的非法用戶更新。

read-only參數具有允許數據庫更新的條件為:

具有SUPER權限的用戶可以更新,不受read-only參數影響,例如:管理員root

來自從服務器線程可以更新,不受read-only參數影響,例如:rep用戶

在生產環境中,可以在從庫Slave中使用read-only參數,確保從庫數據不被非法更新。

p.查看二進制日誌:

[root@localhost ~]# mysqlbinlog mysql-bin.000001

q.Web用戶專業設置方案:MySQL主從復制讀寫分離集群

專業的運維人員提供給開發人員的讀寫分離的賬戶設置如下:

1)訪問主庫和從庫時使用一套用戶密碼,例如,用戶名:web,密碼:123456

2)即使訪問IP不同,端口也盡量相同(3306)。例如:寫庫VIP10.0.0.1 ,讀庫VIP10.0.0.2

除了IP沒辦法修改之外,要盡量為開發人員提供方便,如果數據庫前端有DAL層(DBPROXY代理)還可以只給開發人員一套用戶、密碼、IP、端口,這樣就更專業了,剩下的都是由運維搞定。

給開發授權權限

方法1:主庫和從庫使用不同的用戶,授權不同的權限。

主庫上對web_w用戶授權如下:

用戶:web_w 密碼:123456 端口3306 主庫VIP10.0.0.1

權限:SELECT,INSERT,UPDATE,DELETE

命令:GRANT SELECT,INSERT,UPDATE,DELETE ON wen.* to ‘web_w‘@10.0.0.% identified by ‘123456‘;

從庫對web_r用戶授權如下:

用戶:web_r 密碼:123456 端口:3306 從庫VIP10.0.0.2

權限:SELECT

命令:GRANT SELECT ON web.* TO [email protected].% identfied by ‘123456‘;

提示:此方法顯得不夠專業,但是可以滿發開發需求。

方法2:主庫和從庫使用相同的用戶,但授予不同的權限。(由於主從同步 有一些可能無法同步)

主庫上對web用戶授權如下:

用戶:web 密碼:123456 端口:3306 主庫VIP10.0.0.1

權限:SELECT,INSERT,UPDATE,DELETE

命令:GRANT SELECT,INSERT,UPDATE,DELETE ON web.* TO [email protected].% identified by ‘123456‘;

從庫上對web用戶授權如下:

用戶:web 密碼:123456 端口:3306 從庫VIP10.0.0.2

權限:SELECT

#由於主庫和從庫是同步復制的,所以從庫上的Web用戶會自動和主庫一直,既無法實現只讀select的權限

方法3:在從庫上設置read-only參數,讓從庫只讀

主庫和從庫:主庫和從庫使用相同的用戶,授予相同的權限(非ALL權限)推薦做法,我在公司就是這麽幹的

用戶:web 密碼:123546 端口:3306 主庫VIP:10.0.0.8

權限:SELECT,INSERT,UPDATE,DELETE

命令:GRANT SELECT,INSERT,UPDATE,DELETE ON web.* to [email protected].% identified by ‘123546‘;

由於從庫設置了read-only,非super權限是無法寫入的,因為通過read-only參數就可以

忽略授權庫Mysql同步,主庫配置參數如下:

binlog-ignore-db = mysql

replicate-ignore-db = mysql

r.MySQL主從復制集群架構的數據備份策略

有了主從復制,還需要做定時全量備份 因為,如果主庫有語句誤操作(例如:drop database oldboy;)從庫也會執行drop,這樣MySQL從庫就都刪除了該數據。

把從庫作為數據備份服務器時,備份策略如下:

高並發業務場景備份時,可以選擇在一臺從庫上備份(Slave)把從庫作為數據備份服務器時需要在從庫binlog功能。

1)選擇一個不對外提供服務的從庫,這樣可以確保和主庫更新最接近,專門做數據備份用

2)開啟從庫的binlog功能。

備份時可以選擇只停止SQL線程,停止應用SQL語句到數據庫,I/O線程保留工作狀態,執行命令為stop slave sql_thread;備份方式可以采取mysqldump邏輯備份或者直接物理備份,例如使用cptar(針對目錄)工具,或xtrabackup(第三方的物理備份軟件)進行備份,邏輯備份和物理備份的選擇,一般是根據總的備份數據量的多少進行選擇,數據庫低於20G,建議選擇mysqldump邏輯備份方法,安全穩定,最後把全量和binlog數據發送到備份服務器上留存。

Mysql讀寫分離實現水平擴展:做這個之間必須要做好主從復制才行

s.解決大並發解決方案Mysql讀寫分離技術

方法一:基於程序代碼內部實現:這類方法是目前生產環境中應用最廣泛的,我們公司是程序員來實現的

在代碼中根據insertselect進行選擇分類,這類方法是目前生產環境中應用最廣泛的

優點:性能好,因為在程序代碼中實現,不需要增加額外的設備作為硬件支持,缺點是需要開發人員來實現,運維人員無從下手

方法二:基於中間代理層實現 運維人員主要學習這個

代理一般是位於客戶端和服務器之間,代理服務器接到客戶端請求後通過判斷然後轉發到後端數據庫,目前主要有兩個代表性程序

Mysql_proxy:mysql開源項目,通過其自帶的lua腳本進行sql判斷

Amoeba:由陳思儒開發,作者就職於阿裏巴巴,該程序由java進行開發 這個使用比較多

t.生產管理核心思想:

實戰互聯網公司數據存儲解決方案