MINOR: cache: Add a max-secondary-entries cache option

This new option allows to tune the maximum number of simultaneous
entries with the same primary key in the cache (secondary entries).
When we try to store a response in the cache and there are already
max-secondary-entries living entries in the cache, the storage will
fail (but the response will still be sent to the client).
It defaults to 10 and does not have a maximum number.
This commit is contained in:
Remi Tricot-Le Breton 2020-12-10 17:58:43 +01:00 committed by William Lallemand
parent 73be796462
commit 5853c0c0d5
2 changed files with 36 additions and 4 deletions

View File

@ -14606,6 +14606,8 @@ The cache won't store and won't deliver objects in these cases:
- If the response does not have an explicit expiration time (s-maxage or max-age
Cache-Control directives or Expires header) or a validator (ETag or Last-Modified
headers)
- If the process-vary option is enabled and there are already max-secondary-entries
entries with the same primary key as the current response
- If the request is not a GET
- If the HTTP version of the request is smaller than 1.1
@ -14636,7 +14638,7 @@ max-object-size <bytes>
All objects with sizes larger than "max-object-size" will not be cached.
max-age <seconds>
Define the maximum expiration duration. The expiration is set has the lowest
Define the maximum expiration duration. The expiration is set as the lowest
value between the s-maxage or max-age (in this order) directive in the
Cache-Control response header and this value. The default value is 60
seconds, which means that you can't cache an object more than 60 seconds by
@ -14649,6 +14651,11 @@ process-vary <0 or 1>
(which might come with a cpu cost) which will be used to build a secondary key
for a given request (see RFC 7234#4.1). The default value is 0 (disabled).
max-secondary-entries <number>
Define the maximum number of simultaneous secondary entries with the same primary
key in the cache. This needs the vary support to be enabled. Its default value is 10
and should be passed a strictly positive integer.
6.2.2. Proxy section
---------------------

View File

@ -49,6 +49,7 @@ struct cache {
unsigned int maxage; /* max-age */
unsigned int maxblocks;
unsigned int maxobjsz; /* max-object-size (in bytes) */
unsigned int max_secondary_entries; /* maximum number of secondary entries with the same primary hash */
uint8_t vary_processing_enabled; /* boolean : manage Vary header (disabled by default) */
char id[33]; /* cache name */
};
@ -104,7 +105,7 @@ struct cache_st {
struct shared_block *first_block;
};
#define SECONDARY_ENTRY_MAX_COUNT 10
#define DEFAULT_MAX_SECONDARY_ENTRY 10
struct cache_entry {
unsigned int complete; /* An entry won't be valid until complete is not null. */
@ -276,7 +277,7 @@ static struct eb32_node *insert_entry(struct cache *cache, struct cache_entry *n
entry_count = entry->secondary_entries_count;
last_clear_ts = entry->last_clear_ts;
if (entry_count >= SECONDARY_ENTRY_MAX_COUNT) {
if (entry_count >= cache->max_secondary_entries) {
/* Some entries of the duplicate list might be expired so
* we will iterate over all the items in order to free some
* space. In order to avoid going over the same list too
@ -291,7 +292,7 @@ static struct eb32_node *insert_entry(struct cache *cache, struct cache_entry *n
}
entry_count = clear_expired_duplicates(&prev);
if (entry_count >= SECONDARY_ENTRY_MAX_COUNT) {
if (entry_count >= cache->max_secondary_entries) {
/* Still too many entries for this primary key, delete
* the newly inserted one. */
entry = container_of(prev, struct cache_entry, eb);
@ -1800,6 +1801,7 @@ int cfg_parse_cache(const char *file, int linenum, char **args, int kwm)
tmp_cache_config->maxage = 60;
tmp_cache_config->maxblocks = 0;
tmp_cache_config->maxobjsz = 0;
tmp_cache_config->max_secondary_entries = DEFAULT_MAX_SECONDARY_ENTRY;
}
} else if (strcmp(args[0], "total-max-size") == 0) {
unsigned long int maxsize;
@ -1877,6 +1879,29 @@ int cfg_parse_cache(const char *file, int linenum, char **args, int kwm)
}
tmp_cache_config->vary_processing_enabled = atoi(args[1]);
} else if (strcmp(args[0], "max-secondary-entries") == 0) {
unsigned int max_sec_entries;
char *err;
if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
err_code |= ERR_ABORT;
goto out;
}
if (!*args[1]) {
ha_warning("parsing [%s:%d]: '%s' expects a strictly positive number.\n",
file, linenum, args[0]);
err_code |= ERR_WARN;
}
max_sec_entries = strtoul(args[1], &err, 10);
if (err == args[1] || *err != '\0' || max_sec_entries == 0) {
ha_warning("parsing [%s:%d]: max-secondary-entries wrong value '%s'\n",
file, linenum, args[1]);
err_code |= ERR_ABORT;
goto out;
}
tmp_cache_config->max_secondary_entries = max_sec_entries;
}
else if (*args[0] != 0) {
ha_alert("parsing [%s:%d] : unknown keyword '%s' in 'cache' section\n", file, linenum, args[0]);