mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-29 14:50:59 +01:00
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:
parent
73be796462
commit
5853c0c0d5
@ -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
|
- 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
|
Cache-Control directives or Expires header) or a validator (ETag or Last-Modified
|
||||||
headers)
|
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 request is not a GET
|
||||||
- If the HTTP version of the request is smaller than 1.1
|
- 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.
|
All objects with sizes larger than "max-object-size" will not be cached.
|
||||||
|
|
||||||
max-age <seconds>
|
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
|
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
|
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
|
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
|
(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).
|
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
|
6.2.2. Proxy section
|
||||||
---------------------
|
---------------------
|
||||||
|
|||||||
31
src/cache.c
31
src/cache.c
@ -49,6 +49,7 @@ struct cache {
|
|||||||
unsigned int maxage; /* max-age */
|
unsigned int maxage; /* max-age */
|
||||||
unsigned int maxblocks;
|
unsigned int maxblocks;
|
||||||
unsigned int maxobjsz; /* max-object-size (in bytes) */
|
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) */
|
uint8_t vary_processing_enabled; /* boolean : manage Vary header (disabled by default) */
|
||||||
char id[33]; /* cache name */
|
char id[33]; /* cache name */
|
||||||
};
|
};
|
||||||
@ -104,7 +105,7 @@ struct cache_st {
|
|||||||
struct shared_block *first_block;
|
struct shared_block *first_block;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SECONDARY_ENTRY_MAX_COUNT 10
|
#define DEFAULT_MAX_SECONDARY_ENTRY 10
|
||||||
|
|
||||||
struct cache_entry {
|
struct cache_entry {
|
||||||
unsigned int complete; /* An entry won't be valid until complete is not null. */
|
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;
|
entry_count = entry->secondary_entries_count;
|
||||||
last_clear_ts = entry->last_clear_ts;
|
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
|
/* Some entries of the duplicate list might be expired so
|
||||||
* we will iterate over all the items in order to free some
|
* we will iterate over all the items in order to free some
|
||||||
* space. In order to avoid going over the same list too
|
* 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);
|
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
|
/* Still too many entries for this primary key, delete
|
||||||
* the newly inserted one. */
|
* the newly inserted one. */
|
||||||
entry = container_of(prev, struct cache_entry, eb);
|
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->maxage = 60;
|
||||||
tmp_cache_config->maxblocks = 0;
|
tmp_cache_config->maxblocks = 0;
|
||||||
tmp_cache_config->maxobjsz = 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) {
|
} else if (strcmp(args[0], "total-max-size") == 0) {
|
||||||
unsigned long int maxsize;
|
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]);
|
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) {
|
else if (*args[0] != 0) {
|
||||||
ha_alert("parsing [%s:%d] : unknown keyword '%s' in 'cache' section\n", file, linenum, args[0]);
|
ha_alert("parsing [%s:%d] : unknown keyword '%s' in 'cache' section\n", file, linenum, args[0]);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user