从存储到数据库,从搜索到大数据, 数据管理技术总是充满挑战

网易私有云的出现为DDB的思变提供了契机,从12年开始,我们就在基于网易私有云开发一套平台化的管理工具cloudadmin,为此,我们将DDB中原先master的功能打散,一部分分库相关功能集成到Proxy中,如分库管理,表管理,用户管理等,一部分中心化功能集成到cloudadmin中,如报警监控,此外,cloudadmin中提供了一键部署,自动和手动备份,版本管理等平台化功能。私有云DDB的整体架构如下图所示:

%e6%97%a0%e6%a0%87%e9%a2%985

私有云DDB架构

在云DDB解决方案中,还打包了网易私有云LVS服务,cloudadmin通过DDBAgent实现一键部署和报警监控。到目前为止,网易80%以上的DDB集群都已部署云端,云DDB的出现极大减轻了运维人员的负担。

 

DDB特性介绍

分布式执行计划

分布式执行计划定义了SQL在分库分表环境中各个数据库节点上执行的方法,顺序以及合并规则,是DDB实现中最为复杂的一环。

如SQL:select * from user order by id limit 10 offset 10;

这个SQL要查询id排名在10—20之间的user信息,这里涉及到两个合并操作:全局id排序和全局limit offset。对全局id排序,DDB的做法是将id排序下发给各个数据库节点,在DBI层再进行一层归并排序,这样可以充分利用数据库节点的计算资源,同时将中间件层的排序复杂度降到最低,例如一些需要用到临时文件的排序场景,如果在中间件做全排序会导致极大开销。

对全局limit offset,DDB的做法是将offset累加到limit中下发,因为单个数据节点中的offset是没有意义的,且会造成错误的数据偏移,只有在中间件层的全局offset才能保证offset的准确性。

所以最后下发的给各个DBN的SQL变为:select * from user order by id limit 20。

又如SQL:select avg(age) from UserTet group by name

可以通过explain语法得到SQL的执行计划,如下图所示:

%e6%97%a0%e6%a0%87%e9%a2%986

explain示例

上述SQL包含group by分组和avg聚合两种合并操作,与全局order by类似,group by也可以下发给数据节点,中间件层做一个归并去重,但是前提要将group by的字段同时作为order by字段下发,因为归并的前提是排序。对avg聚合,不能直接下发,因为得到所有数据节点各自的平均值,不能求出全局平均值,需要在DBI层把avg转化为sum和count再下发,在结果集合并时再求平均。

DDB执行计划的代价取决于DBI中的排序,过滤和连接,在大部分场景下,排序可以将order by下发来简化为一次性归并排序,这种情况下代价较小,但是对group by和order by同时存在的场景,需要优先下发group by字段的排序,以达到归并分组的目的,这种情况下,就需要将所有元素做一次全排序,除非group by和order by的字段相同。

DDB的连接运算有两种实现,第一种是将连接直接下发,若连接的两张表数据分布完全相同,并且在分区字段上连接,则满足连接直接下发的条件,因为在不同数据节点的分区字段必然没有相同值,不会出现跨库连接的问题。若不满足连接下发条件,会在DBI内部执行nest loop算法,驱动表的顺序与from表排列的次序一致,此时若出现order by表次序与表排列次序不一致,则不满足order by下发条件,也需要在DBI内做一次全排序。

分库分表的执行计划代价相比单机数据库而言,更加难以掌控,即便是相同的SQL模式,在不同的数据分布和分区字段使用方式上,也存在很大的性能差距,DDB的使用要求开发者和DBA对执行计划的原理具有一定认识。

如分库分表在分区字段的使用上很有讲究:一般建议应用中80%以上的SQL查询通过分区字段过滤,使SQL可以单库执行。对于那些没有走分区字段的查询,需要在所有数据节点中并行下发,这对线程和CPU资源是一种极大的消耗,伴随着数据节点的扩展,这种消耗会越来越剧烈。另外,基于分区字段跨库不重合的原理,在分区字段上的分组,聚合,distinct,连接等操作,都可以直接下发,这样对中间件的代价往往是最小的。