Visitar URL original
[improvement](fe) Share CloudReplica route identifiers by deardeng · Pull Request #68783 · apache/doris · GitHub
Skip to content

[improvement](fe) Share CloudReplica route identifiers - #68783

Merged
deardeng merged 1 commit into
apache:masterfrom
deardeng:improvement/cloud-replica-route-object-sharing
Oct 9, 2026
Merged

deardeng merged 1 commit into
apache:masterfrom
deardeng:improvement/cloud-replica-route-object-sharing

Conversation

@deardeng

@deardeng deardeng commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: #67636

Problem Summary: CloudReplica image deserialization created independent String cluster IDs and boxed Long backend IDs for equivalent routes. The tested production image contains 4,197,906 replicas and 62,708,955 routes but only 15 cluster IDs and about 85 backend IDs, so millions of equal route identifiers retained duplicate heap objects. Canonical sharing reduced forced-GC live heap from 15,311,045,744 bytes to 8,539,550,968 bytes, saving 6,771,494,776 bytes (6.31 GiB, 44.2%).

Intern cluster IDs and primary backend IDs on route updates and after image deserialization so equal routes reuse the same objects. Use Guava weak interners instead of strong process-lifetime maps: active routes keep canonical objects alive, while identifiers become collectable after their last route is removed. Routing behavior and the serialized image format are unchanged.

The full 6.93 GB image completed compatibility load and dump with the final weak-interner implementation. A clean run loaded in 225.679 seconds and dumped in 145.935 seconds. JFR attributed 255 of 18,139 load-stage CPU samples (1.41%) to the interner path, with no sampled allocations attributed directly to it.

Release note

Reduce FE heap usage for CloudReplica routing metadata and release unused historical route identifiers.

Check List (For Author)

  • Test: Unit Test / Manual test
    • CloudReplicaTest: 23 tests passed
    • ./build.sh --fe passed with Checkstyle 0 violations
    • Full production image compatibility load and dump passed
    • JFR profile verified the interner path is not a load hotspot
  • Behavior changed: Yes; equal in-memory route identifiers are shared and unused canonical identifiers can be reclaimed, without changing routing results or image serialization
  • Does this need documentation: No

What problem does this PR solve?

Issue Number: close #xxx

Related PR: #xxx

Problem Summary:

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

### What problem does this PR solve?

Issue Number: None

Related PR: apache#67636

Problem Summary: CloudReplica image deserialization created independent String cluster IDs and boxed Long backend IDs for equivalent routes. The tested production image contains 4,197,906 replicas and 62,708,955 routes but only 15 cluster IDs and about 85 backend IDs, so millions of equal route identifiers retained duplicate heap objects. Canonical sharing reduced forced-GC live heap from 15,311,045,744 bytes to 8,539,550,968 bytes, saving 6,771,494,776 bytes (6.31 GiB, 44.2%).

Intern cluster IDs and primary backend IDs on route updates and after image deserialization so equal routes reuse the same objects. Use Guava weak interners instead of strong process-lifetime maps: active routes keep canonical objects alive, while identifiers become collectable after their last route is removed. Routing behavior and the serialized image format are unchanged.

The full 6.93 GB image completed compatibility load and dump with the final weak-interner implementation. A clean run loaded in 225.679 seconds and dumped in 145.935 seconds. JFR attributed 255 of 18,139 load-stage CPU samples (1.41%) to the interner path, with no sampled allocations attributed directly to it.

### Release note

Reduce FE heap usage for CloudReplica routing metadata and release unused historical route identifiers.

### Check List (For Author)

- Test: Unit Test / Manual test
    - CloudReplicaTest: 23 tests passed
    - ./build.sh --fe passed with Checkstyle 0 violations
    - Full production image compatibility load and dump passed
    - JFR profile verified the interner path is not a load hotspot
- Behavior changed: Yes; equal in-memory route identifiers are shared and unused canonical identifiers can be reclaimed, without changing routing results or image serialization
- Does this need documentation: No
@deardeng
deardeng requested a review from gavinchou as a code owner October 8, 2026 09:18
@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@deardeng

deardeng commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@deardeng

deardeng commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Complete static review of PR #68783 at b26ee79. I found no substantiated new inline issues and no still-applicable existing P0/P1 comments. Both changed files and their related route, image, replay, and cleanup paths were reviewed. No additional user focus points were supplied.

Critical checkpoints:

  • Goal, scope, and tests: Weak interning shares equal primary cluster/backend identifiers on updates and image load, and shares secondary cluster identifiers on live updates. The change is confined to CloudReplica and focused unit tests. The inspected tests check identity on updates, current and legacy image formats, JSON equality, and collection after route removal. They were not run in this review.
  • Concurrency and locks: Query routing, rebalancing, and catalog replay can update routes concurrently through ConcurrentHashMap. The shared interners are concurrency-safe and map operations use value equality. Image post-processing completes in Gson's read adapter before the replica is returned to callers, so replacing its map does not race with published route updates. No new explicit locks, lock ordering, blocking I/O, or heavy work under a catalog lock were found.
  • Lifecycle: Live map entries strongly retain their canonical keys and values; the weak interners allow unused identifiers to be collected after route removal. Static initialization has no cross-unit dependency or ownership cycle. Secondary routes are omitted from ordinary images by Doris's annotation-based serialization rule and are interned when recreated at runtime.
  • Configuration and compatibility: No config, function symbol, FE/BE field, or persisted format changed. Current be and legacy bes maps both reach the new canonicalization after legacy migration and stale-route cleanup. Journal replay uses the same primary update method; no new failover or transaction persistence gap was found.
  • Parallel paths and conditions: Primary assignments from query fallback, rebalancer, warmup, and replay use the updated method; secondary fallback and smooth upgrade use the updated secondary method. Existing route cleanup and value-based lookup semantics remain intact. The new condition-free interner helpers do not introduce a special-case behavior change.
  • Coverage and results: Existing tests cover stale-route cleanup and fallback behavior; new tests cover the changed object-sharing paths. No regression result file changed. The PR description reports FE unit/build and production-image checks, but this review did not independently execute builds, tests, or the image load, as required by the review instructions.
  • Observability, data writes, and performance: No data write or visibility path changed, and existing route logs remain applicable; new metrics or logs are not needed for object sharing. Image load creates one transient replacement map per replica and route writes add interner lookups, but the inspection found no concrete material regression. The stated heap and JFR measurements are author-provided, not independently reproduced here.

One candidate about secondary routes surviving image reload was withdrawn after confirming the secondary map is excluded from normal image serialization. All three independent review passes returned NO_NEW_VALUABLE_FINDINGS after that correction, and the final changed-file sweep left no unresolved points. Review complete.

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 29085 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit b26ee79fd8f42e18fe468e5c021ade9ab7221b5e, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17571	5634	5565	5565
q2	2158	322	254	254
q3	10199	1395	849	849
q4	4678	488	348	348
q5	7433	796	539	539
q6	197	193	156	156
q7	784	821	611	611
q8	9253	1370	1185	1185
q9	5736	4504	4515	4504
q10	6816	1299	1033	1033
q11	450	255	241	241
q12	634	400	295	295
q13	18082	3102	2375	2375
q14	277	279	240	240
q15	q16	745	731	696	696
q17	1209	749	577	577
q18	7173	6253	6179	6179
q19	1132	974	619	619
q20	409	345	227	227
q21	5166	2316	2453	2316
q22	371	316	276	276
Total cold run time: 100473 ms
Total hot run time: 29085 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	6206	6113	6133	6113
q2	676	588	545	545
q3	5208	5443	4937	4937
q4	2080	2187	1619	1619
q5	5324	5436	6001	5436
q6	255	200	161	161
q7	2379	2112	1929	1929
q8	3348	3093	2944	2944
q9	8360	8284	8308	8284
q10	3777	3687	3344	3344
q11	673	456	409	409
q12	710	746	584	584
q13	2861	3197	2501	2501
q14	334	316	283	283
q15	q16	729	730	663	663
q17	8702	7680	7537	7537
q18	13229	12397	13179	12397
q19	1019	950	932	932
q20	2249	2229	1983	1983
q21	6194	4835	5093	4835
q22	521	480	396	396
Total cold run time: 74834 ms
Total hot run time: 67832 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 152458 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit b26ee79fd8f42e18fe468e5c021ade9ab7221b5e, data reload: false

query5	4307	592	425	425
query6	421	208	196	196
query7	4795	452	222	222
query8	327	190	167	167
query9	8757	4041	4004	4004
query10	459	323	256	256
query11	5954	3422	3195	3195
query12	138	86	83	83
query13	1241	431	321	321
query14	6538	4727	4480	4480
query14_1	4249	4288	4233	4233
query15	212	208	192	192
query16	968	485	427	427
query17	822	637	514	514
query18	2402	425	300	300
query19	190	164	128	128
query20	78	78	75	75
query21	209	131	109	109
query22	12998	12927	12902	12902
query23	13265	12623	12239	12239
query23_1	12180	12320	12121	12121
query24	7096	817	446	446
query24_1	456	447	469	447
query25	502	389	337	337
query26	1299	253	138	138
query27	2771	430	272	272
query28	4632	1932	1939	1932
query29	1514	579	436	436
query30	296	211	189	189
query31	883	783	646	646
query32	134	93	82	82
query33	501	295	226	226
query34	893	861	499	499
query35	728	769	654	654
query36	849	813	745	745
query37	160	105	85	85
query38	1775	1761	1698	1698
query39	696	708	675	675
query39_1	652	660	681	660
query40	216	113	93	93
query41	64	65	60	60
query42	87	82	79	79
query43	373	381	323	323
query44	1279	687	688	687
query45	182	178	158	158
query46	824	960	562	562
query47	2884	3073	2940	2940
query48	299	301	221	221
query49	577	416	296	296
query50	669	274	211	211
query51	10411	10511	10426	10426
query52	81	86	74	74
query53	186	209	161	161
query54	232	182	177	177
query55	81	63	62	62
query56	249	215	196	196
query57	1598	1599	1578	1578
query58	277	257	250	250
query59	2380	2399	2136	2136
query60	275	233	221	221
query61	145	151	138	138
query62	394	336	281	281
query63	197	156	164	156
query64	2710	974	892	892
query65	3430	3366	3375	3366
query66	1779	426	325	325
query67	20114	20285	19982	19982
query68	3255	976	603	603
query69	387	293	262	262
query70	934	841	838	838
query71	313	238	218	218
query72	2919	2748	2643	2643
query73	519	532	298	298
query74	4606	4473	4299	4299
query75	2356	2288	1942	1942
query76	2311	1007	614	614
query77	362	398	301	301
query78	9205	9057	8509	8509
query79	940	880	516	516
query80	764	414	343	343
query81	560	319	269	269
query82	582	133	108	108
query83	274	195	178	178
query84	312	121	101	101
query85	946	428	363	363
query86	344	244	234	234
query87	1999	1949	1823	1823
query88	3588	2683	2667	2667
query89	341	300	258	258
query90	1791	184	178	178
query91	156	148	128	128
query92	99	82	93	82
query93	992	982	548	548
query94	490	296	282	282
query95	597	347	317	317
query96	663	516	227	227
query97	2451	2440	2314	2314
query98	182	189	166	166
query99	776	763	656	656
Total cold run time: 234092 ms
Total hot run time: 152458 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.61 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit b26ee79fd8f42e18fe468e5c021ade9ab7221b5e, data reload: false

query1	0.00	0.00	0.01
query2	0.10	0.04	0.05
query3	0.27	0.12	0.11
query4	1.60	0.12	0.13
query5	0.24	0.22	0.25
query6	1.17	0.69	0.68
query7	0.04	0.01	0.01
query8	0.06	0.04	0.04
query9	0.42	0.35	0.34
query10	0.58	0.57	0.58
query11	0.20	0.15	0.13
query12	0.18	0.14	0.14
query13	0.49	0.50	0.50
query14	1.00	0.97	0.96
query15	0.65	0.60	0.61
query16	0.36	0.36	0.36
query17	1.17	1.19	1.13
query18	0.22	0.20	0.20
query19	2.03	1.97	2.04
query20	0.02	0.01	0.02
query21	15.49	0.28	0.15
query22	4.49	0.06	0.06
query23	16.26	0.33	0.12
query24	2.63	1.01	0.42
query25	0.09	0.07	0.04
query26	1.68	0.26	0.15
query27	0.05	0.05	0.04
query28	2.52	0.64	0.43
query29	12.51	4.16	3.28
query30	0.27	0.14	0.13
query31	2.77	0.59	0.34
query32	3.22	0.62	0.51
query33	3.27	3.28	3.26
query34	15.49	4.01	3.41
query35	3.34	3.35	3.34
query36	0.53	0.45	0.47
query37	0.10	0.06	0.07
query38	0.06	0.04	0.03
query39	0.04	0.03	0.03
query40	0.16	0.14	0.14
query41	0.10	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 95.95 s
Total hot run time: 24.61 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 100.00% (10/10) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 100.00% (10/10) 🎉
Increment coverage report
Complete coverage report

@deardeng
deardeng merged commit 818d3f6 into apache:master Oct 9, 2026
47 of 48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants