数据拆到多台机器就是分布式?从电商仓库看懂分片与分布式的本质区别

面试里经常有人会问:数据库把数据拆到多台机器上,不就是分布式了吗?

严格来说,分片确实是分布式系统的一种基础能力。但在工程选型的语境下,我们通常把只做了数据拆分和具备完整分布式协作能力区分开来。分片解决的是数据太多,一台机器放不下,或者单机已经扛不住了,所以把数据拆开,放到多台机器上。至于这些机器之间怎么配合、怎么通信、怎么保证整个系统正常工作,那才是分布式系统要解决的问题。

所以,数据放在多台机器上,只能说明系统用了多台机器,并不能直接等同于具备分布式能力。

这个区别换个生活场景就清楚了。先不说数据库,我们看看仓库是怎么处理的。

中央仓库

我们用电商仓库举例。

最开始,所有商品都放在一个中央仓库里。随着商品越来越多,这个仓库慢慢到了容量和处理能力的上限。

于是,老板把商品按类目拆开,分别放到五个仓库:3C、服饰、生鲜、家居和图书。每个仓库负责自己的商品,独立入库、独立出库,也维护自己的库存。

这其实就是分片。

原来一台机器承担的存储和读写压力,现在分摊到了多台机器上。单个仓库的压力小了,整体容量也上去了。

但问题并没有结束。仓库一多,仓库之间怎么配合,就成了新的问题。

单纯的分片带来的问题

一个用户下了一笔订单,买了手机壳、T恤、牛奶和三本书。客服要查这笔订单的物流状态,得分别给四个仓库打电话。仓库A说不知道B有没有货,B也说不知道C的库存。它们只是物理上被分开了,信息上并没有打通。

这就是单纯的分片:数据被切开了,但每个实例仍然孤立。放在数据库里,相当于你把一张大表按某个规则拆成了多张表,分别放在不同的MySQL实例上。查询如果恰好只命中一个实例,一切正常;一旦需要跨实例汇总,就得自己写代码去拼结果。

需要一个调度中心

老板又加了一层调度中心。

每个仓库只需要告诉调度中心,自己负责什么:3C仓负责电子产品,服饰仓负责服装鞋帽,其他仓库也各自登记自己的范围。

用户下单后,不再直接找某个仓库,而是先把请求交给调度中心。调度中心根据商品信息查一下对应关系,再把请求转到正确的仓库。至于仓库内部怎么存、怎么取,还是各管各的。

这就是很多数据库分片方案的基本思路。以MySQL的Vitess,以及MongoDB的Sharded Cluster为例,底层依然是多个相互独立的数据库实例,它们并不知道彼此的存在。Vitess的VTGate除了维护分片规则、把请求路由到对应分片之外,也会做查询重写、结果合并,甚至部分跨分片事务的协调工作。但底层MySQL实例本身不会直接通信,协作语义仍然由中间层补齐。

这样一来,客户端看到的还是一个数据库,底下实际上已经拆成了多个数据库实例。

但这种方式也有一个明显的问题:协调层知道所有分片,也承担了所有分片之间的协调。

一旦协调层出了问题,整个系统都会受到影响。更麻烦的是,如果一个订单同时涉及多个仓库,协调层还得负责把这些请求组织起来,而各个仓库之间本身并不会直接协作。

真正的分布式

真正的升级,不是再加一个调度中心,而是让仓库之间能够互相感知。每个仓库实时同步自己的库存和运力,A仓缺货时自动从B仓调拨,一笔大订单可以拆到多个仓库同时拣货,某个仓库故障时系统自动把订单导到最近的仓库。客户端不需要知道该找谁,连接到集群的任意一个接入节点,这个节点会自己把请求转到正确的地方。

这就是分布式系统。节点之间通过协议直接通信,并通过Raft或Paxos这类共识协议同步状态和决策,共同维护一份集群视图,能自主完成路由、复制、故障转移和负载均衡。TiDB、CockroachDB、YugabyteDB走的都是这条路。

放到仓库的语境下,分布式不是仓库变多了,而是仓库之间会协作了。

回到数据库

把这个例子换回数据库,分片和分布式的区别就比较清楚了。

分片数据库,实际上还是多个独立的数据库实例,只是在前面增加了一层路由。数据被拆开了,但各个分片之间并不知道彼此的存在。这样做的好处是比较容易在现有数据库上改造,对业务的影响也相对小。但随着系统变复杂,跨分片事务、全局一致性、故障转移等问题都会变得麻烦,而中间的路由层也可能成为瓶颈。

分布式数据库则不一样。它从一开始就把多节点协作作为数据库本身的一部分。数据同样会被拆成多个分片,但这些节点之间是相互协作的,会同步数据和状态,并共同完成复制、故障切换、数据迁移等工作。

所以,分片解决的是数据怎么拆,分布式解决的是拆开以后,多个节点怎么一起工作。

选型判断

到底选分片,还是直接用分布式数据库,主要看两件事。

一个是业务怎么用数据库。如果大部分查询都能落到单个分片,跨分片事务和Join很少,对自动故障切换的要求也不高,那么分片方案完全可以满足需求,而且改造起来通常更简单。

但如果业务经常需要跨分片查询、事务需要覆盖多个节点,或者希望扩缩容、故障切换这些事情尽量由数据库自己处理,那么分布式数据库会更合适。

另一个是团队能维护到什么程度。分片方案看起来简单,但分片键怎么选、请求怎么路由、数据怎么迁移和重新分布,这些事情最终都需要团队自己解决。分布式数据库则把很多工作交给了数据库引擎,但团队也需要为此付出学习和排查问题的成本。

所以选型时,不要只看数据库本身的能力,还要看业务的实际使用方式,以及团队是否有能力长期维护这套方案。

小结

分片和分布式经常被放在一起说,但解决的并不是同一个问题。

严格来说,分片是分布式能力的一部分。我们这里强调的,是工程上只拆分、不协作与拆分且协作的差别。分片解决的是数据怎么拆、放在哪里;分布式解决的是多个节点怎么协作。一个系统可以只做分片,也可以同时具备分片和分布式能力,但数据拆到多台机器上,并不意味着它就成了分布式系统。

所以做数据库选型时,先把自己的问题搞清楚:到底是一台机器的容量和性能不够了,还是已经需要多个节点共同完成数据管理和故障处理。把这个问题想明白,基本就知道该往哪个方向选了。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容