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。

相关文章
相关标签/搜索