OpenStack trove原理及配置實踐

DBaaS是什麼?  python

 

字面上理解數據庫便是服務,簡單來講就是以服務的形式爲用戶提供數據庫服務。mysql

在雲平臺上使用trove有什麼優點?  sql

 

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

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

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

 

 

 

架構解析安全

 

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。

相關文章
相關標籤/搜索