PHPSocialNetwork / phpfastcache

A high-performance backend cache system. It is intended for use in speeding up dynamic web applications by alleviating database load. Well implemented, it can drops the database load to almost nothing, yielding faster page load times for users, better resource utilization. It is simple yet powerful.
https://www.phpfastcache.com
MIT License
2.36k stars 452 forks source link

Clearing expired cache #884

Closed Yalme closed 1 year ago

Yalme commented 1 year ago

What's your question ?

Hello dear Devs!

The story: I have website with hundreds of thousands pages, each calling side APIs and sometime doing heavy queries. With many search bots and visitors server was heavy loaded. I decided to use your cache project, answering many similar queries with one saved.

The problem: I'm start with using just basic file cache driver. After some time the amount of generated cache files comes to near one million (which is cap for my hosting company) and keep growing. According to my statistic around 40% of cache successfully used as planned and it's good, but new pages creates every day and old cache not need and just become dead weight. I need some mechanism to consistently clear old expired cache to keep server space for new cache files. Not all cache (I know about existed full clear method), because a lot of fresh one is actually work, but only expired.

What I'm tried: Read docs but not found any methods like "clearAllExpiredCache". So I mark all needed cache with some tag, like "to_clear", than query it and remove in cycle. Like this:

$test = $cache->getItemsByTag('to_clear');
foreach ($test as $test_item) {
    // if ($test_item->isExpired()) { // also tried this
    if (!$test_item->isHit()) {
        $cache->deleteItem($test_item->getKey());
    }
}

But seems like it doesn't work. At least "getItemsByTag" getting not all tagged items.

The question: What should I do to solve problem? How to deal with file overflow on server without full cache clear each day?

References (optional)

No response

Do you have anything more you want to share? (optional)

No response

github-actions[bot] commented 1 year ago

Hello curious contributor ! Since it seems to be your first contribution, make sure that you've been:

Geolim4 commented 1 year ago

Hello @Yalme,

My immediate (and short) answer is: It's not possible ATM. Because actually the cache rely on files he needs when cacheItem->get() is called. Nothing more, nothing less.

I can't provide a solution that would "clean expired files" because it would take a lot of CPU resources and time to scan/remove expired files. That's the short answer.

There's plenty of other issues that you need to take into consideration:

My ultimate recommendation, by looking at your issue, is to migrate to a high-performant K/V-based backend such Redis, Ssdb, etc (take a look at the README.md).

Files backend is good and enough for small/medium website with few visitors & cache entries. For a greater usage you absolutely need K/V-based backend.

Geolim4 commented 1 year ago
$test = $cache->getItemsByTag('to_clear');
foreach ($test as $test_item) {
    // if ($test_item->isExpired()) { // also tried this
    if (!$test_item->isHit()) {
        $cache->deleteItem($test_item->getKey());
    }
}

But seems like it doesn't work. At least "getItemsByTag" getting not all tagged items.

It's completely normal, the cache items, even when fetched from expired values, are completely ignored from Phpfastcache core as it will recreate a new and fresh CacheItem object since the expired one has to more interest for us.

Geolim4 commented 1 year ago

Hello @Yalme ,

I’m closing this issue for now because of (inactivity / outdated code / …).

You can always reopen it though! :) Please (update the issue / add comment / clarify …).

Regards, Georges.L