MXS-2253 Make Cache use the new duration config type

Internally the Cache used seconds, so some changes were needed.
This commit is contained in:
Johan Wikman
2019-02-13 09:43:12 +02:00
parent c116452c25
commit 2528c5fa4d
7 changed files with 82 additions and 73 deletions

View File

@ -5,53 +5,7 @@ This filter was introduced in MariaDB MaxScale 2.1.
Table of Contents Table of Contents
================= =================
* [Overview](#overview) [TOC]
* [Limitations](#limitations)
* [Invalidation](#invalidation)
* [Prepared Statements](#prepared-statements)
* [Security](#security)
* [Configuration](#configuration)
* [Filter Parameters](#filter-parameters)
* [storage](#storage)
* [storage_options](#storage_options)
* [hard_ttl](#hard_ttl)
* [soft_ttl](#soft_ttl)
* [max_resultset_rows](#max_resultset_rows)
* [max_resultset_size](#max_resultset_size)
* [max_count](#max_count)
* [max_size](#max_size)
* [rules](#rules)
* [cached_data](#cached_data)
* [selects](#selects)
* [cache_inside_transactions](#cache_inside_transactions)
* [debug](#debug)
* [enabled](#enabled)
* [Runtime Configuration](#runtime-configuration)
* [@maxscale.cache.populate](#maxscalecachepopulate)
* [@maxscale.cache.use](#maxscalecacheuse)
* [@maxscale.cache.soft_ttl](#maxscalecachesoft_ttl)
* [@maxscale.cache.hard_ttl](#maxscalecachehard_ttl)
* [Client Driven Caching](#client-driven-caching)
* [Rules](#rules-1)
* [When to Store](#when-to-store)
* [Qualified Names](#qualified-names)
* [Implication of the <em>default</em> database](#implication-of-the-default-database)
* [Regexp Matching](#regexp-matching)
* [Examples](#examples)
* [When to Use](#when-to-use)
* [Examples](#examples-1)
* [Security](#security-1)
* [Storage](#storage-1)
* [storage_inmemory](#storage_inmemory)
* [storage_rocksdb](#storage_rocksdb)
* [Parameters](#parameters)
* [cache_directory](#cache_directory)
* [collect_statistics](#collect_statistics)
* [Example](#example)
* [Configuration](#configuration-1)
* [cache_rules.json](#cache_rulesjson)
* [Performance](#performance)
* [Summary](#summary)
## Overview ## Overview
@ -173,14 +127,19 @@ storage_options=storage_specific_option1=value1,storage_specific_option2=value2
#### `hard_ttl` #### `hard_ttl`
_Hard time to live_; the maximum amount of time - in seconds - the cached _Hard time to live_; the maximum amount of time the cached
result is used before it is discarded and the result is fetched from the result is used before it is discarded and the result is fetched from the
backend (and cached). See also `soft_ttl` below. backend (and cached). See also `soft_ttl` below.
``` ```
hard_ttl=60 hard_ttl=60s
``` ```
The default value is `0`, which means no limit. The default value is `0s`, which means no limit.
The duration can be specified as explained
[here](Getting-Started/Configuration-Guide.md#durations).
If no explicit unit has been specified, the value is interpreted as seconds
in MaxScale 2.4. In subsequent versions a value without a unit may be rejected.
#### `soft_ttl` #### `soft_ttl`
@ -194,11 +153,16 @@ from the backend. That is, as long as `soft_ttl` but not `hard_ttl` has passed,
even if several clients request the same value at the same time, there will be even if several clients request the same value at the same time, there will be
just one request to the backend. just one request to the backend.
``` ```
soft_ttl=60 soft_ttl=60s
``` ```
The default value is `0`, which means no limit. If the value of `soft_ttl` is The default value is `0`, which means no limit. If the value of `soft_ttl` is
larger than `hard_ttl` it will be adjusted down to the same value. larger than `hard_ttl` it will be adjusted down to the same value.
The duration can be specifed as explained
[here](Getting-Started/Configuration-Guide.md#durations).
If no explicit unit has been specified, the value is interpreted as seconds
in MaxScale 2.4. In subsequent versions a value without a unit may be rejected.
#### `max_resultset_rows` #### `max_resultset_rows`
Specifies the maximum number of rows a resultset can have in order to be Specifies the maximum number of rows a resultset can have in order to be

View File

@ -209,3 +209,20 @@ json_t* Cache::do_get_info(uint32_t what) const
return pInfo; return pInfo;
} }
//static
uint64_t Cache::time_ms()
{
timespec t;
int rv = clock_gettime(CLOCK_MONOTONIC_COARSE, &t);
if (rv != 0)
{
mxb_assert(errno == EINVAL); // CLOCK_MONOTONIC_COARSE not supported.
rv = clock_gettime(CLOCK_MONOTONIC, &t);
mxb_assert(rv == 0);
}
return t.tv_sec * 1000 + (t.tv_nsec / 1000000);
}

View File

@ -56,10 +56,10 @@ typedef enum cache_selects
#define CACHE_ZDEFAULT_MAX_RESULTSET_ROWS "0" #define CACHE_ZDEFAULT_MAX_RESULTSET_ROWS "0"
// Bytes // Bytes
#define CACHE_ZDEFAULT_MAX_RESULTSET_SIZE "0" #define CACHE_ZDEFAULT_MAX_RESULTSET_SIZE "0"
// Seconds // Duration
#define CACHE_ZDEFAULT_HARD_TTL "0" #define CACHE_ZDEFAULT_HARD_TTL "0s"
// Seconds // Duration
#define CACHE_ZDEFAULT_SOFT_TTL "0" #define CACHE_ZDEFAULT_SOFT_TTL "0s"
// Integer value // Integer value
#define CACHE_ZDEFAULT_DEBUG "0" #define CACHE_ZDEFAULT_DEBUG "0"
// Positive integer // Positive integer
@ -208,6 +208,14 @@ public:
*/ */
virtual cache_result_t del_value(const CACHE_KEY& key) = 0; virtual cache_result_t del_value(const CACHE_KEY& key) = 0;
/**
* Returns the monotonic time, expressed in milliseconds, since an
* unspecified starting point.
*
* @return The time.
*/
static uint64_t time_ms();
protected: protected:
Cache(const std::string& name, Cache(const std::string& name,
const CACHE_CONFIG* pConfig, const CACHE_CONFIG* pConfig,

View File

@ -191,12 +191,12 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE()
}, },
{ {
"hard_ttl", "hard_ttl",
MXS_MODULE_PARAM_COUNT, MXS_MODULE_PARAM_DURATION,
CACHE_ZDEFAULT_HARD_TTL CACHE_ZDEFAULT_HARD_TTL
}, },
{ {
"soft_ttl", "soft_ttl",
MXS_MODULE_PARAM_COUNT, MXS_MODULE_PARAM_DURATION,
CACHE_ZDEFAULT_SOFT_TTL CACHE_ZDEFAULT_SOFT_TTL
}, },
{ {
@ -346,8 +346,8 @@ bool CacheFilter::process_params(MXS_CONFIG_PARAMETER* ppParams, CACHE_CONFIG& c
bool error = false; bool error = false;
config.debug = ppParams->get_integer("debug"); config.debug = ppParams->get_integer("debug");
config.hard_ttl = ppParams->get_integer("hard_ttl"); config.hard_ttl = ppParams->get_duration("hard_ttl", mxs::config::INTERPRET_AS_SECONDS).count();
config.soft_ttl = ppParams->get_integer("soft_ttl"); config.soft_ttl = ppParams->get_duration("soft_ttl", mxs::config::INTERPRET_AS_SECONDS).count();
config.max_size = ppParams->get_size("max_size"); config.max_size = ppParams->get_size("max_size");
config.max_count = ppParams->get_integer("max_count"); config.max_count = ppParams->get_integer("max_count");
config.storage = ppParams->get_c_str_copy("storage"); config.storage = ppParams->get_c_str_copy("storage");

View File

@ -16,6 +16,7 @@
#include <maxscale/alloc.h> #include <maxscale/alloc.h>
#include <maxscale/modutil.hh> #include <maxscale/modutil.hh>
#include <maxscale/query_classifier.hh> #include <maxscale/query_classifier.hh>
#include "../../cache.hh"
#include "inmemorystoragest.hh" #include "inmemorystoragest.hh"
#include "inmemorystoragemt.hh" #include "inmemorystoragemt.hh"
@ -31,6 +32,7 @@ const size_t INMEMORY_KEY_LENGTH = 2 * SHA512_DIGEST_LENGTH;
#if INMEMORY_KEY_LENGTH > CACHE_KEY_MAXLEN #if INMEMORY_KEY_LENGTH > CACHE_KEY_MAXLEN
#error storage_inmemory key is too long. #error storage_inmemory key is too long.
#endif #endif
} }
InMemoryStorage::InMemoryStorage(const string& name, const CACHE_STORAGE_CONFIG& config) InMemoryStorage::InMemoryStorage(const string& name, const CACHE_STORAGE_CONFIG& config)
@ -162,7 +164,7 @@ cache_result_t InMemoryStorage::do_get_value(const CACHE_KEY& key,
Entry& entry = i->second; Entry& entry = i->second;
uint32_t now = time(NULL); int64_t now = Cache::time_ms();
bool is_hard_stale = hard_ttl == 0 ? false : (now - entry.time > hard_ttl); bool is_hard_stale = hard_ttl == 0 ? false : (now - entry.time > hard_ttl);
bool is_soft_stale = soft_ttl == 0 ? false : (now - entry.time > soft_ttl); bool is_soft_stale = soft_ttl == 0 ? false : (now - entry.time > soft_ttl);
@ -251,7 +253,7 @@ cache_result_t InMemoryStorage::do_put_value(const CACHE_KEY& key, const GWBUF&
const uint8_t* pData = GWBUF_DATA(&value); const uint8_t* pData = GWBUF_DATA(&value);
copy(pData, pData + size, pEntry->value.begin()); copy(pData, pData + size, pEntry->value.begin());
pEntry->time = time(NULL); pEntry->time = Cache::time_ms();
return CACHE_RESULT_OK; return CACHE_RESULT_OK;
} }

View File

@ -73,7 +73,7 @@ private:
{ {
} }
uint32_t time; int64_t time;
Value value; Value value;
}; };

View File

@ -18,6 +18,24 @@
using namespace std; using namespace std;
namespace
{
unsigned int millisleep(unsigned int milliseconds)
{
unsigned int seconds = milliseconds / 1000;
milliseconds -= (seconds * 1000);
timespec req = { seconds, milliseconds * 1000000 };
timespec rem = { 0, 0 };
nanosleep(&req, &rem);
return rem.tv_sec * 1000 + rem.tv_nsec / 1000000;
}
}
// //
// class TesterStorage::HitTask // class TesterStorage::HitTask
// //
@ -276,8 +294,8 @@ int TesterStorage::test_ttl(const CacheItems& cache_items)
out() << "ST" << endl; out() << "ST" << endl;
config.thread_model = CACHE_THREAD_MODEL_ST; config.thread_model = CACHE_THREAD_MODEL_ST;
config.hard_ttl = 6; config.hard_ttl = 6000;
config.soft_ttl = 3; config.soft_ttl = 3000;
Storage* pStorage; Storage* pStorage;
@ -293,8 +311,8 @@ int TesterStorage::test_ttl(const CacheItems& cache_items)
out() << "MT" << endl; out() << "MT" << endl;
config.thread_model = CACHE_THREAD_MODEL_MT; config.thread_model = CACHE_THREAD_MODEL_MT;
config.hard_ttl = 6; config.hard_ttl = 6000;
config.soft_ttl = 3; config.soft_ttl = 3000;
int rv2 = EXIT_FAILURE; int rv2 = EXIT_FAILURE;
pStorage = get_storage(config); pStorage = get_storage(config);
@ -342,8 +360,8 @@ int TesterStorage::test_ttl(const CacheItems& cache_items, Storage& storage)
else else
{ {
// Let's stay just below the soft_ttl value. // Let's stay just below the soft_ttl value.
sleep(soft_ttl - 1); millisleep(soft_ttl - 1000);
slept += soft_ttl - 1; slept += soft_ttl - 1000;
GWBUF* pValue; GWBUF* pValue;
@ -359,8 +377,8 @@ int TesterStorage::test_ttl(const CacheItems& cache_items, Storage& storage)
gwbuf_free(pValue); gwbuf_free(pValue);
sleep(2); // Expected to get us passed the soft ttl. millisleep(2000); // Expected to get us passed the soft ttl.
slept += 2; slept += 2000;
pValue = NULL; pValue = NULL;
result = storage.get_value(cache_item.first, 0, &pValue); result = storage.get_value(cache_item.first, 0, &pValue);
@ -385,8 +403,8 @@ int TesterStorage::test_ttl(const CacheItems& cache_items, Storage& storage)
gwbuf_free(pValue); gwbuf_free(pValue);
sleep(hard_ttl - slept + 1); // Expected to get us passed the hard ttl. millisleep(hard_ttl - slept + 1000); // Expected to get us passed the hard ttl.
slept += hard_ttl - slept + 1; slept += hard_ttl - slept + 1000;
pValue = NULL; pValue = NULL;
result = storage.get_value(cache_item.first, CACHE_FLAGS_INCLUDE_STALE, &pValue); result = storage.get_value(cache_item.first, CACHE_FLAGS_INCLUDE_STALE, &pValue);