OpenStack数据库服务Trove。

Trove的设计目标

Trove is Database as a Service for OpenStack. It’s designed to run entirely on OpenStack, with the goal of allowing users to quickly and easily utilize the features of a relational or non-relational database without the burden of handling complex administrative tasks. 

这是Trove在官方首页上对这个项目的说明,有两个关键点:

  • 一是从产品设计上说,它定位不仅仅是关系型数据库,而且还涵盖非关系数据库的服务。
  • 二是从产品实现上说,它是完全基于Openstack的。

Trove的架构介绍

实际上Trove的架构(最新版本)与Openstack Nova项目的架构是如出一辙,可以说是Nova的一个简化版。也是典型的Openstack项目架构风格。Trove所管理的各个数据库引擎的差异性主要体现在trove-guestagent的具体manager和strategies代码实现上。架构如图所示:

trove-api是接入层,轻量级请求通过在接入层直接处理或者通过直接访问guestagent处理,比如获取实例列表、获取实例规格列表等;而比较重的请求则通过message bus(Openstack默认实现是Rabbitmq)中转给trove-taskmanager进行调度处理。trove-taskmanager是调度处理层,主要是处理较重的请求,比如创建实例、实例resize等。

taskmanager会通过Nova、Swift的API访问Openstack基础的服务,而且是有状态的,是整个系统的核心。trove-conductor是guestagent访问数据库的代理层,主要是为了屏蔽掉guestagent直接对数据库的访问。

在Trove目前的实现中,一个数据库实例一一对映到一个vm,而guestagent也是运行在vm里面。vm镜像包含了经过裁剪的操作系统、数据库引擎和guestagent(镜像具体实现没有标准,数据库引擎和guestagent也都可以在vm启动时通过网络动态装载)。而实例所在分区的硬盘是通过Cinder提供的云硬盘。每个vm都会关联一个安全组防火墙,只允许数据库服务的端口通过(比如Mysql,默认是TCP 3306端口)。从这里可以看出,Trove创建数据库实例是非常灵活的,后期的调度也非常方便,这些都得益于Nova和Cinder。

Trove功能介绍

正如前面说的,实际上Trove是在主流的关系和非关系型数据库的一些核心概念基础上抽象出的一个系统框架,所以其实现的功能也是围绕着这些核心概念的。Trove的概念关系图:

因此Trove的主要功能也是围绕这几个概念实现的。datastore管理,Instance管理,configuration管理,database管理,user管理,replication管理,backup管理,cluster管理等等。

从最新的Liberty版本看,目前Trove的功能还是比较多的,而且扩展性很强。可惜的是实例统计监控功能却没有看到,而统计监控功能的缺失,应该也是导致了实例容灾的自动切换还没有实现,相信这些都会在不久的新版本中逐渐完善。不过从另外一个角度看,由于数据库对用户来说是非常关键的服务,涉及到核心数据的数据一致性问题,目前交由用户上层去确认和切换实例也不失一个明智的选择。下面以Mysql数据库作为例子,对Trove的一些重要功能进行分析。

1、动态resize能力

分为instance-resize和volume-resize,前者主要是实例运行的内存大小和cpu核数,后者主要是指数据库分区对应的硬盘卷的大小。由于实例是跑在vm上的,而vm的cpu和memory的规格可以通过Nova来进行动态调整,所以调整是非常方便快捷的。另外硬盘卷也是由Cinder提供的动态扩展功能来实现resize。resize过程中服务会有短暂的中断,是由于mysqld重启导致的。

2、全量与增量备份

目前mysql的实现中,备份是由实例vm上的guestagent运行xtrabackup工具进行备份,且备份后的文件会存储在Swift对象存储中。从备份创建实例的过程则相反。由于xtrabackup强大的备份功能,所以Trove要做的只是做一些粘胶水的工作。

3、动态配置更新

目前支持实例的自定义配置,可以创建配置组应该到一组实例上,且动态attach到运行中的实例中生效。

4、一主多从的一键创建

在创建数据库实例的API中,支持批量创建多个从实例,并以指定的实例做主进行同步复制。这样就方便了从一个已有实例创建多个从实例的操作。而且mysql5.6版本之后的同步复制支持GTID二进制日志,使得主从实例之间关系的建立更加可靠和灵活,在failover处理上也更加快速。

5、集群创建与管理(percona/mariadb支持)

Cluster功能目前在mysql原生版本暂时不支持,但是其两个分支版本percona和mariadb基于Galera库实现的集群复制技术是支持的。另外Liberty版本的Trove也提供了对mongodb的集群支持。

在控制节点上安装trove

1、预安装软件

yum insall epel-release -y
yum install python-virtualenv git screen -y
# 安装过程中会用到gcc
yum install gcc -y
# trove的安装中,pycrypto没有安装,需要手动安装,否则会报no modules
pip install pycrypto wrapt==1.10.8

2、编辑/etc/pip.conf

[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com

3、创建用户

useradd -m a

4、初始环境

su - a
virtualenv ven/bin/activate
pip install pip --upgrade

5、下载并安装trove

git clone https://github.com/openstack/trove.git
cd trove
git checkout stable/newton
pip install -r requirements.txt
# 如果使用python setup.py develop将不会安装trove时python的path,使用作一个指向
# python setup.py develop
python setup.py install

6、创建数据库

mysql -hmariadb_host -uroot -p 
CREATE DATABASE trove;
GRANT ALL PRIVILEGES ON trove.* TO 'trove'@'%' IDENTIFIED BY '123456';

7、创建trove的user,endpoint

# user
openstack user create --domain default --password-prompt trove
openstack role add --project service --user trove admin
openstack user set --project service trove
 
# service
openstack service create --name trove \
  --description "Database" database
 
# endpoint
openstack endpoint create --region RegionOne \
  database public http://node1_ip:8779/v1.0/%\(tenant_id\)s
openstack endpoint create --region RegionOne \
  database internal http://node1_ip:8779/v1.0/%\(tenant_id\)s
openstack endpoint create --region RegionOne \
  database admin http://node1_ip:8779/v1.0/%\(tenant_id\)s

8、准备配置文件

mkdir -p ~/log/trove
mkdir -p /etc/trove
cd trove
cp etc/trove/trove.conf.sample /etc/trove/trove.conf
cp etc/trove/api-paste.ini /etc/trove/
cp etc/trove/trove-taskmanager.conf.sample /etc/trove/trove-taskmanager.conf
cp etc/trove/trove-guestagent.conf.sample /etc/trove/trove-guestagent.conf
cp etc/trove/trove-conductor.conf.sample /etc/trove/trove-conductor.conf
 
cd /etc/trove

9、配置trove

编辑 trove.conf, trove-taskmanager.conf and trove-conductor.conf

[DEFAULT]
log_dir = /home/a/log/trove
log_file = trove-api.log
 
如果是trove-taskmanager.conf
log_file = trove-taskmanager.log
 
如果是trove-conductor.conf
log_file = trove-conductor.log
 
auth_strategy = keystone
trove_auth_url = http://node0_ip:5000/v2.0
nova_compute_url = http://node0_ip:8774/v2
cinder_url = http://node0_ip:8776/v1 # traskmanager.conf中未配置些项 
#swift_url = http://node0_ip:8080/v1/AUTH_
notifier_queue_hostname = node0_ip
 
[database]
connection = mysql+pymysql://trove:123456@node0_ip/trove
 
 
[DEFAULT]
rpc_backend=rabbit
 
 
[oslo_messaging_rabbit]
rabbit_host=node0_ip
rabbit_port=5672
rabbit_userid=openstack
rabbit_password=rabbit_password

编辑trove.conf

[DEFAULT]
auth_strategy = keystone
add_addresses = True
# network_label_regex = ^NETWORK_LABEL$ # nova-network 配置此项
network_label_regex = .* # neutron 配置此项
api_paste_config = /etc/trove/api-paste.ini
 
 
[keystone_authtoken]
...
auth_uri = http://node0_ip:5000
auth_url = http://node0_ip:35357
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = trove
password = 123456

编辑trove-taskmanager.conf

[DEFAULT]
nova_proxy_admin_user = trove
nova_proxy_admin_pass = TROVE_PASS
nova_proxy_admin_tenant_name = service
taskmanager_manager = trove.taskmanager.manager.Manager
#nova_proxy_admin_tenant_id =
 
network_driver = trove.network.nova.NovaNetwork
default_neutron_networks =
 
# 若启用安全组,创建trove实例中会有报错,"From port must be an integer."
trove_security_groups_support = False
 
# 如果在guest agent运行在centos7中,需要配置以下几项
guest_config = /etc/trove/trove-guestagent.conf
guest_info = guest_info
injected_config_location = /etc/trove/
cloudinit_location = /etc/trove/cloudinit

编辑 trove-guestagent.conf

[DEFAULT]
log_dir = /var/log/trove/
#log_file = logfile.txt
#log_config_append = /etc/trove/trove-logging-guestagent.conf
#log_dir = /home/a/log/trove/
log_file = trove-guestagent.log
 
rpc_backend=rabbit
 
[oslo_messaging_rabbit]
rabbit_host=node0_ip
rabbit_port=5672
rabbit_userid=openstack
rabbit_password = rabbit_password
 
[DEFAULT]
nova_proxy_admin_user = admin
nova_proxy_admin_pass = ADMIN_PASS
nova_proxy_admin_tenant_name = service
trove_auth_url = http://node0_ip:35357/v2.0

10、 Populate trove database

trove-manage --config-file /etc/trove/trove.conf  db_sync

11、 启动servie

su - a
screen -S trove-api trove-api \
   --config-file /etc/trove/trove.conf
 
screen -S trove-taskmanager trove-taskmanager \
  --config-file /etc/trove/trove-taskmanager.conf
 
screen -S trove-conductor trove-conductor \
  --config-file /etc/trove/trove-conductor.conf

使用trove

1、下载并上传mysql image

wget http://tarballs.openstack.org/trove/images/ubuntu/mysql.qcow2
glance image-create --name "mysqlTest" --disk-format qcow2 \
  --container-format bare \
  --file mysql.qcow2

2、Create a datastore

trove-manage \
  --config-file /etc/trove/trove.conf \
  datastore_update mysql ''

3、Update the datastore to use the new image

# glance_image_ID替换为上面mysqlTest的ID,glance_image_ID后面的有一对单引号,引号间无空白字符
trove-manage --config-file /etc/trove/trove.conf \
  datastore_version_update \
  mysql mysql-5.6 mysql glance_image_ID '' 1

4、创建一个mysql实例

# mysql_instance_1后面的2为flavor的ID,可替换为别的flovar id,--size 为cinder volume的大小
trove create mysql_instance_1 2 --size 5 --databases myDB \
    --users userA:password --datastore_version mysql-5.6 \
    --datastore mysql

已知问题

在20170105,python-novaclient已经发布7.0.0,在源码安装trove过程中,默认安装python-novaclient(7.0.0),导致trove list报错,需要将python-novaclient替换为6.0.0

pip uninstall python-novaclient
pip install python-novaclient==6.0.0

完毕。