通过数据库进行通信
了解数据库如何帮助分布式系统中的通信。
在任何系统中,数据始终在不同节点之间持续流动。你发布一条 Facebook 动态、在 Google 上搜索信息、在亚马逊下单购买新款 iPhone,诸如此类的每一次与互联网服务的交互,都涉及数据的传递。事实上,在现代系统中,数据的使用量比以往任何时候都要密集。
注意:在分布式系统中,进程(以及类似节点)之间的高效通信至关重要。这些进程可以位于同一节点上,也可以分布在多个不同的节点上。通信越快,系统的整体运行速度就越快。
当两个进程进行通信时,通常是一个进程向另一个进程传递数据,或者双方互相交换数据。如果进程间通信效率低下,整个系统可能会陷入停滞。因此,确保通信高效极为重要。
本章我们将学习分布式系统中高效的数据传输机制。首先从使用数据库实现数据流转开始。
使用数据库实现数据流动
数据库是任何系统的核心组成部分。一个进程将数据写入数据库,另一个进程则读取该数据。有时,读写操作甚至可以由同一个进程完成——即当前写入数据,稍后再次读取。
在大型系统中,同时有多个进程对同一数据库进行读写操作非常常见。这些进程可能来自同一服务的多个实例,也可能来自不同的独立服务。从数据库的角度来看,这种差异并不重要。
1<img src="http://network.jancsitech.net:9000/pageflex-ai/images/general/202509/1758383074142004775.svg" alt="使用数据库实现进程间的数据流通" />
上述场景显示,一个节点正在向数据库写入数据,而两个节点正在从该数据库读取数据。这是分布式系统中极为常见的模式。
数据库允许任意进程在任意时刻执行读或写操作。但在某些情况下,读写操作可能需要等待。例如,当两个进程同时尝试更新数据库表中的同一行时,关键问题是:哪一个应该优先执行?如果多个进程试图读取同一行数据,是否应立即允许读取,还是需要排队等待?
根据数据库架构的不同,上述情况的处理方式也有所不同。大多数情况下,只允许一个进程对某一行加锁并执行写入操作,其他试图写入的进程必须等待第一个操作完成。而在某些系统中,允许多个写入操作同时发生,并由系统自行决定最终状态。
如前所述,当某一行被写锁锁定时,读取请求是否应该被允许?还是需要等待?
这同样取决于数据库架构和系统需求。对于强一致性系统,更新中的行应对读写请求均加锁。而对于支持最终一致性的系统,则允许读取过期数据。
一个简明示例
延续上述思路,数据库在分布式系统中常被用作数据传输的媒介。系统的一部分可将输出写入数据库,另一部分则可轻松读取这些数据。
一个典型的例子是 Facebook 的“可能认识的人”功能。你可能注意到,主页动态中有时会出现一个可垂直滚动的区域,列出一些好友推荐及头像缩略图。该功能的一种可能数据流程如下:
- 头像缩略图生成服务负责从用户头像生成缩略图,并将其存储在某种数据存储中,例如 AWS 的 S3。
- 主页动态服务调用“可能认识的人”服务,以获取特定用户的推荐列表。
- “可能认识的人”服务从数据存储中读取缩略图,并返回结果。
1<img src="http://network.jancsitech.net:9000/pageflex-ai/images/general/202509/1758383081471855685.svg" alt="通过数据库实现数据通信的示例" />
上述方案只是一个简单构想,并非设计该功能最标准或最高效的实现方式。重点在于:数据库可以作为大型分布式系统中不同节点与服务器之间数据流动的一种途径。
核心要点
- 在分布式系统中,通信是必不可少的。
- 通信可以通过多种方式实现,其中一种就是使用数据库。
- 选择合适的数据库是一项关键决策,因为不同数据库针对的是不同类型的问题而设计。