目前,服务器的磁盘和内存,cpu都相对较好,一台数据库服务器可以存储好几亿条的数据,在一个什么样的情况下,应该考虑分布式数据库的,百亿?千亿?
如果单机数据库,直接通过分布式数据库来访问,分布式数据库是否能够提高数据库的效率呢?
数据库分库后,一些复杂的sql场景,会比较难处理,而且分库之后,sql除了查询分库的数据外,还要进行数据合并操作,那是否是说不分库,比分库更好一些呢?
答一.
分别回答下,题主的三个问题:
1. 目前,服务器的磁盘和内存,cpu都相对较好,一台数据库服务器可以存储好几亿条的数据,在一个什么样的情况下,应该考虑分布式数据库的,百亿?千亿?
考虑用分布式数据库,肯定是容量或者性能方面,现有的单机数据库满足不了业务的需求。当然,遇到了容量或者性能的问题,也不一定要用分布式数据库,可以通过scale-up的方式,即升级数据库服务器的CPU、内存、磁盘,将SATA/SAS盘换SSD盘等方式解决。不过相对scale-up来说, 分布式数据库这种scale-out的方式,扩展性会更强一些,一般来说也更具性价比。
普通的X86服务器,一台数据库服务器存好几亿条数据,问题不大,但前提是需要分库或分表,单表几亿条数据,普通服务器基本支撑不了的,毕竟数据量一大,表对应的B树层次就高,写入时B树节点的分裂和调整,开销也大。同时,上亿规模下,单台数据库服务器的恐怕不能支持密集的读请求,性能可能会有问题。
2. “如果单机数据库,直接通过分布式数据库来访问,分布式数据库是否能够提高数据库的效率呢?”
题主这里所说的分布式数据库, 应该是指数据库中间件这样的软件吧。目前比较流行的一种做法,是DBA利用开源中间件,结合自己项目的mysql或pg数据库,来搭建出一套分布式数据库的解决方案。主要的方法有两种:
一种是水平拆分。当数据量大到单机数据库已存储不下时, 可以对数据进行拆分,化整为零,将数据均匀分布到多个数据库节点中。由于对数据进行了拆分,每个数据库节点上的数据量小了,自然读写性能就提高了。
另一种是读写分离。这种方法,主要用在数据量并不大,单机数据库能够hold得住,但读请求很高的情况下。此时,可以配置多个只读数据库节点,来分担主节点的读请求。通过数据复制机制,在主节点和只读节点之间进行数据的实时同步,保证主从节点的数据一致性。
两种方法很好地解决了数据库的容量和性能问题。当然,使用了中间件,相当于在sql的执行路径上,多了一个处理环节,因此单条sql的延时,相对于直连数据库节点,在非满负载的情况下,肯定是要高的。但在实际的业务访问中,sql的性能瓶颈,一般都出在数据库节点上,中间件只是做单纯的sql解析和路由,性能开销不会很大。因此,通过增加数据库节点,提升sql处理的短板,是能够提高系统效率的。
3.“数据库分库后,一些复杂的sql场景,会比较难处理,而且分库之后,sql除了查询分库的数据外,还要进行数据合并操作,那是否是说不分库,比分库更好一些呢?”
基于中间件来进行分库, 确实对 SQL 有阉割的情况,并不是所有sql都能够支持。主要原因是数据被拆分了。而数据一旦被拆分到多个节点,则:
1.复杂的join查询
2. 同时更新多个数据库节点的sql语句
这两类SQL的支持难度,就比较高。这也是目前市面上所有中间件都无法满足的两点。复杂的join查询之所以难以支持,是因为要跨节点join;同时更新多个节点的sql难以支持,是因为很难解决多个节点的并发一致性问题。但是除了这两点之外,其他的sql类型,一款中间件是能够努力做到的。
从中间件实现的角度,我们来对sql做一个分析,以说明这一点。
1. 按操作范围的维度,可以把所有的SQL,分为3类:
1.1 kv类的sql: 这种sql操作很简单,就是简单的set/put某个表的一条记录,大部分insert/delete/update语句,和指定primary key/key的select,都属于这种类型。
1.2 范围更新/查询:这种sql不局限于操作一条记录,但还是作用于一张表。比如update多行记录,或者select某个时间范围的记录等。
1.3 多表join查询:又包括两种:
1.3.1 分库分表键都是同一个的多表join:由于采用同一个划分键,因此join操作其实是发生在单节点
1.3.2 分库分表键不是同一个的多表join: 此时涉及到跨节点的join,实现复杂
2.按是否要在关系运算之后,还要对结果进行聚合,把select sql分为两类:
2.1 不需要进行结果聚合,即select sql中没有集函数、group by、order by、limit等需要在关系运算之后,再对结果进行处理和聚合;
2.2 包括上述结果聚合语法的select sql
3.从是否对分布式事务有要求的角度,可以把SQL分为两类:
3.1 只读写一个节点的sql,无分布式事务要求
3.2 跨多个节点读写的sql,有分布式事务要求
根据之前所述, 目前的业内的中间件,都不能支持1.3.2 和3.2(mycat对分布式事务的支持,只支持最终一致性,还是一个伪支持;阿里DRDS号称内测版本支持分布式事务,但一直未见公测),而除去这两点,对于类型(1.1, 1.2, 1.3.1) × (2.1,2.2)得到的6种sql类型,理论上讲,中间件都是可以做到支持的。
对于OLTP应用来讲,这6种类型能够覆盖绝大部分的业务场景,这也是中间件技术这几年这么流行的原因。遗憾的是,目前业内的各大中间件, 对这6种类型的sql,支持程度往往都有一定的折扣。比如对于这样一条操作单表的sql:
select distinct id, avg(price) from t1 where id>=1 group by concat(id,name) order by avg(price) limit 10;
目前主流的几款中间件,似乎就不能支持。
目前,UCloud 的 UDB 团队,也在打造一款基于中间件和 UDB 的,分布式数据库产品 UDDB,协议和SQL语法,全面兼容MYSQL。我们从零开始,但目标远大。正如 UCloud 一直强调的,用户的需求是我们下一款产品。我们的第一个目标,是做一款业内最好用的分布式数据库,解决用户在使用mysql中间件构建分布式解决方案时的痛点:学习成本高,配置复杂,运维麻烦,扩容不方便。
在系统管理上,UDDB将做到一步创建,开箱即用,无需额外的管理和配置操作,并提供全自动化,无需停服的水平扩展/缩容操作;SQL支持上,我们将对类型(1.1, 1.2, 1.3.1) × (2.1,2.2)这6种sql,进行全面的支持,让用户在遇到带avg集函数、group by,order dy的select sql时, 无需担忧系统是否支持,即可放心使用。
预计在今年9月底,UDDB将开放内测,敬请大家关注。
长期来看,打造这样一款分布式数据库服务,是我们和客户交流,探索未来的一种方式。诚然,相对于 Google F1,Oceanbase 等全新设计的分布式数据库产品, 基于中间件的分布式数据库,在技术上并非最前沿,但是我们相信,这是广大客户目前正需要的。我们相信只有先服务好用户,深入到用户的需求当中,根据用户需求不断迭代,同时团队自身不断成长,才能真正理解公有云环境下,用户对分布式数据库的需求,才能做出接地气和广受欢迎的产品。
答二.
凡事都是能简则简,虽然分布式数据库是数据库发展的方向,但并不是说一定要用分布式。例如,很多NoSQL都是分布式的,但是很多中小型系统的都没用用到分布式的特性。
但对于大型应用来说分布式数据库就非常有优势。现在比较流行的说法“金融级”的数据库产品面向银行等大型企业的大量高频的数据处理,则都需要分布式数据库,几十个节点到1-2百的节点也非常多。
规模、性能、高并发、数据拆分、降低索引层次高度等都需要综合考虑来决定是否使用分布式数据库。分布式架构不是一个新鲜事务,因为现在网络带宽(万兆以上带宽)、存储、x86的低成本才给了分布式数据库大力发展的条件。
技术产品采用主要是性价比,在海量数据处理情况下,分布式数据库的性价比特别明显:
更多的特性也不再一一描述了。分布式数据库核心之一就是对数据的精细颗粒度管理,数据拆分后,命令下压能否在精准定位到相应的数据节点来做计算。
数据拆分有三大类:
所以分布式数据库非常需要架构师和工程师对业务理解能力和数据规划能力。
和选择产品有关的另一点就是产品化和成熟度,如果您是企业采购数据库,这点就尤为重要。数据库是否有“原厂”的技术服务能力也是大型企业选择数据库重点。
答三.
1. 什么情况下使用分布式数据库
这个取决于你的业务,如果单机数据库已经能满足你当前的业务需求并且也能满足可预期的未来一段时间的业务需求,那就没必要用分布式数据库。具体的业务需求可以考虑容量、性能、一致性要求、可靠性和容灾等。
2. 分布式数据库是否能够提高数据库的效率
分布式数据库不一定能提高效率,假设你的数据量不大,或者是每次查询只涉及很少一块数据,并且索引建的比较好,单机数据库的速度有明显的优势。
3. 复杂的 SQL
如果用一些中间件方案,对跨库事务、join等操作很难处理好。但是分布式数据库!=中间件方案,中间件方案只是其中的一种。我们正在做的 TiDB,采用的和 Google F1/Spanner 相同的思路,不需要进行分库分表,对复杂的 SQL 会采用分布式计算,提高性能。欢迎试用。