mirror of
https://github.com/nginx/nginx.git
synced 2024-11-24 13:49:05 +08:00
Cache: added watermark to reduce IO load when keys_zone is full.
When a keys_zone is full then each next request to the cache is penalized. That is, the cache has to evict older files to get a slot from the keys_zone synchronously. The patch introduces new behavior in this scenario. Manager will try to maintain available free slots in the keys_zone by cleaning old files in the background.
This commit is contained in:
parent
861e75dc20
commit
b18ba1e9f6
@ -138,6 +138,8 @@ typedef struct {
|
||||
ngx_atomic_t cold;
|
||||
ngx_atomic_t loading;
|
||||
off_t size;
|
||||
ngx_uint_t count;
|
||||
ngx_uint_t watermark;
|
||||
} ngx_http_file_cache_sh_t;
|
||||
|
||||
|
||||
|
@ -62,6 +62,7 @@ static ngx_int_t ngx_http_file_cache_add(ngx_http_file_cache_t *cache,
|
||||
ngx_http_cache_t *c);
|
||||
static ngx_int_t ngx_http_file_cache_delete_file(ngx_tree_ctx_t *ctx,
|
||||
ngx_str_t *path);
|
||||
static void ngx_http_file_cache_set_watermark(ngx_http_file_cache_t *cache);
|
||||
|
||||
|
||||
ngx_str_t ngx_http_cache_status[] = {
|
||||
@ -147,6 +148,8 @@ ngx_http_file_cache_init(ngx_shm_zone_t *shm_zone, void *data)
|
||||
cache->sh->cold = 1;
|
||||
cache->sh->loading = 0;
|
||||
cache->sh->size = 0;
|
||||
cache->sh->count = 0;
|
||||
cache->sh->watermark = (ngx_uint_t) -1;
|
||||
|
||||
cache->bsize = ngx_fs_bsize(cache->path->name.data);
|
||||
|
||||
@ -861,6 +864,8 @@ ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
|
||||
fcn = ngx_slab_calloc_locked(cache->shpool,
|
||||
sizeof(ngx_http_file_cache_node_t));
|
||||
if (fcn == NULL) {
|
||||
ngx_http_file_cache_set_watermark(cache);
|
||||
|
||||
ngx_shmtx_unlock(&cache->shpool->mutex);
|
||||
|
||||
(void) ngx_http_file_cache_forced_expire(cache);
|
||||
@ -877,6 +882,8 @@ ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
|
||||
}
|
||||
}
|
||||
|
||||
cache->sh->count++;
|
||||
|
||||
ngx_memcpy((u_char *) &fcn->node.key, c->key, sizeof(ngx_rbtree_key_t));
|
||||
|
||||
ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)],
|
||||
@ -1631,6 +1638,7 @@ ngx_http_file_cache_free(ngx_http_cache_t *c, ngx_temp_file_t *tf)
|
||||
ngx_queue_remove(&fcn->queue);
|
||||
ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
|
||||
ngx_slab_free_locked(cache->shpool, fcn);
|
||||
cache->sh->count--;
|
||||
c->node = NULL;
|
||||
}
|
||||
|
||||
@ -1883,6 +1891,7 @@ ngx_http_file_cache_delete(ngx_http_file_cache_t *cache, ngx_queue_t *q,
|
||||
ngx_queue_remove(q);
|
||||
ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
|
||||
ngx_slab_free_locked(cache->shpool, fcn);
|
||||
cache->sh->count--;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1892,8 +1901,9 @@ ngx_http_file_cache_manager(void *data)
|
||||
{
|
||||
ngx_http_file_cache_t *cache = data;
|
||||
|
||||
off_t size;
|
||||
time_t next, wait;
|
||||
off_t size;
|
||||
time_t next, wait;
|
||||
ngx_uint_t count, watermark;
|
||||
|
||||
next = ngx_http_file_cache_expire(cache);
|
||||
|
||||
@ -1904,13 +1914,16 @@ ngx_http_file_cache_manager(void *data)
|
||||
ngx_shmtx_lock(&cache->shpool->mutex);
|
||||
|
||||
size = cache->sh->size;
|
||||
count = cache->sh->count;
|
||||
watermark = cache->sh->watermark;
|
||||
|
||||
ngx_shmtx_unlock(&cache->shpool->mutex);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
|
||||
"http file cache size: %O", size);
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
|
||||
"http file cache size: %O c:%ui w:%i",
|
||||
size, count, (ngx_int_t) watermark);
|
||||
|
||||
if (size < cache->max_size) {
|
||||
if (size < cache->max_size && count < watermark) {
|
||||
return next;
|
||||
}
|
||||
|
||||
@ -2094,12 +2107,16 @@ ngx_http_file_cache_add(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
|
||||
fcn = ngx_slab_calloc_locked(cache->shpool,
|
||||
sizeof(ngx_http_file_cache_node_t));
|
||||
if (fcn == NULL) {
|
||||
ngx_http_file_cache_set_watermark(cache);
|
||||
|
||||
if (cache->fail_time != ngx_time()) {
|
||||
cache->fail_time = ngx_time();
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
|
||||
"could not allocate node%s", cache->shpool->log_ctx);
|
||||
}
|
||||
|
||||
cache->sh->count++;
|
||||
|
||||
ngx_shmtx_unlock(&cache->shpool->mutex);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -2146,6 +2163,16 @@ ngx_http_file_cache_delete_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_file_cache_set_watermark(ngx_http_file_cache_t *cache)
|
||||
{
|
||||
cache->sh->watermark = cache->sh->count - cache->sh->count / 8;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
|
||||
"http file cache watermark: %ui", cache->sh->watermark);
|
||||
}
|
||||
|
||||
|
||||
time_t
|
||||
ngx_http_file_cache_valid(ngx_array_t *cache_valid, ngx_uint_t status)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user