[
https://issues.apache.org/jira/browse/HDDS-17622?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Siyao Meng updated HDDS-17622:
------------------------------
Affects Version/s: 2.2.1
2.0.0
1.4.0
2.1.2
2.1.0
1.4.1
2.1.1
2.2.2
1.3.0
2.2.0
> RackScatter placement fails although a rack has a writable datanode, because
> a new rack gets only one round of random picks
> ---------------------------------------------------------------------------------------------------------------------------
>
> Key: HDDS-17622
> URL: https://issues.apache.org/jira/browse/HDDS-17622
> Project: Apache Ozone
> Issue Type: Bug
> Affects Versions: 1.3.0, 1.4.0, 2.0.0, 1.4.1, 2.1.0, 2.2.0, 2.1.1, 2.1.2,
> 2.2.1, 2.2.2
> Reporter: Siyao Meng
> Priority: Minor
> Attachments:
> CR-4-retry-skipped-rack-in-rackscatter-unique-rack-phase.patch,
> TestBugCR4RackScatterSingleRoundOfPicks.java
>
>
> h3. Mechanism
> {{SCMContainerPlacementRackScatter.chooseDatanodesInternal}} first picks one
> node on each rack that holds no replica yet ("unique racks"), then fills the
> rest with a same-rack fallback. For each rack, {{chooseNode}} draws up to 5
> random nodes ({{INNER_LOOP_MAX_RETRY}}) and excludes each one that
> {{isValidNode}} rejects. {{chooseNodesFromRacks}} can retry a rack whose
> picks all missed in a later round ({{skippedRacks}}, ending after 4 rounds
> without progress, {{OUTER_LOOP_MAX_RETRY}} + 1), but the unique-rack phase
> calls it with {{maxOuterLoopIterations = maxReplicasPerRack}}. For EC on at
> least as many racks as replicas that is 1, so a rack gets a single round of 5
> picks. If those miss, the method throws {{FAILED_TO_FIND_HEALTHY_NODES}}
> ("Chosen nodes size from Unique Racks: 0, but required nodes to choose from
> Unique Racks: 1 do not match"), and the same-rack fallback is not reached.
> Full, STALE, decommissioning and maintenance datanodes stay in the network
> topology and are not in the excluded list, so on a rack where most datanodes
> cannot take a replica, 5 picks often miss the ones that can.
> h3. Trigger
> An EC container needs a target on a new rack, most datanodes of that rack are
> full or not writable, and it is the only rack without a replica, for example
> a cluster with exactly as many racks as the EC width (rs-3-2 on 5 racks).
> With more candidate racks, the first round moves on to the next rack, and the
> placement fails only if every candidate rack misses. For example rs-3-2 with
> index 1 to 4 on four racks and index 5 missing, and a fifth rack with 10
> datanodes of which one is writable: 5 picks without replacement miss it with
> probability 0.5. With 20 unusable datanodes and one writable it is 16/21
> (about 0.76).
> h3. Impact
> The placement fails although a valid target exists.
> {{ReplicationManagerUtil.getTargetDatanodes}} turns it into
> {{FAILED_TO_FIND_SUITABLE_NODE}}, {{ECUnderReplicationHandler}} rethrows, and
> the container is requeued for the next pass, which draws again. Repair still
> completes, but with failure probability p it takes p/(1-p) extra passes on
> average (the under-replicated queue is processed every 30 s by default): one
> more pass in the first layout above and about three in the second, while the
> container runs with reduced redundancy. Each failed pass also logs an ERROR
> with a stack trace, raises the container's requeue count (which sorts it
> behind others with the same remaining redundancy), and runs the handler's
> remedies for a missing target, such as deleting an UNHEALTHY replica if the
> container has one. The same applies to every caller of the EC policy, for
> example copies for decommission and mis-replication, and EC pipeline creation
> on the write path ({{ECPipelineProvider}} calls the same {{chooseDatanodes}}
> with no used nodes), where {{WritableECContainerProvider}} hides most
> failures by falling back to existing open pipelines and a second allocation
> attempt. Not measured end to end; only the per placement failure rate was run.
> HDDS-16634 reports the same kind of probe limit in
> {{SCMContainerPlacementRackAware}}, measured as a slower decommission.
> h3. Reproduction
> [^TestBugCR4RackScatterSingleRoundOfPicks.java] ({{hadoop-hdds/server-scm}},
> target path and Maven command in the class comment) builds the example above
> with a real {{NetworkTopologyImpl}} and the real policy (only {{NodeManager}}
> is a mock that returns the datanodes): rack4 has 5 full, 4 STALE and 1
> writable datanode, and rack0 to rack3 each have the used node and 2 free
> writable nodes. It runs 200 placements for one target through
> {{ReplicationManagerUtil.getTargetDatanodes}}. On unmodified source about
> half failed (102 of 200 in one run) with {{FAILED_TO_FIND_SUITABLE_NODE}},
> the other 98 chose the writable datanode of rack4, and none used the free
> nodes of rack0 to rack3. The test passes when the defect is present. With the
> patch all 200 chose the writable datanode and the test fails at the assertion
> on the failure count.
> h3. Patch
> [^CR-4-retry-skipped-rack-in-rackscatter-unique-rack-phase.patch], against
> e4ae41fc4047c99af983020b4f33bd297c9d0ac5. It also applies to master at
> 3fc2387040f.
> The unique-rack phase no longer limits {{chooseNodesFromRacks}} to
> {{maxReplicasPerRack}} rounds (the same-rack fallback already passed
> {{Integer.MAX_VALUE}}), so the existing skipped-rack retry runs: a rack whose
> picks all missed is tried again in the next round, with the rejected nodes
> still excluded, until 4 rounds bring no progress. The round limit parameter,
> now unused, is removed. The per rack limit is unchanged, so no rack gets more
> than {{maxReplicasPerRack}} nodes, and the final
> {{validateContainerPlacement}} check still applies. A placement that
> succeeded at the old limit is unchanged; only placements that used to throw
> get more picks. A rack with no usable node (as in HDDS-17362) still ends in
> the same exception, after 20 picks instead of 5, so such a failing placement
> now logs up to 4 times as many INFO lines from {{isValidNode}} and
> {{chooseNode}} on each pass. This is bounded and rack scoped, and the
> same-rack fallback already behaves this way.
> This narrows the failure, it does not remove it: a rack is now searched up to
> 20 picks instead of 5. Picks are made without replacement, so a rack of up to
> 20 datanodes is always searched completely, and the remaining failure needs a
> larger rack that is almost all unusable. With 20 unusable datanodes and one
> writable, 91 of 2000 placements still failed (1/21 expected), against about
> 76% before. Choosing only among datanodes that can take a replica would
> remove it; that is the direction of HDDS-16634 and out of scope here. Falling
> through to the same-rack fallback instead of throwing, as HDDS-16629 did for
> {{SCMContainerPlacementRackAware}} when no other rack has a writable node,
> was not taken: here another rack does have one, and the fallback would put
> the replica on a rack that already holds one, leaving the container
> mis-replicated.
> Covered by {{chooseOnlyWritableNodeOfMostlyUnusableRack}} in the existing
> {{TestSCMContainerPlacementRackScatter}}: one writable datanode among 10 on
> the only new rack must be chosen in 20 of 20 placements, and when it is made
> STALE too the placement still fails with {{FAILED_TO_FIND_HEALTHY_NODES}}.
> Without the change it fails with the "Unique Racks: 0" exception above. With
> the change, the placement policy, pipeline placement and Replication Manager
> handler suites in {{hadoop-hdds/server-scm}} pass (651 tests) and checkstyle
> is clean.
> Found by code review of the SCM EC container replication and placement repair
> paths, as part of the TLA+ verification effort under HDDS-15926, on commit
> e4ae41fc4047c99af983020b4f33bd297c9d0ac5. Checked against HDDS issues and
> apache/ozone pull requests for duplicates before filing. Related but not
> duplicates: HDDS-16634 (the probe limit in
> {{SCMContainerPlacementRackAware}}), HDDS-17362 (RackScatter counts a rack of
> out-of-service datanodes as available; the patch does not change that case
> beyond the extra picks described above). The attached patch is a proposal for
> review. Generated with Specula (Claude Opus 5.5).
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]