From e2bc3f4bbc9d16d108cfeadf5da09309903eec94 Mon Sep 17 00:00:00 2001 From: Evan Zelkowitz Date: Thu, 7 May 2020 16:34:21 +0000 Subject: [PATCH 1/4] Add an optional ramcache setting to volume.config to disable it This adds an additional option of `ramcache=true/false` to the volume.config. The default is true, so enabled, to leave current functionality as is and for the general use case. If set to false then this will stop the cache from initializing a ramcache for that specific volume and avoid the ramcache all together. This may be desirable for people running with volumes composed of ram disks to avoid double ram caching and reclaim memory+time --- doc/admin-guide/files/volume.config.en.rst | 17 ++++++++++++++-- doc/admin-guide/storage/index.en.rst | 9 +++++++++ iocore/cache/Cache.cc | 20 +++++++++++-------- iocore/cache/CacheHosting.cc | 23 ++++++++++++++++++---- iocore/cache/P_CacheHosting.h | 1 + iocore/cache/P_CacheVol.h | 1 + 6 files changed, 57 insertions(+), 14 deletions(-) diff --git a/doc/admin-guide/files/volume.config.en.rst b/doc/admin-guide/files/volume.config.en.rst index 7fdfc8e3381..63f167f8bb6 100644 --- a/doc/admin-guide/files/volume.config.en.rst +++ b/doc/admin-guide/files/volume.config.en.rst @@ -57,14 +57,27 @@ volumes without deleting and clearing the existing volumes. Changing this file to add, remove or modify volumes effectively invalidates the cache. + +Optional ramcache setting +------------------------- + +You can also add an option ``ramcache=true/false`` to the volume configuration +line. True is the default setting and so not needed unless you want to explicitly +set it. Setting ``ramcache=false`` will disable the ramcache that normally +sits in front of a volume. This may desirable if you are using something like +ramdisks, to avoid wasting RAM and time on double caching objects. + + Examples ======== The following example partitions the cache across 5 volumes to decreasing -single-lock pressure for a machine with few drives.:: +single-lock pressure for a machine with few drives. The last volume being +an example of one that might be composed of purely ramdisks so that the +ramcache has been disabled.:: volume=1 scheme=http size=20% volume=2 scheme=http size=20% volume=3 scheme=http size=20% volume=4 scheme=http size=20% - volume=5 scheme=http size=20% + volume=5 scheme=http size=20% ramcache=false diff --git a/doc/admin-guide/storage/index.en.rst b/doc/admin-guide/storage/index.en.rst index 50e1e63fbd1..4574a48f967 100644 --- a/doc/admin-guide/storage/index.en.rst +++ b/doc/admin-guide/storage/index.en.rst @@ -137,6 +137,15 @@ To change the RAM cache size: 1GB or more, then restart with the :program:`trafficserver` command (refer to :ref:`start-traffic-server`). +Disabling the RAM Cache +----------------------- + +It is possible to disable the RAM cache. If you have configured your +storage using the :file:`volume.config` you can add an optional directive +of ``ramcache=false`` to whichever volumes you wish to have it disabled on. +This may desirable for volumes composed of storage like RAM disks where +you may want to avoid double RAM caching. + Changing Cache Capacity ======================= diff --git a/iocore/cache/Cache.cc b/iocore/cache/Cache.cc index ae94e3bbb78..19638314fc3 100644 --- a/iocore/cache/Cache.cc +++ b/iocore/cache/Cache.cc @@ -911,12 +911,14 @@ CacheProcessor::cacheInitialized() Debug("cache_init", "CacheProcessor::cacheInitialized - cache_config_ram_cache_size == AUTO_SIZE_RAM_CACHE"); for (i = 0; i < gnvol; i++) { vol = gvol[i]; - gvol[i]->ram_cache->init(vol->dirlen() * DEFAULT_RAM_CACHE_MULTIPLIER, vol); - ram_cache_bytes += gvol[i]->dirlen(); - Debug("cache_init", "CacheProcessor::cacheInitialized - ram_cache_bytes = %" PRId64 " = %" PRId64 "Mb", ram_cache_bytes, - ram_cache_bytes / (1024 * 1024)); - CACHE_VOL_SUM_DYN_STAT(cache_ram_cache_bytes_total_stat, (int64_t)gvol[i]->dirlen()); + if (gvol[i]->cache_vol->ramcache) { + gvol[i]->ram_cache->init(vol->dirlen() * DEFAULT_RAM_CACHE_MULTIPLIER, vol); + ram_cache_bytes += gvol[i]->dirlen(); + Debug("cache_init", "CacheProcessor::cacheInitialized - ram_cache_bytes = %" PRId64 " = %" PRId64 "Mb", ram_cache_bytes, + ram_cache_bytes / (1024 * 1024)); + CACHE_VOL_SUM_DYN_STAT(cache_ram_cache_bytes_total_stat, (int64_t)gvol[i]->dirlen()); + } vol_total_cache_bytes = gvol[i]->len - gvol[i]->dirlen(); total_cache_bytes += vol_total_cache_bytes; Debug("cache_init", "CacheProcessor::cacheInitialized - total_cache_bytes = %" PRId64 " = %" PRId64 "Mb", @@ -955,14 +957,14 @@ CacheProcessor::cacheInitialized() for (i = 0; i < gnvol; i++) { vol = gvol[i]; double factor; - if (gvol[i]->cache == theCache) { + if (gvol[i]->cache == theCache && gvol[i]->cache_vol->ramcache) { ink_assert(gvol[i]->cache != nullptr); factor = static_cast(static_cast(gvol[i]->len >> STORE_BLOCK_SHIFT)) / theCache->cache_size; Debug("cache_init", "CacheProcessor::cacheInitialized - factor = %f", factor); gvol[i]->ram_cache->init(static_cast(http_ram_cache_size * factor), vol); ram_cache_bytes += static_cast(http_ram_cache_size * factor); CACHE_VOL_SUM_DYN_STAT(cache_ram_cache_bytes_total_stat, (int64_t)(http_ram_cache_size * factor)); - } else { + } else if (gvol[i]->cache_vol->ramcache) { ink_release_assert(!"Unexpected non-HTTP cache volume"); } Debug("cache_init", "CacheProcessor::cacheInitialized[%d] - ram_cache_bytes = %" PRId64 " = %" PRId64 "Mb", i, @@ -2541,6 +2543,7 @@ cplist_update() for (config_vol = config_volumes.cp_queue.head; config_vol; config_vol = config_vol->link.next) { if (config_vol->number == cp->vol_number) { if (cp->scheme == config_vol->scheme) { + cp->ramcache = config_vol->ramcache; config_vol->cachep = cp; } else { /* delete this volume from all the disks */ @@ -2716,7 +2719,8 @@ cplist_reconfigure() (int64_t)config_vol->size, 128); Warning("volume %d is not created", config_vol->number); } - Debug("cache_hosting", "Volume: %d Size: %" PRId64, config_vol->number, (int64_t)config_vol->size); + Debug("cache_hosting", "Volume: %d Size: %" PRId64 " Ramcache: %d", config_vol->number, (int64_t)config_vol->size, + config_vol->ramcache); } cplist_update(); /* go through volume config and grow and create volumes */ diff --git a/iocore/cache/CacheHosting.cc b/iocore/cache/CacheHosting.cc index f7754d29315..8f19b269e4d 100644 --- a/iocore/cache/CacheHosting.cc +++ b/iocore/cache/CacheHosting.cc @@ -656,6 +656,7 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf) CacheType scheme = CACHE_NONE_TYPE; int size = 0; int in_percent = 0; + bool ramcache = true; while (true) { // skip all blank spaces at beginning of line @@ -743,6 +744,18 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf) } else { in_percent = 0; } + } else if (strcasecmp(tmp, "ramcache") == 0) { // match ramcache + tmp += 9; + if (!strcasecmp(tmp, "false")) { + tmp += 5; + ramcache = false; + } else if (!strcasecmp(tmp, "true")) { + tmp += 4; + ramcache = true; + } else { + err = "Unexpected end of line"; + break; + } } // ends here @@ -765,9 +778,10 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf) } else { configp->in_percent = false; } - configp->scheme = scheme; - configp->size = size; - configp->cachep = nullptr; + configp->scheme = scheme; + configp->size = size; + configp->cachep = nullptr; + configp->ramcache = ramcache; cp_queue.enqueue(configp); num_volumes++; if (scheme == CACHE_HTTP_TYPE) { @@ -775,7 +789,8 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf) } else { ink_release_assert(!"Unexpected non-HTTP cache volume"); } - Debug("cache_hosting", "added volume=%d, scheme=%d, size=%d percent=%d", volume_number, scheme, size, in_percent); + Debug("cache_hosting", "added volume=%d, scheme=%d, size=%d percent=%d, ramcache enabled=%d", volume_number, scheme, size, + in_percent, ramcache); } tmp = bufTok.iterNext(&i_state); diff --git a/iocore/cache/P_CacheHosting.h b/iocore/cache/P_CacheHosting.h index 90822e2c44b..5d46dcd4a4c 100644 --- a/iocore/cache/P_CacheHosting.h +++ b/iocore/cache/P_CacheHosting.h @@ -171,6 +171,7 @@ struct ConfigVol { CacheType scheme; off_t size; bool in_percent; + bool ramcache; int percent; CacheVol *cachep; LINK(ConfigVol, link); diff --git a/iocore/cache/P_CacheVol.h b/iocore/cache/P_CacheVol.h index 5b3254ea7bf..b476ab9f69f 100644 --- a/iocore/cache/P_CacheVol.h +++ b/iocore/cache/P_CacheVol.h @@ -283,6 +283,7 @@ struct CacheVol { int scheme = 0; off_t size = 0; int num_vols = 0; + bool ramcache = true; Vol **vols = nullptr; DiskVol **disk_vols = nullptr; LINK(CacheVol, link); From fb8060a914d1307bb897c789fdc498b8d4c9d89c Mon Sep 17 00:00:00 2001 From: Evan Zelkowitz Date: Thu, 7 May 2020 20:14:30 -0600 Subject: [PATCH 2/4] Update volume.config.en.rst missed 'be' --- doc/admin-guide/files/volume.config.en.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/admin-guide/files/volume.config.en.rst b/doc/admin-guide/files/volume.config.en.rst index 63f167f8bb6..46395f180d6 100644 --- a/doc/admin-guide/files/volume.config.en.rst +++ b/doc/admin-guide/files/volume.config.en.rst @@ -64,8 +64,8 @@ Optional ramcache setting You can also add an option ``ramcache=true/false`` to the volume configuration line. True is the default setting and so not needed unless you want to explicitly set it. Setting ``ramcache=false`` will disable the ramcache that normally -sits in front of a volume. This may desirable if you are using something like -ramdisks, to avoid wasting RAM and time on double caching objects. +sits in front of a volume. This may be desirable if you are using something like +ramdisks, to avoid wasting RAM and cpu time on double caching objects. Examples From 86332daabbc17abc1e15faab2f6ed04522bf1282 Mon Sep 17 00:00:00 2001 From: Evan Zelkowitz Date: Thu, 7 May 2020 20:15:15 -0600 Subject: [PATCH 3/4] Update index.en.rst --- doc/admin-guide/storage/index.en.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/admin-guide/storage/index.en.rst b/doc/admin-guide/storage/index.en.rst index 4574a48f967..fc290071d24 100644 --- a/doc/admin-guide/storage/index.en.rst +++ b/doc/admin-guide/storage/index.en.rst @@ -143,7 +143,7 @@ Disabling the RAM Cache It is possible to disable the RAM cache. If you have configured your storage using the :file:`volume.config` you can add an optional directive of ``ramcache=false`` to whichever volumes you wish to have it disabled on. -This may desirable for volumes composed of storage like RAM disks where +This may be desirable for volumes composed of storage like RAM disks where you may want to avoid double RAM caching. Changing Cache Capacity From c2fda51ccd6fefec42ab973b94d203804c228d76 Mon Sep 17 00:00:00 2001 From: Evan Zelkowitz Date: Tue, 19 May 2020 19:55:01 +0000 Subject: [PATCH 4/4] Rename ramcache boolean to ramcache_enabled to avoid confusion --- iocore/cache/Cache.cc | 12 ++++++------ iocore/cache/CacheHosting.cc | 28 ++++++++++++++-------------- iocore/cache/P_CacheHosting.h | 2 +- iocore/cache/P_CacheVol.h | 14 +++++++------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/iocore/cache/Cache.cc b/iocore/cache/Cache.cc index 19638314fc3..d34e93e30a8 100644 --- a/iocore/cache/Cache.cc +++ b/iocore/cache/Cache.cc @@ -912,7 +912,7 @@ CacheProcessor::cacheInitialized() for (i = 0; i < gnvol; i++) { vol = gvol[i]; - if (gvol[i]->cache_vol->ramcache) { + if (gvol[i]->cache_vol->ramcache_enabled) { gvol[i]->ram_cache->init(vol->dirlen() * DEFAULT_RAM_CACHE_MULTIPLIER, vol); ram_cache_bytes += gvol[i]->dirlen(); Debug("cache_init", "CacheProcessor::cacheInitialized - ram_cache_bytes = %" PRId64 " = %" PRId64 "Mb", ram_cache_bytes, @@ -957,14 +957,14 @@ CacheProcessor::cacheInitialized() for (i = 0; i < gnvol; i++) { vol = gvol[i]; double factor; - if (gvol[i]->cache == theCache && gvol[i]->cache_vol->ramcache) { + if (gvol[i]->cache == theCache && gvol[i]->cache_vol->ramcache_enabled) { ink_assert(gvol[i]->cache != nullptr); factor = static_cast(static_cast(gvol[i]->len >> STORE_BLOCK_SHIFT)) / theCache->cache_size; Debug("cache_init", "CacheProcessor::cacheInitialized - factor = %f", factor); gvol[i]->ram_cache->init(static_cast(http_ram_cache_size * factor), vol); ram_cache_bytes += static_cast(http_ram_cache_size * factor); CACHE_VOL_SUM_DYN_STAT(cache_ram_cache_bytes_total_stat, (int64_t)(http_ram_cache_size * factor)); - } else if (gvol[i]->cache_vol->ramcache) { + } else if (gvol[i]->cache_vol->ramcache_enabled) { ink_release_assert(!"Unexpected non-HTTP cache volume"); } Debug("cache_init", "CacheProcessor::cacheInitialized[%d] - ram_cache_bytes = %" PRId64 " = %" PRId64 "Mb", i, @@ -2543,8 +2543,8 @@ cplist_update() for (config_vol = config_volumes.cp_queue.head; config_vol; config_vol = config_vol->link.next) { if (config_vol->number == cp->vol_number) { if (cp->scheme == config_vol->scheme) { - cp->ramcache = config_vol->ramcache; - config_vol->cachep = cp; + cp->ramcache_enabled = config_vol->ramcache_enabled; + config_vol->cachep = cp; } else { /* delete this volume from all the disks */ int d_no; @@ -2720,7 +2720,7 @@ cplist_reconfigure() Warning("volume %d is not created", config_vol->number); } Debug("cache_hosting", "Volume: %d Size: %" PRId64 " Ramcache: %d", config_vol->number, (int64_t)config_vol->size, - config_vol->ramcache); + config_vol->ramcache_enabled); } cplist_update(); /* go through volume config and grow and create volumes */ diff --git a/iocore/cache/CacheHosting.cc b/iocore/cache/CacheHosting.cc index 8f19b269e4d..c62d53c47ad 100644 --- a/iocore/cache/CacheHosting.cc +++ b/iocore/cache/CacheHosting.cc @@ -650,13 +650,13 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf) line_num++; char *end; - char *line_end = nullptr; - const char *err = nullptr; - int volume_number = 0; - CacheType scheme = CACHE_NONE_TYPE; - int size = 0; - int in_percent = 0; - bool ramcache = true; + char *line_end = nullptr; + const char *err = nullptr; + int volume_number = 0; + CacheType scheme = CACHE_NONE_TYPE; + int size = 0; + int in_percent = 0; + bool ramcache_enabled = true; while (true) { // skip all blank spaces at beginning of line @@ -748,10 +748,10 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf) tmp += 9; if (!strcasecmp(tmp, "false")) { tmp += 5; - ramcache = false; + ramcache_enabled = false; } else if (!strcasecmp(tmp, "true")) { tmp += 4; - ramcache = true; + ramcache_enabled = true; } else { err = "Unexpected end of line"; break; @@ -778,10 +778,10 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf) } else { configp->in_percent = false; } - configp->scheme = scheme; - configp->size = size; - configp->cachep = nullptr; - configp->ramcache = ramcache; + configp->scheme = scheme; + configp->size = size; + configp->cachep = nullptr; + configp->ramcache_enabled = ramcache_enabled; cp_queue.enqueue(configp); num_volumes++; if (scheme == CACHE_HTTP_TYPE) { @@ -790,7 +790,7 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf) ink_release_assert(!"Unexpected non-HTTP cache volume"); } Debug("cache_hosting", "added volume=%d, scheme=%d, size=%d percent=%d, ramcache enabled=%d", volume_number, scheme, size, - in_percent, ramcache); + in_percent, ramcache_enabled); } tmp = bufTok.iterNext(&i_state); diff --git a/iocore/cache/P_CacheHosting.h b/iocore/cache/P_CacheHosting.h index 5d46dcd4a4c..ba4af9b20a1 100644 --- a/iocore/cache/P_CacheHosting.h +++ b/iocore/cache/P_CacheHosting.h @@ -171,7 +171,7 @@ struct ConfigVol { CacheType scheme; off_t size; bool in_percent; - bool ramcache; + bool ramcache_enabled; int percent; CacheVol *cachep; LINK(ConfigVol, link); diff --git a/iocore/cache/P_CacheVol.h b/iocore/cache/P_CacheVol.h index b476ab9f69f..a51d245e585 100644 --- a/iocore/cache/P_CacheVol.h +++ b/iocore/cache/P_CacheVol.h @@ -279,13 +279,13 @@ struct AIO_Callback_handler : public Continuation { }; struct CacheVol { - int vol_number = -1; - int scheme = 0; - off_t size = 0; - int num_vols = 0; - bool ramcache = true; - Vol **vols = nullptr; - DiskVol **disk_vols = nullptr; + int vol_number = -1; + int scheme = 0; + off_t size = 0; + int num_vols = 0; + bool ramcache_enabled = true; + Vol **vols = nullptr; + DiskVol **disk_vols = nullptr; LINK(CacheVol, link); // per volume stats RecRawStatBlock *vol_rsb = nullptr;