membphis commented on PR #14141:
URL: https://github.com/apache/apisix/pull/14141#issuecomment-6623017268

   @AlinsRan, I completed an independent local before/after run against base 
`6205e4a568106eea8277f61ae6ef942bbff62d97` and PR head 
`1e8b72e1ae8cf63197ab45659137442925e077a8`.
   
   ### P2: the limiter-object cache regresses high-cardinality dynamic quotas
   
   The stable-quota case improves, but cycling through 4,096 valid resolved 
counts makes the new 1,024-entry limiter cache churn. Throughput fell in all 
eight paired runs, by 11.3% to 22.7%.
   
   | Scenario / metric | Before | After | Change |
   | --- | ---: | ---: | ---: |
   | Stable resolved count, requests/sec | 15,106 | 18,293 | +21.1% |
   | 4,096 rotating counts, requests/sec | 14,902 | 11,926 | -20.0% |
   | 4,096 rotating counts, worker CPU per request | 66.81 us | 83.47 us | 
+24.9% |
   | Stable count, Lua allocation per request | 11,698 B | 2,193 B | -81.3% |
   | Rotating counts, Lua allocation per request | 11,645 B | 2,773 B | -76.2% |
   
   The route uses local policy and one rule:
   
   ```json
   {"count":"${http_count ?? 
1000000000}","time_window":60,"key":"${host}:${uri}","header_prefix":"one"}
   ```
   
   The single wrk thread cycles the `Count` header through `1000000000 + n % 
4096`. The URI and rate-limit key stay fixed, and all benchmark requests return 
200. This exercises supported request-resolved quotas without exhausting the 
counter.
   
   I also ran three diagnostic pairs using a temporary copy of the PR head, 
replacing only the [limiter-cache 
call](https://github.com/apache/apisix/blob/1e8b72e1ae8cf63197ab45659137442925e077a8/apisix/plugins/limit-count/init.lua#L575)
 with `create_limit_obj(conf, rule, name)`. Median throughput recovered from 
12,059 to 17,717 requests/sec, and worker CPU fell from 82.57 to 56.18 
us/request. The template, header-name and key-prefix caches remained enabled.
   
   This is a merge blocker for workloads whose resolved quota working set 
exceeds the cache capacity: the optimization adds significant CPU cost to an 
existing request path. Please avoid filling/evicting this cache for low-reuse 
dynamic quota values; retaining direct construction for request-derived quotas 
is a simple fallback. Keep the other caches and add an above-capacity benchmark 
when revising this path.
   
   ### Regression coverage
   
   Ran all 29 relevant files: `limit-count*.t`, `graphql-limit-count*.t`, 
`proxy-rewrite*.t`, and `t/core/utils.t`.
   
   - Before: 2,263 assertions; after: 2,321 assertions.
   - Both revisions passed 28/29 files. The same two existing DNS assertions in 
`utils.t` (TEST 9 and TEST 11) failed on this host. All other assertions, 
including the new template/cache cases, passed. No new functional failures were 
found.
   - Redis MONITOR confirmed unchanged command counts per limiter invocation: 
fixed window 1 with a warm script / 2 with a cold script; sliding window 2 / 3 
respectively. Internal Redis Lua commands were excluded from the network-call 
count.
   
   Runtime: the CI-pinned APISIX runtime 1.4.2, with the package SHA256 checked 
against the repository's installer. Performance numbers are medians of eight 
interleaved before/after pairs, each with a fresh gateway, one worker pinned to 
a physical core, a one-second warm-up and a five-second measurement, wrk with 
one thread and 100 connections, and a separate mock-upstream core. CPU comes 
from the gateway worker's process counters. Lua allocation uses three 
2,000-request samples with GC paused only during that measurement.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to