数据库查询的神奇技巧:挽救你的数据世界

发表时间: 2024-01-03 08:30

这个妙不可言的处理数据库查询的技巧,可以说是挽救了Discord。

它帮助Discord存储并检索了数万亿条信息,而且在整个过程中,他们的数据库集群都保持运转良好。

这个妙法就叫做请求合并(Request Coalescing)。

它的作用如此关键,实在不容忽视。

但是,为什么这个技术如此出色呢?

如果多个用户同时请求同一条信息,为何不只在数据库中查询一次呢?

这正是请求合并技术可以帮我们做到的。

下面是后台发生的详细过程(参见下图):

✅第一个发出请求的用户会启动数据服务中的一个工作任务。

✅对同一数据的后续请求会检查这个工作任务是否存在,如果存在则订阅这个任务。

✅一旦初始的工作任务查询了数据库并获得结果,它就会同时将结果返回给所有的订阅者。

使用请求合并技术有许多优势:

[1] 可以更有效地利用数据库资源。

[2] 能处理更多的并发请求,而不会产生过热的数据库区域。

[3] 可以降低延迟时间。

但也必须承认,这个技术有一些限制:

[1] 实现起来可能相当复杂,因为需要实现公平的分布式读写锁。说到底,我们需要让多个读取器同时访问数据,同时也要防止写入数据时发生冲突。

[2] 尽管总体上的延迟可能会降低,但某些请求可能需要更多的时间。

使用这个技术,我们需要考虑一些重要问题:

✅ 请求合并与缓存有什么不同?

使用请求合并的话,只有一个请求者会实际去触发对存储组件的查询,其他的请求则只是订阅这个请求。而使用缓存的话,所有的请求都会命中缓存。

✅ 为什么不直接使用缓存就好?

请求合并并不是要取代缓存。

你甚至可以在一个缓存基础上添加请求合并。毕竟,它的重点是减少针对数据源的请求次数。

✅ 在Discord的案例中,这个技术是如何实施的?

Discord并未正式公开他们的实施细节,不过我在论坛上找到了一些相关信息。

每个工作任务都有自己的本地状态,它实际上就是一个储存了请求和等待回应的发送方列表的哈希地图。

每当有回应传入,他们就会从哈希地图中移除请求,并将结果反馈给所有的请求者。

一般来说,我们并不需要使用请求合并技术。但在某些规模较大的情况下,它其实可以挽救你的业务。

那么你对这种技术怎么看呢?

你认为它是有益的,还是可能会带来问题呢?