Consistently use swappable cache interfaces
Background
CiviCRM caches were originally (and are primarily) stored in the table civicrm_cache
. This design is great for small sites (easy to deploy on server with less software to administer). However, for larger sites that get value from using multiple MySQL servers, it's not so great: cache data (by its nature) is frequently written+read, but it's expensive to write cache data when there are multiple MySQL servers... and the overhead doesn't give us much benefit because the data is fundamentally expendable. A lighter system (like Memcache/Redis) would be more generally appropriate.
You might recall that CiviCRM's cache subsystem can optionally incorporate Memcache/Redis (since roughly 4.3ish?). This appears as CRM_Utils_Cache_*
, and it started some great improvements (e.g. using faster cache providers; and swapping cache providers). Notably, the functionality uses Memcache/Redis as an extra cache tier (i.e. when reading a cache, it first checks memcache; then it falls back to checking civicrm_cache
in MySQL). This helps read performance (because your cache-hit usually returns faster), but it doesn't help write performance (because you need to propagate cache-writes to every tier). Using only Memcache/Redis (as a single tier -- without MySQL) would be even better for performance.
I don't believe that the status quo reflects a technical necessity. (If you can handle deployment/configuration of Memcache/Redis a front-tier... then you can probably handle it as the main tier.) Rather, it reflects a development practicality: the app was originally written to only use civicrm_cache
. Consequently, there are a handful of oddball use-cases/code-paths which directly access civicrm_cache
or CRM_Core_BAO_Cache
, and it would've been harder to do anything if it had required finding+fixing all of them.
Scope
The general scope of this ticket is to hunt down the oddball use-cases/code-paths which directly reference civicrm_cache
or CRM_Core_BAO_Cache
. I expect the project to produce a handful of distinct PRs. To avoid redundantly documenting this, I'm aiming for each PR to have a more concrete discussion about the use-cases/code-paths being cleaned up.
PR List
- 12330 - CRM_Utils_Cache_Redis::flush() - Respect prefixes (m)
- 12331 - CRM_Utils_Cache - Always use a prefix. Standardize delimiter (m)
- 12336 - systemStatusCheckResult - Migrate from settings to cache (m)
- 12342 - Caching - Comply with PSR-16 interfaces (m)
- 215 - Import PSR-16 compliance test (m)
- 12348 - Cache-keys for CRM_Utils_Cache_* should avoid reserved chars (m)
12350 - civicrm_cache - Allow storage of binary data- 12354 - civicrm_cache - Allow storage of binary data (m)
-
12360- Full PSR-16 compliance for ... (depends:12342, 12348, 12354). Cherry-picked to form smaller PRs: - 12362 - Forms/Sessions - Store state via Civi::cache('session') (depends: 12360)
- 12368 - ~~civicrm_cache - Finish transition from DATETIME to TIMESTAMP~~ (m)
See also
- #217 (closed) - Allow replacement of PrevNextCache implementation (for search screens)
- #284 (closed) - Aggressive cache clearing significantly increases test time