DBaas(database-as-a-service)随着云计算大潮也开始火热起来,国外的Amazon RDS、Microsoft Azure SQL、Google Cloud SQL、HP Cloud Relational Database等产品已经争得不可开交,国内阿里云也大力招聘数据库开发大牛准备拿下国内市场;云数据库看起来很美好,尤其对初始创业团队或规模不大的企业公司,因为配置、后续扩展、调优、备份、访问控制等原来需要专门DBA来处理的地方通通"云端"搞定,而且还是灵活的按需付费,但云数据库目前还不太成熟,主要面临着三方面的挑战:1.弹性扩展2.多租户的整合性3.隐私问题
对此,MIT发起了Relational Cloud项目,以期解决这些问题,这项目也得到了NSF(美国国家科学基金会)的支持,目前已取得了一些成果;下面简单谈下Relational Cloud如何克服这三大困难的.
设计架构
Relational Cloud使用现有的RDBMS(目前支持MySQL和Postgres)作为一个backend node,上面只运行一个实例,实例上可以运行很多数据库,一个数据库里可以有很多张表,一个数据库的负载叫做workload;1个租户(也即使用者)可以使用1个乃至多个数据库,但一个数据库不会同时给2个以上租户使用.
客户端使用标准连接器(譬如JDBC)来连接Relational Cloud的front-end,front-end然后向router咨询,router分析这个SQL然后决定哪些节点参与执行和相应执行计划,随后front-end协调各节点的事务处理、还负责失效节点的处理,同时它还根据各租户性能优先级处理分配速率.front-end monitor还是个监控器,监控workload数据处理速度和机器整体的负载,有了这些监控数据,Relational Cloud才能做决策:1.当单台机器性能不够,将数据库分片到其他节点上2.最优放置分片到各个backend节点,不宕机迁移数据,高可用复制3.加密数据的查询
总体概览图如下所示:
1.弹性扩展
当某个租户的负载越来越高而单台机器性能又达到瓶颈,这时只好分片扩展了,分片还能达到负载均衡的效果,但制定扩展的规则是个问题;Relational Cloud使用了一种叫workload-aware partitioner的基于图分析的分片算法来将复杂查询分片到不同节点.workload-aware partitioner有个很好的优点就是schema的布局和外键间复杂关系不影响它的效率,所以很适合社交网络间的多对多关系.对OLTP应用来说,尽量少分片,也即尽量将事务在一台节点上执行,因为分布式事务开销太大.
2.多租户的整合性
对云数据库厂家来说希望一台机器最大化的承担最多租户,同时某个租户假如运行复杂SQL也不会影响其他租户的使用.传统做法是使用虚拟机:一台机器划分出很多虚拟机,每个虚拟机包含一个数据库运行实例.但这种做法的实际运行效率却不高,因为每个虚拟机里都单独运行一个数据库实例,每个实例单独管理buffer pool、产生各自的log等等,也即每个虚拟机都有固定无法避免的损耗.Relational Cloud没有使用虚拟机,而是一台机器只装一个实例,但却下属很多小逻辑数据库,能通过分片和迁移最大化利用单台机器(oracle 12c的多租户特性不知道是不是,我对oracle不熟,哈).
一个新创建数据库是被任意存放在某个节点的,但它所有的运行状态信息都被放在另一台专门的机器上,通过分析运行状态预测这个数据库以后的负载是否会影响机器上的其他数据库,后续是否需要做分片.假如要分片,就用之前提到的workload-aware partitioner算法,完成后的分片再按一定分配算法放到不同节点上.监控和数据整合引擎在Relational Cloud里叫Kairos,主要由三部分组成:
1.Resource Monitor:自动化采集数据库和系统运行信息;但一个挑战就是如何准确估计一个数据库实际需要的内存,因为数据库实例启动时预先分配一整块大buffer pool共享给各个数据库用,而其实这pool里面很多page都还没用.Kairos使用一种聪明方法来探测一个数据库实际需要内存大小--它重复访问一个逐渐增大的临时probe table,同时检测磁盘负载情况,一旦磁盘使用率增高,说明内存不够了,通过记录临时probe table前后大小,就知道这个新部署数据库的内存实际占用了.
2.Combined Load Predictor: Kairos也使用了一种非线性算法来预测两个数据库合并后的实际负载.为什么是非线性算法?因为CPU、IO、内存的消耗叠加通常是非线性的,尤其对IO适用--两个并在一起数据库的IO总量通常比原先相加的小,因为log共用,而group commit就能很大提高log刷新效率了.
3.Consolidation Engine:最后在合并阶段,Kairos非线性优化的放置分片到哪个backend node上,以两方面做基准--能不能使需要的机器数据最少和能不能均衡负载.
除了上述这些功能,为应对日常维护或者某个backend node失效需要移除等状况,Relational Cloud还提供了透明迁移功能,迁移时不宕机而且性能也无明显下降.
3.隐私问题
数据隐私可能是大部分公司使用云服务的最大问题,有些商业机密可能关乎公司的生死.传统加密无法防止服务器端的查看,譬如一个库加密存放着,但运行SQL总归要先将库解密,这时DBA就能通过show processlist看到了.Relational Cloud创造性的使用CryptDB来实现低损耗加密解密,据测试性能只比未加密情况下减少了22.5%.
目前加密手段有很多种,譬如:randomized encryption(RND)、deterministic encryption(DET)、order-preserving encryp-tion(OPE)、homomorphic encryption(HOM).这些加密方式都有各自的特点:RND提供最大化隐私保密性,但加密数据也得解密后才能比较;DET的隐私性相对弱点,但支持密文的等值比较(譬如select * from table where id=1这样的语句,没必要解密成明文再比较,直接将数值1加密后值与现有加密表的行比较就行);OPE隐私性更弱,但能支持密文不等值比较和排序操作;最后HON支持直接对加密表进行更改.CryptDB的关键之处是使用adjustable security--每行每个值被不同加密方法加密多次,像个洋葱一般,每层放置不同加密值,越外层加密等级越高,但相应功能也越少,如图:
对数值类型,加密三次,第三次是RND,前两次加密方法可以灵活选择;对于字符串类型,加密两次,第一次加密允许等值比较和按词搜索,第二次加密其实不算加密,只是生成一个对应key,比较这个key就能判断两个字符串是否不相等.
每层都有自己加密key,客户端能访问所有层的key,当客户端受到SQL查询时,它决定一个合适key来解密合适的层(譬如等值查询DET层就够了).看下例子:
SELECT iprice,...FROM item WHERE i_id=N
JDBC将会先解密I_id列到DET level4,然后where判断,找到结果列后计算DET level4的加密值,通过这个值找到RND加密的结果给JDBC客户端,客户端再解密.可以看到在DET level4的等值比较也还是加密的,所以即使DBA也无法看到明文数据.
性能
下面所有测试都是在TPC-C下:
整合效率:下图可看到Relation Cloud的整合效率是相当高的,节省6~17倍的服务器.
性能:比较了单台机器上运行多服务器实例和单实例分割多个逻辑库的效率,十分喜人的对比!
扩展性:扩展至8台机器,吞吐率接近线性增长.
加密损耗:加密后平均只损耗了22.5%的性能,可以接受.
结尾
DBaas目前还是各大云计算公司的机密,外人不得一窥,之前我对数据库云的概念还只是停留在KVM、LXC等虚拟化层面上,Relational Cloud提供了了个很好的参考学习平台,但多租户效率分配、租户间性能隔离、分片算法、CryptDB等等本篇博文都没细究,详情请参考官网.