mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-22 06:22:38 +00:00
ec distribution: merge repeat node registrations
A shard location now auto-registers an unknown node with no free slots; a later AddNode carrying the real capacity was then dropped entirely. Repeat registration now updates the node's capacity and adopts any new shards, while the first registration keeps the topology placement.
This commit is contained in:
@@ -16,15 +16,21 @@ func NewTopologyAnalysis() *TopologyAnalysis {
|
||||
}
|
||||
|
||||
// AddNode registers a node in the topology, including any shards it already
|
||||
// holds for the volume being analyzed. A node id may only register once.
|
||||
// holds for the volume being analyzed. A node id may only register once;
|
||||
// registering it again updates its capacity and adds any new shards. The
|
||||
// first registration wins for the node's place in the topology.
|
||||
func (a *TopologyAnalysis) AddNode(node *TopologyNode) {
|
||||
if _, ok := a.AllNodes[node.NodeID]; ok {
|
||||
return
|
||||
}
|
||||
a.AllNodes[node.NodeID] = node
|
||||
a.RackToNodes[rackKey(node.DataCenter, node.Rack)] = append(a.RackToNodes[rackKey(node.DataCenter, node.Rack)], node)
|
||||
if !contains(a.DCToRacks[node.DataCenter], node.Rack) {
|
||||
a.DCToRacks[node.DataCenter] = append(a.DCToRacks[node.DataCenter], node.Rack)
|
||||
registered, ok := a.AllNodes[node.NodeID]
|
||||
if !ok {
|
||||
registered = node
|
||||
a.AllNodes[node.NodeID] = node
|
||||
a.RackToNodes[rackKey(node.DataCenter, node.Rack)] = append(a.RackToNodes[rackKey(node.DataCenter, node.Rack)], node)
|
||||
if !contains(a.DCToRacks[node.DataCenter], node.Rack) {
|
||||
a.DCToRacks[node.DataCenter] = append(a.DCToRacks[node.DataCenter], node.Rack)
|
||||
}
|
||||
} else {
|
||||
registered.FreeSlots = node.FreeSlots
|
||||
registered.TotalShards = node.TotalShards
|
||||
}
|
||||
seen := node.ShardIDs[:0]
|
||||
for _, shardID := range node.ShardIDs {
|
||||
@@ -36,9 +42,9 @@ func (a *TopologyAnalysis) AddNode(node *TopologyNode) {
|
||||
for _, shardID := range node.ShardIDs {
|
||||
a.AddShardLocation(ShardLocation{
|
||||
ShardID: shardID,
|
||||
NodeID: node.NodeID,
|
||||
DataCenter: node.DataCenter,
|
||||
Rack: node.Rack,
|
||||
NodeID: registered.NodeID,
|
||||
DataCenter: registered.DataCenter,
|
||||
Rack: registered.Rack,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +157,20 @@ func TestTopologyAnalysisDuplicateNode(t *testing.T) {
|
||||
assert.Equal(t, 2, a.ShardsByNode["n1"])
|
||||
}
|
||||
|
||||
// A node auto-registered by a shard location gets its real capacity when the
|
||||
// node itself registers later, plus any shards the location did not mention.
|
||||
func TestTopologyAnalysisNodeCapacityLateRegistration(t *testing.T) {
|
||||
a := NewTopologyAnalysis()
|
||||
a.AddShardLocation(ShardLocation{ShardID: 0, NodeID: "n1", DataCenter: "dc1", Rack: "r1"})
|
||||
a.AddNode(makeNode("n1", "dc1", "r1", 10, 1))
|
||||
a.Finalize()
|
||||
|
||||
assert.Equal(t, 10, a.AllNodes["n1"].FreeSlots)
|
||||
assert.Equal(t, []int{0, 1}, a.AllNodes["n1"].ShardIDs)
|
||||
assert.Equal(t, 2, a.ShardsByNode["n1"])
|
||||
assert.Len(t, a.RackToNodes[rackKey("dc1", "r1")], 1)
|
||||
}
|
||||
|
||||
// Shards may be registered either through TopologyNode.ShardIDs or through
|
||||
// AddShardLocation — both must leave the node holding the shards.
|
||||
func TestTopologyAnalysisAddShardLocation(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user