分布式存储

Introduction

Usage Scenario

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

  • 企业级方面

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

  • 互联网方面

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

Advantage

单机房一旦死机,断电、维护根本无法挽回整个数据,想离线读取等都不行。当一个机房不可用,所有的业务就都不可用。荔枝 FM 要求业务离用户最近,南方的用户连南方的机房,北方的用户连北方的机房,国外的用户连国外的机房。大陆的网络和国外的网络有一定的隔离性,如果没有做多机 房的连通性,数据的传输和实时性就会有问题。

  • 数据安全:机房不可用时数据无法访问

  • 业务可用性:机房不可用时业务停止

  • 用户响应:因为网络连通性,不同地域的用户的请求响应延迟不同

    而多机房架构下,一个机房的数据放在另一个机房是异地多活。上面是数据容灾,下面的是业务容灾,第三个是让服务离用户最近。这是荔枝 FM 做跨机房的原因。

Solution

对于 MySQL 的解决方案,一般主要分为两类。 第一类:多库冗余的方案 这类产品的主要特性是可以提供多个主库,主库之间的同步是实时的,不会有延迟。但是每个数据库都保存了全部的数据,所以 是冗余的。这类产品没有水平切分表的功能,所以和上面说的企业级的 cluster 差不多。最大特点是省钱。 第二类:水平切分表的方案 当数据的量很大,cluster 已经解决不了的时候,一般会首先采用垂直切分,也就是分库。把不同的功能分配到不同的数据库里。 也有一种观点认为垂直切分是把一个表的字段切分,分配到不同的表里。 垂直切分虽然可以按照业务需求,把数据库的负载分开,但是对于每一个数据库,如果表的数据超大,就需要采用另一种方案, 也就是水平切分,把一个表的数据按照某个规则分配到不同的数据库的不同的表里,一般把这个叫做 sharding。 MySQL 提供了 sharding 的解决方案:MySQL Cluster (别看名字叫 cluster,其实它也提供了 sharding 的功能)。 看介绍功能非常强大,但是也有一些限制,比如数据库引擎不能使用 innoDB,必须使用 NDB 等。 第三类:各个公司自定制的分库,分表方案 使用自己定制的方案,各个公司都遵循了差不多同一个思路:垂直切分(分库),水平切分(分表)。网上的资料有很多,各个 公司分享的资料也有很多。但是因为这确实是有价值的技术,所以大家的分享也就都是“浅尝辄止”,总体思路分享了,细节是 绝对不会分享的。所以资料看多了,也就发现思路都差不多,就看你怎么做了。 细节。 第四类:使用云服务 很多大型的云服务提供商基本都提供了分布式数据库的服务,如果想节省成本,降低风险,这绝对是好的选择。

一致性哈希

一致性 hash 作为一个负载均衡算法,可以用在分布式缓存、数据库的分库分表等场景中,还可以应用在负载均衡器中作为作为负载均衡算法。在有多台服务器时,对于某个请求资源通过 hash 算法,映射到某一个台服务器,当增加或减少一台服务器时,可能会改变这些资源对应的 hash 值,这样可能导致一部分缓存或数据失效了。一致性 hash 就是尽可能在将同一个资源请求路由到同一台服务器中。