Cache Module
The cache
module is used to cache attributes. The idea is that you can look
up information in a database, and then cache it. Repeated requests for the same
information will then have the cached values added to the request.
The module can cache a fixed set of attributes per key.
It can be listed in any recv
or send
section.
If you want to have different things cached for different
sections, you will need to define multiple instances of the module,
via cache <nameN> { … } .
|
Option | Description |
---|---|
|
if it found or created a cache entry. |
|
if it merged a cached entry. |
|
if it did nothing. |
|
on error. |
Configuration Settings
- driver
-
The current backend datastore used to store the cache entries are:
Driver | Description |
---|---|
|
An in memory, non persistent rbtree based datastore. Useful for caching data locally. |
|
A non persistent "webscale" distributed datastore. Useful if the cached data need to be shared between a cluster of RADIUS servers. |
|
A persistent "webscale" clustered, sharded, data store. Extremely fast, and a good candidate for sharing data such as EAP session blobs, between a cluster of servers. |
Some drivers accept specific options, to set them a config section with the the name as the driver should be added to the cache instance. |
Driver specific options are:
Memcached cache driver
- options
-
Memcached configuration options.
The memcached options are documented at http://docs.libmemcached.org/libmemcached_configuration.html#memcached
- pool
-
Connection pool.
Redis cache driver
- server
-
Redis Server name.
If using Redis cluster, multiple 'bootstrap' servers may be listed here (as separate config items). These will be contacted in turn until one provides us with a valid map for the cluster. Server strings may contain unique ports.
e.g.:
server = '127.0.0.1:30001' server = '[::1]:30002'
Instantiation failure behaviour is controlled by pool.start
as
with every other module, but with clustering, the pool section
determines limits for each node in the cluster, not the cluster
as a whole.
- port
-
Port to use for Redis server.
The default port is 6379.
- password
-
For authenticating ourselves to the Redis server.
- database
-
The database number to use.
- pool
-
Connection pool.
- key
-
The
key
used to index the cache. It is dynamically expanded at run time. - ttl
-
The TTL of cache entries, in seconds. Entries older than this will be expired.
This value should be between 10
and 86400
.
You can flush the cache via
radmin -e "set module config cache epoch 123456789"
Where last value is a 32-bit Unix timestamp. Cache entries older
than this are expired, as new entries added.
You should never set the "epoch" configuration item in this file.
|
- add_stats
-
If
yes
the following attributes will be added to the request:-
&request.Cache-Entry-Hits
- The number of times this entry has been retrieved.
-
Not supported by the rlm_cache_memcached module.
|
- max_entries
-
Maximum entries allowed.
- update { … }
-
The attributes to cache for a particular key.
Each key gets the same set of cached attributes.
The operation of the update
section is a little different
from normal update
sections. This is because we need to
both reference the attributes which we want to store in the
cache, and also to describe where those attributes are
written to when the cache entry is read.
The solution (albeit an imperfect one) is that the cache
does not store attributes, it stores update
sections.
The update
section given below is used as a template
for the cache entry.
When the cache entry is created, the right-hand side of each attribute assignment line is expanded. The left-hand side of the attribute assignment is left alone.
Once all of the right-hand side values are expanded, the
result is an update
section with left-hand side
assignments, and right-hand side values. That update
section is then cached, indexed by the key
When the cache entry is read, it is looked up by the key
,
and the cached update
section is found. This cache entry
now has left-hand side assignments, and right-hand side
values. It is then applied to the current request.
For example, if the cache
module is configured with the
block below:
update { &reply.Reply-Message := "Hello %{User-Name}" }
When the cache entry is created, the module will expand the
right side of the entry, using the attributes from the
packet. In this case, the string could expand to "Hello bob"
.
Once all of the right-hand values are expanded, the resulting cache entry will look like this:
update { &reply.Reply-Message := "Hello bob" }
When the cache module is read, this update
section is
applied just as if it had been specified in a configuration
file.
Only request , reply , control and
session-state lists are available for the left side of
cache entries. Attempting to reference other lists will
raise an error during config validation.
|
- <list>.<attribute> <op> <value>
-
Cache all instances of
Reply-Message
in the reply list.
Add our own to show when the cache was last updated.
Add your own value for Class
.
How to use
Configuration
This module supports a number of runtime configuration parameters
represented by attributes in the &control.
list.
- &control.Cache-TTL
-
Sets the TTL of an entry to be created, or modifies the TTL of an existing entry.
Condition | Description |
---|---|
|
Set the TTL of the entry to the new value (and reset the expiry timer). |
|
Expire the existing entry and create a new
one with TTL set to |
|
Expire the existing entry and create a new one. |
- &control.Cache-Status-Only
-
If present and set to
yes
will prevent a new entry from being created, and existing entries from being merged. It will also alter the module’s return codes.-
The module will return
ok
if a cache entry was found. -
The module will return
notfound
if no cache entry was found.
-
If this is set to yes , no other cache control attributes will
be honoured, but they will still be cleared.
|
- &control.Cache-Allow-Insert
-
If present and set to
no
will prevent a new entry from being created. If not present or set toyes
, and no entry exists, a new one will be created. This is evaluated afterCache-TTL
, so expired entries may be recreated. - &control.Cache-Allow-Merge
-
If present and set to
no
will prevent existing entries from being merged. If not present or set toyes
, and an entry exists (and is valid), it will be merged with the current request. This is evaluated beforeCache-TTL
, so entries being expired may first be merged. - &control.Cache-Merge-New
-
If present and set to
yes
will merge new cache entries into the current request. Useful if results of execs or expansions are stored directly in the cache.
All runtime configuration attributes will be removed from the
&control. list after the cache module is called.
|
Methods
The cache module also allows handling the cache using the methods.
- cache.status
-
Verify if an entry already exists without load the entries.
Return | Description |
---|---|
|
if a cache entry was found. |
|
if no cache entry was found. |
|
if the cache was unavailable. |
- cache.load
-
Load an existing cache entry and merge it into the request.
Return | Description |
---|---|
|
if a cache entry was found and loaded. |
|
if no cache entry was found. |
|
if the cache was unavailable. |
- cache.update
-
Perform an upsert against the data store, updating the entry TTL
Return | Description |
---|---|
|
if we added cache entry. |
|
if the cache was unavailable. |
- cache.store
-
Inserts data into the cache if, and only if, it is not already present Will not update the entry TTL.
Return | Description |
---|---|
|
we created or updated a cache entry. |
|
if a cache entry aready existed. |
|
if the cache was unavailable. |
- cache.clear
-
Delete cache entry from the data store without checking if the entry already exists.
Return | Description |
---|---|
|
if we found and removed a entry. |
|
if no cache entry was found. |
|
if the cache was unavailable. |
- cache.ttl
-
Change the TTL on an existing entry.
Return | Description |
---|---|
|
if we found entry and updated the ttl. |
|
if no cache entry was found. |
|
if the cache was unavailable. |
Examples
# Add a cache entry
&control.Cache-TTL := 1h
cache.store
if (updated) {
..keys stored
}
# Get the cache status
cache.status
if (ok) {
..Exist a cache entry
}
# Load the cache entry
cache.load
if (updated) {
..loaded
}
# Change the entries TTL
&control.Cache-TTL := 30m
cache.ttl
if (updated) {
..ttl changed
}
# Clear the cache
cache.clear
if (ok) {
..cache is empty
}
|
Default Configuration
cache {
# driver = "rbtree"
# memcached {
# options = "--SERVER=localhost"
# pool {
# start = 0
# min = 0
# max =
# spare = 1
# uses = 0
# lifetime = 0
# idle_timeout = 60
# }
# }
# redis {
# server = 127.0.0.1
# port = 6379
# password = 'supersecret'
# database = 0
# pool {
start = 0
min = 0
# max =
# spare = 1
# uses = 0
# lifetime = 0
# idle_timeout = 60
# }
# }
key = &User-Name
ttl = 10
add_stats = no
# max_entries = 0
update {
&reply.Reply-Message := &reply.Reply-Message
&reply.Reply-Message += "Cache last updated at %t"
&reply.Class := "%randstr(ssssssssssssssssssssssssssssssss)"
}
}