OpenStack trove原理及配置實踐


DBaaS是什么?  

 

字面上理解數據庫即是服務,簡單來說就是以服務的形式為用戶提供數據庫服務。

在雲平台上使用trove有什么優勢?  

 

  1. 簡化IT操作流程,降低使用數據庫使用門檻舉個例子,曾經我搭建一個LAMP網站,數據庫要自己安裝,創建,授權,必要的話,還要自己做主從很繁瑣,而且不是專業人員也搞不定,有了Dbaas后,我只需要在控制台點幾下就弄好。

  2. 自動化操作,自動的增、刪、改、備。

  3. 更好的資源利用,你可以根據業務量,自由的對數據庫實例進行伸縮。

 

 

 

架構解析

 

trove和其他一些openstak組件一樣,它暴露一個public-api,通過這個api訪問trove-service,同時也保存着一些數據庫實例狀態到數據庫中。

 

組件功能

 

  • trove-api

用於操作請求的接收和分發操作提供REST風格的API,同時與trove-conductor和trove-taskmanager通信,一些輕量級的請求比如獲取實例狀態,實例數量等操作都是自身直接處理或訪問trove

conductor和trove-taskmanager處理,比較重量級的操作比如創建數據庫,創建備份等操作都是通過rpc傳遞給trove-taskmanager,taskmanager,然后在通過調用nova、swift、neutron、cinder等組件來完成操作。

  • trove-conductor

將vm內trove-guestagent發送的狀態信息保存到數據庫,與trove-guestagent的通信是通過rpc來實現的,trove-conductor這個組件的目的是為了避免創建的數據庫的實例直接訪問數據庫,它是做為一個trove-guestagent將昨天寫入數據庫的中間件。

  • trove-taskmanager

執行trove中大部分復雜的操作,請求者發送消息到task manager,task manager在請求者的上下文中調用相應的程序執行這些請求。task manager處理一些操作,包括實例的創建、刪除,與其他服務如Nova、Cinder、Swift等的交互,一些更復雜的Trove操作如復制和集群,以及對實例的整個生命周期的管理。trov-taskmanager就像是其他openstak服務的客戶端,如nova,swift,cinder等,當要創建數據庫實例時就將請求發送給nova,讓nova去創建個實例,要備份的話就調用swift接口上傳備份。

  • trove-guestagent

trove-guestagent集成在vm鏡像里面,通過監聽rpc里面task manager發過來的指令,並在本地執行代碼完成數據庫任務,taskmanager將消息發送到guest agent,guest agent通過調用相應的程序執行這些請求。

功能原理介紹(這里只介紹對mysql數據庫的功能實現,因為trove對mysql支持比較成熟

這里分別介紹三個功能的原理:

  1. 創建數據庫實例

  2. 創建數據庫備份

  3. mysql的主從

     

創建數據庫實例  

 

 

創建數據庫實例時,實際上就是通過trove-taskmanager create_instance()方法去調用nova-api,然后調用 _get_injected_files方法將guet_infotrove-guetagent.conf信息注入到 數據庫實例/etc/trove/conf.d/里面,提供給guest-agent進行后續的操作。

 

所以4.0版本的trove並不需要一開始就將trove-guestagent.conf這個配置文件封裝在鏡像里面,這個配置文件是通過nova注入的,所以鏡像只需要配置好guest-agent從哪里讀這個配置文件。剩下的就交給trove-guestagent guest_info_file這個配置文件。

 

[DEFAULT]

guest_id=7ec35639-5139-4ae4-8388-8101e41cc0f7 #這個ID是trove 分配給這個實例的ID

datastore_manager=mysql             #采用的是哪個datastore

tenant_id=f2f0e038ff0342a3bc99d8971f829ac2 #是哪個租戶的

 

當你在控制台輸入需要創建的雲硬盤的大小時,實際上是通過調用taskmanager里面的_create_volume方法:

 

收集齊上面那些信息后,然后調用nova來創建數據庫實例:

然后數據庫實例里面的guest-agent會去讀取通過nova注入的trove-guestagent.conf 去連接rpc讀取taskmanager發送過來的操作請求。

剩下的一些操作比如創建數據庫、創建用戶這些都是taskmanager調用數據庫實例里面的guest-agent去實現。

guest-agent對mysql的一些操作實現是在/usr/lib/python2.7/dist-packages/trove/guestagent/datastore/mysql/service_base.py 他里面包含了

def _get_actual_db_status() #獲取數據庫實例狀態方法

 

主要是通過調用/usr/bin/mysqladmin ping" 和ps -C mysqld h 去獲取數據庫實例狀態。

通過判斷pid文件是否存在來判斷mysql是否shutdown:

 

 

def create_database #創建數據庫實例方法:

 

def create_user #創建用戶並且授權方法:

 

 

后面還有刪除數據庫,刪除用戶,獲取binlog,開始slave、關閉slave等方法。

同時需要注意的是trove創建數據庫實例時,會默認為每個數據庫實例同時創建一個。

SecGroup-xxx xxx為主機ID的安全組。

trove默認是不啟動root用戶的所以在控制台用戶選項卡里面用戶名稱是不能填root的。

需要注意的是上述所有操作都是由trove用戶來執行,所以必須要確認的是trove用戶擁有sudo權限,否則會失敗。

在執行完上述操作前此時數據庫狀態還是building狀態的, 那就是 vm 正在啟動,創建數據庫,創建用戶,對用戶授權,同步my.cnf配置文件到數據庫實例內,重啟mysql ,trove-guestagent 發送 rpc 。

給trove-taskmanager,最后檢測數據庫成功運行后發送 Active 狀態消息給 rpc,trove-taskmanager 收到 Active 消息后,不再發送創建數據庫消息,而 trove-conductor 同時收到 trove-guestagent Active 消息后,去數據庫里更新 trove instance 的狀態,在trove list 就可以看見instance Active 的狀態了。

備份還原  

 

 

目前trove-guestagent只支持mysql的三種備份方式,一種是傳統的mysql Dump方式一種是InnoBackupEx 還有增是InnoBackup的增量備份方式InnoBackupExIncremental。

備份的程序放在/usr/lib/python2.7/dist-packages/trove/guestagent/strategies/backup。

其調用方式也比較簡單,就是trove-guestagent.conf里面配置了什么備份方式就調用指定類執行里面的方法,方法內也都是一些軟件的命令。

 

需要注意的是默認不配置是調用Innobackup,備份的日志會存在tmp目錄下,備份完成后默認是會存儲到swift內。

 

默認備份在swift內的備份文件夾為database_backups 、開啟壓縮、ssl加密,分片等。

調用SwiftStorage類里面的save方法上傳到Swift中

其中會進行文件的校驗。

是備份上去的實際上有兩個文件,第一個enc文件主要是用來分片使用,第二個文件才是主要的備份文件。

mysql主從  

 

 

trove-master端先將當前數據備份到Swift--->然后taskmanager重新創建個數據庫實例------>新創建的數據庫實例將剛剛的備份從Swift拉下來根據里面的bin-log里面的GTID進行還原---->建立主從關系---檢測創建成功taskmanager刪除上傳到Swift的備份。

備份前會做個檢測,發現以前有備份就調用增量備份的方法節省空間,檢測到沒有就調用全備的方法。

這里先做個變量定義,定義好增量備份和全備的變量:

if判斷調用全備還是增量備份。

 

 

目前trove只支持mysql的主從不支持主主並且還是異步的主從。

創建主從時,創建從同樣是調用create_instance()方法:

 

 

只是這里做了個判斷,如果傳過來了slave_of_id就調用__create_replication_slave()方法:

 

__create_replication_slave()方法會去獲去備份的ID ,然后繼續調用nova創建主機。

接下來操作會交給數據庫實例里面的guest-agent進行操作。

guest-agent會先將備份文件從來Swift 下載下來。然后還原。接下來建立主從關系,這里要說明的是trove建立主從關系的方式有兩種一種是傳統的bin-log的形式,一種的用GTID的形式。

在 /usr/lib/python2.7/dist-packages/trove/common/cfg.py

這個是定義的兩個不同的策略:

 

同時也會調用不同的方法去執行。

當你的配置文件

replication_strategy = MysqlBinlogReplication

replication_namespace = trove.guestagent.strategies.replication.mysql_binlog

調用的是

/usr/lib/python2.7/dist-packages/trove/guestagent/strategies/replication/mysql_binlog.py

replication_strategy = MysqlGTIDReplication

replication_namespace = trove.guestagent.strategies.replication.mysql_gtid

調用的是

/usr/lib/python2.7/dist-packages/trove/guestagent/strategies/replication/mysql_gtid.py

這兩個文件有何不同,方法內定義的命令不同:

 

GTID的概述:

全局事物標識:global transaction identifieds。

GTID事物是全局唯一性的,且一個事務對應一個GTID。一個GTID在一個服務器上只執行一次,避免重復執行導致數據混亂或者主從不一致。GTID用來代替classic的復制方法,不在使用binlog+pos開啟復制。而是使用master_auto_postion=1的方式自動匹配GTID斷點進行復制。MySQL-5.6.5開始支持的,MySQL-5.6.10后開始完善。在傳統的slave端,binlog是不用開啟的,但是在GTID中,slave端的binlog是必須開啟的,目的是記錄執行過的GTID(強制)。

下面介紹一下mysql GTID:

GTID的組成部分:

前面是server_uuid:后面是一個序列號

例如:server_uuid:sequence number

7800a22c-95ae-11e4-983d-080027de205a:10

UUID:每個mysql實例的唯一ID,由於會傳遞到slave,所以也可以理解為源ID。

Sequence number:在每台MySQL服務器上都是從1開始自增長的序列,一個數值對應一個事務。

GTID比傳統復制的優勢:

  • 更簡單的實現failover,不用以前那樣在需要找log_file和log_Pos。

  • 更簡單的搭建主從復制。

  • 比傳統復制更加安全。

GTID是連續沒有空洞的,因此主從庫出現數據沖突時,可以用添加空事物的方式進行跳過。

GTID的工作原理:

master更新數據時,會在事務前產生GTID,一同記錄到binlog日志中。slave端的i/o 線程將變更的binlog,寫入到本地的relay log中。sql線程從relay log中獲取GTID,然后對比slave端的binlog是否有記錄。如果有記錄,說明該GTID的事務已經執行,slave會忽略。如果沒有記錄,slave就會從relay log中執行該GTID的事務,並記錄到binlog。在解析過程中會判斷是否有主鍵,如果沒有就用二級索引,如果沒有就用全部掃描。

要點:

  1. slave在接受master的binlog時,會校驗master的GTID是否已經執行過(一個服務器只能執行一次)。

  2. 為了保證主從數據的一致性,多線程只能同時執行一個GTID。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM