如图 12-1 所示就是地球表面的代表——一望无际的华北平原。
北京位于美丽的华北平原北端,生活着两千多万人,在巅峰的 2020 年双 11,天猫平台北京地区销售额为 216 亿,全国总额为 4982 亿,占比为 4.33%,略高于北京占全国 3.44% 的 GDP 比例,数据比较可信。使用这些数字我们可以计算得出,北京的两千多万人,给天猫贡献了583000 * 0.0433 = 25243.9
笔/秒的并发。
虽然全国订单数看起来十分惊人,但是北京这一个地方的压力却只有 2.5 万单每秒,这个哪怕不用奇技淫巧,纯靠数据库硬抗,十万数据库 QPS 只用主从架构可能都能抗住。但是,系统能基于地理位置划分吗?系统不是必须全国一盘棋吗?不是的,可以划分。
下面我们讨论一下怎么划分。
为什么非要全国的用户访问同一个数据库呢?我们可以利用微服务思想对业务系统和数据进行拆分:北京的用户和上海的用户,理论上讲都可以只访问“本地天猫”。
接下来我们分析一下,在一个标准的电商业务中,哪些地方会让一个北京的用户和一个上海的用户发生联系。
实际上,地理上被隔开的两个人,在系统内还真没什么机会需要相互查询对方的数据,这就是我们能基于地理位置对应用和数据库进行分区的现实原因。下面我们一一拆除这几个单点:
基于地理位置对应用和数据库进行划分,产生出两个“本地天猫”后,就需要我们老朋友 DNS 出来表演了。
域名当初可能是为了方便记忆而发明的,但是域名背后的 DNS 服务却几乎是最重要的互联网高并发基础设施:不同地区的人,对同一个域名进行访问,可以获得两个公网 ip,这样“本地天猫”就实现了。
DNS 几乎完全放弃了一致性,但却实现了极高的可用性和分区容错性。其实,gossip 协议也是这个思想:让消息像病毒一样传播,能够实现最终一致性就行了,要啥自行车。
异曲同工的 Kong 集群的设计思想也十分令人震惊:所有节点每 5 秒从数据库读取最新的配置文件,然后,这些节点就成了一个行为完全一致的集群啦。“想那么多干什么,短时间内多个节点的行为不一致,就让它们不一致好了,5 秒之后不就一致了。”
高性能计算第一原则:数据离 CPU 越近,性能越高,容量越小
在我们熟悉的存储器山中,这是一个大家都理解的基本特性,而这个特性引申到分布式系统中,就是:一定不能让应用和数据库分离。
和 InnoDB 一样,很多时候其实是“局部性”这个我们宇宙的基本属性在帮助我们提升系统的性能,让应用和数据库分布在同一个地域,也是在利用局部性获得性能增益。
所以,让应用去隔壁区域的数据库读数据是要极力避免的——我们应该用 API 网关直接把请求发给隔壁区域的应用服务器,这显然是在今天这个异地网络传输速度接近光速的时代最佳的选择。
Clickhouse 在亿级数据量面前丝毫不怵:MySQL、MongoDB、Hadoop,谁也没有老子快。为什么 Clickhouse 这么快呢?
首先,它将数据以列为单位组织起来,压缩后存入磁盘上一个又一个的 block,这些 block 就像 InnoDB 的 16KB 页一样,只是它更大(64KB~1MB)。这样,当我们 select 某个 column 的时候,Clickhouse 就能顺序读出磁盘上这个 column 下面所有行的数据。
由于同一列通常具有高度的数据相似性,所以列式压缩的效果在大部分情况下都非常好,这也能算作“局部性”在数据库层面的一种应用。
除了列存储之外,每个 block 内,Clickhouse 还用“稀疏索引”的方式,将每一列的数据划分为了多个 granularity(颗粒度),然后给每个 granularity 分配一个 CPU 核心进行并行计算,并且它还利用 SSE4.2 指令集,利用 CPU 的 SIMD(Single Instruction Multiple Data)指令,在 CPU 寄存器层面进行并行操作。
这是 Clickhouse 整个架构中笔者最喜欢的部分。我们通过前面的章节可以看出,所有的分布式数据库,其本质都是在搞“内存缓存的数据同步”,Clickhouse 直接掀桌子——老子不要内存缓存了。由于所有数据都在磁盘上,而节点的 CPU 又直接和磁盘数据打交道,所以 Clickhouse 实现了真正的并行:增加 CPU 核心数就能提升系统容量,无论在不在同一台机器上都行,反正 CPU 相互之间完全不需要通信。这样,Clickhouse 通过堆核心数就能够实现系统容量的“近线性扩展”。
我们可以学习这种思想,打造一个可以线性扩展的系统架构:只要不同地区的本地系统之间完全没有“数据实时同步”需求,那其实它们就是两个系统,就可以实现线性的性能提升。
我们说过,关系型数据库的关系,指的就是两行数据之间的关系。现实世界中,位于异地甚至是异国的两个人之间,几乎是不会发生实时相互数据读取的。
站在地球表面来思考,你会发现人类社会和自然规律都是契合高并发“找出单点,进行拆分”哲学原理的:每一个人类居所,本质上都是散落在整个地球上的一个又一个点。因为这些点的存在,我们发明了国省市县乡村逐级政府,同级政府之间几乎没有相互通信。
将一个大系统拆成不需要实时相互通信的多个小系统,可以获得线性的性能提升。
当你的系统顶不住的时候,按照这个原理来拆就行了,绝对顶得住。别说区区一百万 QPS 了,服务全人类也做得到,毕竟全球 80 亿人都生活在如图 12-2 所示的球体上嘛,这个球体的半径也只有六千多公里,不算是很大的一个球。
价值上完了,我们最后再讨论一下高可用。
📙 高并发的哲学原理 《Philosophical Principles of High Concurrency》
Copyright © 2023 吕文翰