GitHub - Kareem-Emad/redis-grid: Redis的分布式分片网格源码实现

20-11-12 banq

分布式缓存层的基本实现,主要用于Redis服务器,以支持分片数据和在多台服务器上分配负载。

通常,我们有一个Redis服务器实例已启动并正在运行,任何对读/写缓存感兴趣的人都将与该服务器联系并获得所需的结果。Redis超级快,因为它可以从内存中为您提供服务。但是我们如何在不同的机器之间分配内存?

我们希望能够做像Envoy一样的事情。

我们需要有一个代理服务器,它可以与任何要从缓存中写入/读取的客户端进行通信,并隐藏所有与我们实际使用多少Redis实例来存储此缓存信息或该信息如何使用有关的信息。路由/存储在每个实例中。

这里出现的一个典型问题是我们如何分配数据。我们如何在代理级别记住例如key为X的存储位置?

我们在写入数据时上也有问题。我们几乎必须能够在实例之间分配key,以使我们不会在其中一个实例过载的同时又使其他实例空闲。

通过使用以下过程,每次有key时,我们都可以知道在哪里存储和从哪里读取数据:

  • 从客户端检索key和带有args的命令。
  • 哈希键
  • 确定此哈希值属于哪个服务器(可以是范围或离散值)

就是这样!现在,我们可以轻松地构建分布式缓存。

我们仍然需要找到用于对key进行哈希处理的最佳哈希函数。这是因为如果我们继续对新键进行哈希运算,则如果函数将所有选择的键名哈希运算到同一服务器上,它们都可能最终位于同一存储桶或服务器中!

此外,在处理代理服务器下运行服务器数量的增加或减少时,我们还有另一个问题。假设我们使用此哈希函数将值哈希到服务器server = hash(key) mod NumServers。使用此功能,我们可以根据当前拥有的服务器数量分配key。分配不是线性的,因此没有对键进行排序,因此A,B,C在S1中,D在S2中,依此类推。

如果我们的一台服务器由于某种原因而关闭怎么办?现在我们必须减少NumServers-1对吗?这实际上是灾难性的,因为现在有了新的模,我们已经散列的值已更改。现在可以将已存储在S1中的key定向到S2,反之亦然。这将导致我们对所有服务器进行全面检查,以重新哈希所有key-哎呀!

我们需要一种更好的方法来对密钥进行哈希处理,以便每当必须从池中添加/删除服务器时,我们将花费最少的精力。

 

一致性哈希

一致哈希:每个服务器都有一个圆圈度数范围,每当将一个新值哈希值对应圆圈中时,我们将只检查该值落入哪个范围。让我们来看一个场景:添加一个新服务器。

每当添加新服务器时,我们都会为该服务器分配一个新位置。我们将此服务器称为D。当然,该服务器将落在圈子中的其他两个服务器之间(例如B和C),因此我们将D放在B和C之间的中间位置。

我们的工作流程:

  • 我们首先从代理处的客户端接收命令详细信息和key。
  • 然后,我们将key哈希到圆圈中某个度数。
  • 检查此键属于哪个范围/地区。
  • 分配/从区域读取key。
  • 从缓存服务器接收响应,并将其发回客户端。

我们做了一个简单的架构,类似于其主要持有框架中的Envoy代理。

源码实现点击标题

 

         

猜你喜欢