分布式数据库学习的总结

算是最近对分布式数据库学习的总结吧(仅限于关系型数据库)。
  • 什么时候需要考虑分布式数据库

    虽然分布式数据库看起来是一个很酷炫,而且是可以解决一切大量存储,读取的完美解决方案,但是不可避免的,在实现方式上要比单机数据库麻烦一些。那么什么时候需要考虑分布式数据库呢? 根据以往的经验,如果你的系统/应用比以下规模要小,那基本不用考虑分布式数据库。

    ■企业级方面

    个人接触过的企业级应用,其作为数据仓库,每天从数十个系统导入数据,同时又分发到数十个系统。这样规模的系统,运行了7,8年,也仅仅是一个Oracle足够了。当然它的实时性要求不高。 其他的系统,大量数据的也有用到Oracle, DB2 cluster(一般是2个服务器),运行10多年也足够了。


    ■互联网方面

    虽然没有什么经验,但是类似 iteye.com 这样的规模,根据其前站长分享的文章,也仅仅使用了缓存,没有使用分布式数据库。 所以,如果你的系统/应用从长远来看,比以上两个规模都小,或者相当的话,是不用考虑分布式数据库的。

  • 企业级数据库的解决方式

    对于企业级数据库,例如Oracle,SQL-Server,DB2等,都有各自的cluster(集群)解决方案。不过cluster并非真正意义上的分布式数据库,仅仅是解决高可用性(HA)下数据库的负载均衡问题。最大的缺点就是每个数据库都是冗余的。所谓冗余,就是每个数据库的数据都是一模一样的,正因为一模一样,所以可以很简单的解决负载问题。但是数据量上升到一定程度,对集群中的每个数据库同样会造成很大的压力。
    虽然如此,但正如上面“是否使用分布式数据库”,你的系统/应用运行10年,可能都不会遇到这样的问题:因为企业级数据库的性能很高,也很容易通过硬件来扩展性能。夸张点说,甚至有的人整个IT职业生涯,都不会遇到必须使用分布式数据库的场合。

    分布式数据库最重要的概念就是sharding,这其中最复杂,最有挑战的就是水平切分表数据。这样的特性也逐渐的出现在了企业级数据库中。

    例如 SQL-Server:
    http://www.infoq.com/cn/news/2011/02/SQL-Sharding
    不过费用非常高。

    Oracle:
    http://www.eygle.com/archives/2015/11/2015_oow_oracle_sharding.html
    仅仅是开始而已。正如文中所说,在Oracle的应用场景中,这种需求不是非常多。
    DB2:资料几乎没有,以后再调查吧。

    企业级数据库的一个特点是价格昂贵,随之而来的是性能非常高。所以如果是部署企业级应用,总的思路应该是提高单台数据库的性能(数据库设计+程序优化+硬件提升)。迫不得已,可以使用Cluster。
    如果要做水平切分表数据,那数据库的数量也必然会上升,成本会大量上升,此时就不应该考虑企业级数据库了。

  • 目前流行的分布式数据库解决方案

    目前在互联网公司中分布式数据库是使用最广泛的 --- 当然,我们局限于大的互联网公司。例如 iteye.com,它也是互联网公司,但是没有必要使用分布式数据库。而BAT的许多应用,因为有上亿级的用户,就必须使用了。

    当需要使用成千上百台服务器的时候,大家普遍选择的是免费的数据库,例如MySQL。所以网上的文章大多是MySQL的解决方案。

    对于MySQL的解决方案,一般主要分为两类。
    第一类:多库冗余的方案
        代表产品:Gelera。http://galeracluster.com/
        这类产品的主要特性是可以提供多个主库,主库之间的同步是实时的,不会有延迟。但是每个数据库都保存了全部的数据,所以
        是冗余的。这类产品没有水平切分表的功能,所以和上面说的企业级的cluster差不多。最大特点是省钱。

    第二类:水平切分表的方案
        当数据的量很大,cluster已经解决不了的时候,一般会首先采用垂直切分,也就是分库。把不同的功能分配到不同的数据库里。
        也有一种观点认为垂直切分是把一个表的字段切分,分配到不同的表里。
        垂直切分虽然可以按照业务需求,把数据库的负载分开,但是对于每一个数据库,如果表的数据超大,就需要采用另一种方案,
        也就是水平切分,把一个表的数据按照某个规则分配到不同的数据库的不同的表里,一般把这个叫做sharding。
        MySQL提供了sharding的解决方案:MySQL Cluster (别看名字叫cluster,其实它也提供了sharding的功能)。
        http://www.mysql.com/products/cluster/features.html
        看介绍功能非常强大,但是也有一些限制,比如数据库引擎不能使用innoDB,必须使用NDB等。

    第三类:各个公司自定制的分库,分表方案
        使用自己定制的方案,各个公司都遵循了差不多同一个思路:垂直切分(分库),水平切分(分表)。网上的资料有很多,各个
        公司分享的资料也有很多。但是因为这确实是有价值的技术,所以大家的分享也就都是“浅尝辄止”,总体思路分享了,细节是
        绝对不会分享的。所以资料看多了,也就发现思路都差不多,就看你怎么做了。
        云栖社区这篇分享不错:https://yq.aliyun.com/edu/lesson/44?spm=5176.100242.lessonh1.36.loWn19,算是讲了很多的
        细节。

    第四类:使用云服务 
        很多大型的云服务提供商基本都提供了分布式数据库的服务,如果想节省成本,降低风险,这绝对是好的选择。

  • 自己的一点想法

    如果有一天自己会面对分布式数据库的场景,并且MySQL提供的方案无法使用的时候,自己会如何设计其中的架构呢?
    大概的架构应该是下面这个样子:


    分布式数据库学习的总结
     

    对于蓝色的“分布式管理器”来说,它应该是一个数据库连接的模拟,或者说是代理。与具体的编程语言无关,总之它就好像是一个数据库。而客户端(无论是Java,C#,PHP),连接它的时候,就和连接一个普通的数据库没什么区别。

    之后,蓝色的“分布式管理器”会把请求发送给绿色的“分布式管理器”,绿色的“分布式管理器”负责连接数据库,负责具体的数据处理。

    ▶ACID的满足
    A:原子性。因为数据的存储依赖于现成的数据库产品,所以原子性不成问题。
    C:一致性和I:隔离性。因为数据分布在不同的数据库上,所以无法使用数据库的事物功能。而数据库的数量很多,即使是2阶段提交也会造成负载的增加和不稳定。所以,分布式管理器中必须要控制事物,也就是每条数据记录,都必须有一些控制事物信息的字段,如事物ID,事物状态等。而我们读取数据的时候,也必须参照这些事物的信息才可以。
    如果一个事物更新3个数据库,在数据准备阶段都没有问题,但是提交阶段出错了(如,死锁,网络故障,机器故障),那么怎么保证事物的完整性?
    个人觉得上面的云栖社区分享的分布式数据库中的方法不错:也就是上面绿色的“分布式管理器”,当它提交数据操作到数据库的时候,如果发现提交失败,那么就再次提交,直到成功为止。
    D:存储性。因为数据的存储依赖于现成的数据库产品,所以存储性也不成问题。

    ▶蓝色和绿色的“分布式管理器”有什么区别?
    按照个人的设想,他们应该是同一个东西,只不过在不同的配置下,发挥了不同的作用。
    蓝色的“分布式管理器”,具有事物信息控制,连接数控制等功能。
    绿色的“分布式管理器”,具有连接数据库,发送SQL,返回结果的功能。
    所以,理论上,绿色的也可以换成蓝色的,这个层级可以一直延伸下去(当然层级过多没什么意义)。

    ▶如何实现sharding的功能?
    最好是要求每个表固定一个名称的字段,然后蓝色的“分布式管理器”,会根据一定的规则(如取模,或者按数字区间分段),把数据分配到不同的数据库上。或者这个字段是可以配置的也可以。

    ▶分布到不同数据库上的数据,如何进行查询?
    这应该是把数据sharding后最有挑战的工作。可以要求具有相关业务的表的数据,它们的sharding字段的值都相同,这样即使是多个表,相关联的部分就总是会分配到相同的数据库上。
    比如表A和表B,前10000条数据,两个表的sharding字段的值都是A001,后10000条数据,两个表的sharding字段的值都是A002。这样至少可以保证前10000条数据都分配到一个数据库,后10000条数据也分配到一个数据库。

    在查询的时候,如果查询条件指定了sharding字段,那就可以直接定位到数据库。如果不指定sharding字段,那么就每个数据库都进行查询,各个查询结果汇总到查询结果最大的那个绿色的“分布式管理器”。如果有order by, group 等对结果集进行合并的操作,就再创建一个临时表,把所有的结果放入这个临时表,然后进行 order by, group 等等处理。当然,这样会影响速度。

    所以,如果可以的话,尽量避免联合查询,客户端分别查询出结果,由客户端来控制是最好的。这也要求事先对业务数据进行好的设计。

    总之,上面是个人的一些设想,实现起来还是很复杂的,例如事物管理,连接管理,多个“分布式管理器”的协调,SQL语句的解析等等。
 
以上就是近期对分布式数据库学习的总结。如有错误,欢迎指正。
 

相关推荐