Database design 对加权有向图进行分区(在键/值数据库上)

Database design 对加权有向图进行分区(在键/值数据库上),database-design,graph,nosql,redis,distributed-computing,Database Design,Graph,Nosql,Redis,Distributed Computing,我们想要切分一个加权有向图 用户可以动态添加节点和边,首先DB/Graph为空 我们将节点和边保存在一个键/值数据库中(可能):对于每个节点,我们将使用nodeId作为键,并使用引用节点的键的sortedset。sortedset中每个nodeId的分数是边的权重 (见此处有关问题:) 我们没有平衡约束,图上最常见的操作是Dijkstra,我们希望最小化I/O(在我们的例子中是网络) 可能的解决方案:每个DB服务器都包含一个具有IP的其他服务器列表: 键:server1,值:……250.1 键:

我们想要切分一个加权有向图

用户可以动态添加节点和边,首先DB/Graph为空

我们将节点和边保存在一个键/值数据库中(可能):对于每个节点,我们将使用nodeId作为键,并使用引用节点的键的sortedset。sortedset中每个nodeId的分数是边的权重

(见此处有关问题:)

我们没有平衡约束,图上最常见的操作是Dijkstra,我们希望最小化I/O(在我们的例子中是网络)

可能的解决方案:每个DB服务器都包含一个具有IP的其他服务器列表:

键:server1,值:……250.1

键:server2,值:……250.2

键:server3,值:……250.3

每个nodeId都将是serverX.originalNodeId

决定哪个节点去哪里的算法是什么?我们应该支持节点的重新定位吗


我想最简单的方法是,将节点A添加到serverX,其中argmax(服务器X中与节点A有边的节点的数量)只要serverX没有被完全占用。

由于处理发生在客户端,这种图形数据不太难分片-每一步只需要一个排序集,因此,从哪个节点加载集合并不重要。获取节点的实际数据是最后一步——如果只有一个节点,那么这将是一个简单的MGET,并且很容易在多个节点之间分割

要确定密钥将存储在哪个节点上,您应该使用哈希,而不是尝试手动跟踪它们。我使用一个表将一系列散列映射到一个特定的节点。它存储在redis中用于长期持久性,但实际上是客户端的一部分。要访问某个特定的密钥,只需获取该密钥的哈希值,在表中查找它,然后连接到该节点。使用一个有数千个插槽的表可以很容易地将数据移动到另一个节点-更新该表,对特定插槽的请求将转移到另一个节点。这与redis集群中使用的方法非常相似,但并不完全相同


也就是说,我设置切分的原因不是图形数据。仅包含ID的小排序集不会占用太多内存-您应该能够在单个节点上处理1亿条边,而不会有太多麻烦。

“碎片”?我一定是老了。这意味着什么?这里的主要问题是,我希望尽可能将连接的图形节点保持在同一台机器上,哈希方法没有考虑到这一点……您使用的是redis脚本吗?否则,将节点保持在一起并不重要。此外,如果连接的节点有时只在同一台服务器上,您可能会发现,选择一台服务器的复杂过程的开销比经常转到另一台容易识别的服务器更大。只有在不知道第一个结果的情况下发送所有命令,才能获得更好的性能-我认为这里不是这种情况,即使是这样,您也可以通过并行地将命令发送到多个节点来获得相同/更好的性能。缩小规模有点困难,因为您无法轻松合并节点,但在一台服务器上运行多个节点可以让您非常接近