我们希望对加权有向图进行分片,
用户可以动态添加节点和边缘,首先DB / Graph为空。
我们将节点和边缘保存在键/值数据库中(可能是Redis):对于每个节点,我们将nodeId作为键,并将引用节点的键的一组排序,每个nodeId的得分sortedSet是边缘的权重。
(请参阅此处的问题:Redis: Implement Weighted Directed Graph)
我们没有平衡约束,图中最常见的操作是Dijkstra,我们希望最小化I / O(在我们的例子中是网络)
可能的解决方案:每个数据库服务器都包含其他具有IP的服务器列表:
key:server1,value:.... 250.1
key:server2,value:.... 250.2
key:server3,value:.... 250.3
并且每个nodeId将是serverX.originalNodeId
决定哪个节点在哪里的算法是什么?我们应该支持重新定位节点吗?
我猜这个天真的方法是,将节点A添加到serverX,其中argmax(服务器X中具有节点A边缘的节点数),只要serverX没有完全占用..
答案 0 :(得分:2)
由于处理发生在客户端,因此这种图形数据并不太难分片 - 每个步骤所需的只是一个有序集合,因此从哪个节点加载无关紧要。获取实际数据与节点一起发生作为最后一步 - 如果您只有一个节点,那将是一个简单的MGET,并且相当容易分割到多个节点。
要确定密钥将存储在哪个节点上,您应该使用哈希而不是尝试手动跟踪它们。我使用一个表将一系列哈希映射到特定节点。它存储在redis中以实现长期持久性,但实际上是客户端的一部分。要访问特定密钥,只需获取密钥的哈希值,在表中查找,然后连接到该节点。使用具有数千个插槽的表可以轻松地将数据移动到另一个节点 - 更新表并且特定插槽的请求将转到不同的节点。这与redis集群中使用的方法非常相似。
那就是说,我设置分片的原因不是图形数据。仅包含ID的小型排序集不占用大量内存 - 您应该能够在单个节点上处理1亿条边,而不会有太多麻烦。