After enabling the cache_lifetime variable on a site, it looks like all cache entries are getting a TTL set to that value (including permanent entries), so if I set it to 1 minute, the whole cache is cleared every minute (automatically deleted by Redis). This doesn't seem to be consistent with the wording of the setting or the behaviour of the db cache.
The 2.x version seems to have similar behaviour but only for temporary items, or permanent items with a specified expiry.
From what I can tell on a full cache bin flush, the db cache will wait for cache_lifetime to pass before deleting all temporary cache entries in that bin (in DrupalDatabaseCache->garbageCollection()).
Comments
Comment #1
pounardThe database backend works very differently from Redis' one, and reproducing its behavior gives us no benefits, this is a won't fix, you should not use this setting when using the Redis module.
If I remember correctly cache_lifetime will force invalid items to be kept during this amount of time, and I read correctly the database backend code, it will do it for all cache bins. Considering how hard it was to have a stable version of the Redis 3.x version and the fact that the Redis module relies on the Redis EXPIRE feature, it's not possible to reproduce this behavior without complexifying a lot the code.
Comment #2
pounardNot switching this to closed status else I'll miss your replies. I will switch this to closed later.
Comment #3
pounardLong time no answer, closing this.
Comment #4
das-peter commentedWow, holy cow!!!
I just stumbled over this. I was wondering why I saw some strange inconsistencies in parts of our caching and when debugging I came across
Redis_Cache::refreshMaxTtl().This looks freaking evil if you think how harmless and inviting the
cache_lifetimesetting looks.Let's add a nice orange warning to the configuration page if this setting is enabled and extend the settings description at least.
@pounard I trust your statement in #1, nevertheless it doesn't feel right that something that says "minimum lifetime" is basically converted to maximum lifetime. While I might could somehow understand that this applies to temporary items it seems quite odd for permanent or items with a specific time-out. I simply can't think of any case in which the TTL could / should be smaller than an explicitly set time-out :|
Comment #5
pounardYou are absolutely right.
Comment #6
pounardHello again!
I am sorry, I didn't answered for a long time. For what it worth, changing behaviours is now out of scope for the 7.x-3.x branch. Nevertheless, if that matters, I fixed it into a new PHP library I am working on:
This library aims to be framework agnostic, provides cache backends for Doctrine, Drupal 7, Drupal 8 and Symfony, and many more components in the future. Since it shares code among all implementations, it also tests that the single piece of code actually does respect the specification of all the interfaces it implements.
It is more thoroughly unit tested, and much more feature-complete: https://github.com/makinacorpus/redis-bundle.
I am closing this issue, the future 7.x-4.x branch will mostly be glue code to make it work gracefully with this shared library.
Comment #7
nicksanta commentedI encountered a problem with this behavior. In this paricular project (Drupal 7) we only used Redis for the cache_form bin. This meant that
a) cache_lifetime had to be enabled for the default cache bins (set to 15 minutes in our case), and
b) our cache_form entries were being garbage cleaned after only 15 minutes - despite Drupal explicitly requesting a 6 hour expiration on cache_form entries.
This result of this was our users received 500 errors and lost their state in multi-step forms if they took more than 15 minutes to complete the form.
We solved this by creating a new cache backend class. If anyone else out there is running into this problem using 7.x-3.x you can solve with this:
settings.php
sites/default/CustomRedisCache.php
Comment #8
les limPart of the problem here is that having a cache_lifetime setting makes the Redis backend treat CACHE_TEMPORARY and CACHE_PERMANENT entries exactly the same - both will get explicit expirations set at `cache_lifetime` seconds in the future. I'm okay with Redis using the cache_lifetime value that way for CACHE_TEMPORARY items, but CACHE_PERMANENT should continue to be treated with the permTTL default setting of 1 year.
Here's a patch to restore that. I'll leave the status as-is since the branch is end-of-life, but it might be helpful to someone else.
Comment #9
cafuego commentedI just wasted a lot of time checking why cached Drupal 7 data was disappearing and finally came to this issue.
Can we get at least that warning patch into the 3.x branch of the module, if not a way to simply allow specific per-bin maximum TTLs via $conf?
Comment #10
torgospizzaSince there's still no 4.x branch, and 3.x is the "recommended version" for Drupal 7, I vote to commit the patch from #8. It's a small patch and appears to be a much-needed fix.
Comment #11
urashima82 commentedHello,
I encountered the same problem and patch #8 solves it. I also vote to commit the patch from #8.
Comment #12
pounardOK, fair enough, I'll commit this asap.
Comment #15
pounardI commited the fix. I think that I did a mistake originally, and you saw it: permTtl was never in use whereas it was exactly meant for this. Thanks a lot!
Comment #16
pounardI'm sorry for not seeing this earlier.
Comment #17
pounardI created the 7.x-3.18 release, you now just have to wait a few minutes for the packages to be built.
Comment #18
pounardComment #19
cafuego commentedThank you @pounard 🎉