]> git.ipfire.org Git - thirdparty/squid.git/commit
Collapse internal revalidation requests (SMP-unaware caches).
authorEduard Bagdasaryan <eduard.bagdasaryan@measurement-factory.com>
Sat, 23 Jul 2016 13:36:56 +0000 (01:36 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Sat, 23 Jul 2016 13:36:56 +0000 (01:36 +1200)
commit1a210de4cfe348c315f1334f4303ee73a45ef7cf
tree42737c5d5c6e7d32a93b9f4715412e8ba8a39dfb
parent6008010b939e6a0e0e33597d09f446c92c9004d6
Collapse internal revalidation requests (SMP-unaware caches).

... also address Bug 4311 and partially address Bug 2833 and Bug 4471.

Extend collapsed_forwarding functionality to internal revalidation
requests. This implementation does not support Vary-controlled cache
objects and is limited to SMP-unaware caching environments, where each
Squid worker knows nothing about requests and caches handled by other
workers. However, it also lays critical groundwork for future SMP-aware
collapsed revalidation support.

Prior to these changes, multiple concurrent HTTP requests for the same
stale cached object always resulted in multiple internal revalidation
requests sent by Squid to the origin server. Those internal requests
were likely to result in multiple competing Squid cache updates, causing
cache misses and/or more internal revalidation requests, negating
collapsed forwarding savings.

Internal cache revalidation requests are collapsed if and only if
collapsed_forwarding is enabled. There is no option to control just
revalidation collapsing because there is no known use case for it.

* Public revalidation keys

Each Store entry has a unique key. Keys are used to find entries in the
Store (both already cached/swapped_out entries and not). Public keys are
normally tied to the request method and target URI. Same request
properties normally lead to the same public key, making cache hits
possible. If we were to calculate a public key for an internal
revalidation request, it would have been the same as the public key of
the stale cache entry being revalidated. Adding a revalidation response
to Store would have purged that being-revalidated cached entry, even if
the revalidation response itself was not cachable.

To avoid purging being-revalidated cached entries, the old code used
private keys for internal revalidation requests. Private keys are always
unique and cannot accidentally purge a public entry. On the other hand,
for concurrent [revalidation] requests to find the store entry to
collapse on, that store entry has to have a public key!

We resolved this conflict by adding "scope" to public keys:

* Regular/old public keys have default empty scope (that does not affect
  key generation). The code not dealing with collapsed revalidation
  continues to work as before. All entries stored in caches continue to
  have the same keys (with an empty scope).

* When collapsed forwarding is enabled, collapsable internal
  revalidation requests get public keys with a "revalidation" scope
  (that is fed to the MD5 hash when the key is generated). Such a
  revalidation request can find a matching store entry created by
  another revalidation request (and collapse on it), but cannot clash
  with the entry being revalidated (because that entry key is using a
  different [empty] scope).

This change not only enables collapsing of internal revalidation
requests within one worker, but opens the way for SMP-aware workers to
share information about collapsed revalidation requests, similar to how
those workers already share information about being-swapped-out cache
entries.

After receiving the revalidation response, each collapsed revalidation
request may call updateOnNotModified() to update the stale entry [with
the same revalidation response!]. Concurrent entry updates would have
wasted many resources, especially for disk-cached entries that support
header updates, and may have purged being-revalidated entries due to
locking conflicts among updating transactions. To minimize these
problems, we adjusted header and entry metadata updating logic to skip
the update if nothing have changed since the last update.

Also fixed Bug 4311: Collapsed forwarding deadlocks for SMP Squids using
SMP-unaware caches. Collapsed transactions stalled without getting a
response because they were waiting for the shared "transients" table
updates. The table was created by Store::Controller but then abandoned (not
updated) by SMP-unaware caches. Now, the transients table is not created
at all unless SMP-aware caches are present. This fix should also address
complaints about shared memory being used for Squid instances without
SMP-aware caches.

A combination of SMP-aware and SMP-unaware caches is still not supported
and is likely to stall collapsed transactions if they are enabled. Note
that, by default, the memory cache is SMP-aware in SMP environments.
24 files changed:
src/HttpHeader.cc
src/HttpHeader.h
src/HttpReply.cc
src/HttpReply.h
src/MemStore.h
src/Store.h
src/Transients.cc
src/Transients.h
src/cf.data.pre
src/client_side_reply.cc
src/client_side_reply.h
src/fs/rock/RockSwapDir.h
src/fs/ufs/UFSSwapDir.h
src/store.cc
src/store/Controller.cc
src/store/Controller.h
src/store/Disk.h
src/store/Disks.cc
src/store/Disks.h
src/store/Storage.h
src/store_key_md5.cc
src/store_key_md5.h
src/tests/stub_HttpReply.cc
src/tests/stub_store.cc