Skip to content

cache: replace Lock with Buffer#587

Merged
hawkw merged 13 commits intomainfrom
eliza/buffer-cache
Jul 1, 2020
Merged

cache: replace Lock with Buffer#587
hawkw merged 13 commits intomainfrom
eliza/buffer-cache

Conversation

@hawkw
Copy link
Contributor

@hawkw hawkw commented Jun 29, 2020

The use of a buffer hides some of the type complexity of the inner
service (all of the type complexity, after #586). However, Linkerd
currently only uses buffers at the Service level, not at the
MakeService level. Since MakeService/NewServices tend to be
generic over both inner MakeService types and over the produced
Services (as well as potentially two future types), they probably have
much longer concrete types than Services in most cases.

As @olix0r suggested, we can replace the Lock that's currently used to
ensure exclusive access to Caches (which are at the MakeService)s
with Buffers. The Lock is currently essentially doing something
quite similar to adding a Buffer anyway. Introducing buffers around
all caches erases the inner type for everything layered around the
cache, which should make overall type length much shorter.

This seems to have a fairly noticeable impact on build time and memory
use (see linkerd/linkerd2#4676). On my machine, running make docker on
#586 gets SIGKILLed (presumably by the OOM killer) after 7m53s. After
this change, make docker completes successfully after 1m44s.

Also, the linkerd2-lock crate can be removed, as it was used only by
Cache.

To work around increased tail latencies when the buffer fills up, this
branch also sets the default buffer capacity to be equal to the
default concurrency limit, rather than 10. This is fine, since the buffer
capacity isn't actually what enforces a bound on proxy memory use.
The spawned tasks waiting on a full buffer are still sitting on the Tokio
executor, and it's actually the in flight limit that stops us from accepting
any more requests when we have too many in flight.

Depends on #586.
Fixes linkerd/linkerd2#4676.

Signed-off-by: Eliza Weisman [email protected]

olix0r and others added 5 commits June 29, 2020 17:32
The buffer middleware is parameterized on the inner service's repsonse
future, which "leaks" the inner service's type to the outer components
(which slows down compilations).

This changes the signature to instead be parameterized by the response
type, boxing the inner service's response future to avoid exposing its
type signature.
@hawkw hawkw requested review from a team, kleimkuhler and olix0r June 29, 2020 21:36
@hawkw hawkw self-assigned this Jun 29, 2020
Comment on lines -241 to -243
// Prevent the cache's lock from being acquired in poll_ready, ensuring this happens
// in the response future. This prevents buffers from holding the cache's lock.
.push_oneshot()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the oneshots here were only necessary due to implementation details of Cache (acquiring the lock in poll_ready), so they are now removeable.

.push(metrics.stack.layer(stack_labels("profile"))),
),
)
.spawn_buffer(buffer_capacity)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

i wasn't sure if we wanted to put an idle timeout here or not. i think we only want that at the request level?

Copy link
Member

Choose a reason for hiding this comment

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

i think that's right -- because the idle timeout is part of cache eviction. i'll give this a closer look though.

Base automatically changed from ver/buffer-opaque to main June 30, 2020 18:50
@hawkw hawkw merged commit f897208 into main Jul 1, 2020
@hawkw hawkw deleted the eliza/buffer-cache branch July 1, 2020 21:13
olix0r added a commit to linkerd/linkerd2 that referenced this pull request Jul 2, 2020
This release increases the default buffer size to match the proxy's
in-flight request limit. This reduces contention in overload--especially
high-concurrency--situations, substantially reducing tail latency.

---

* update test-support clients and servers to be natively async (linkerd/linkerd2-proxy#580)
* Print build diagnostics in docker (linkerd/linkerd2-proxy#583)
* update test controllers to std::future/Tonic; remove threads (linkerd/linkerd2-proxy#585)
* buffer: Box the inner service's reponse future (linkerd/linkerd2-proxy#586)
* Eliminate Bind & Listen traits (linkerd/linkerd2-proxy#584)
* cache: replace Lock with Buffer (linkerd/linkerd2-proxy#587)
cpretzer pushed a commit to linkerd/linkerd2 that referenced this pull request Jul 2, 2020
This release increases the default buffer size to match the proxy's
in-flight request limit. This reduces contention in overload--especially
high-concurrency--situations, substantially reducing tail latency.

---

* update test-support clients and servers to be natively async (linkerd/linkerd2-proxy#580)
* Print build diagnostics in docker (linkerd/linkerd2-proxy#583)
* update test controllers to std::future/Tonic; remove threads (linkerd/linkerd2-proxy#585)
* buffer: Box the inner service's reponse future (linkerd/linkerd2-proxy#586)
* Eliminate Bind & Listen traits (linkerd/linkerd2-proxy#584)
* cache: replace Lock with Buffer (linkerd/linkerd2-proxy#587)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

proxy build responsible for 10% of the world's carbon production

3 participants