I've been reviewing a fuelphp project with performance issues.
It boiled down to how (redis) cacheing is implemented in the fuel core.
I didnt find much about best-practices related to the usage of Fuels Cache Class. So maybe we are just using it the wrong way. I was hoping someone could shed some light on it.
So we are using cached DB queries ( DB::query(..)->cached() ). With redis beeing the default storage driver for the cache. And there are many queries in this project that could benefit from cached results.
With a growing number of queries beeing cached, the time it takes to lookup a cache entry grows significantly and i started to investigate.
Since Redis showed many requests to fuel:index:.db i looked at the implementation of Cache_Storage_Redis and found out about that index beeing used to translate between identifier and actual key in the cache.
So for each Cache request, it has to load that huge and growing index.
So i am wondering:
- Should we use more direct implementation to cache our results?
- What kind of workload / use-cass is the \Cache System build for?
It was originally created to mimic the already existing cache classes, and I think it started out as a copy of an existing class, probably the File class.
The index is there because the identifier represents a tree structure, like the folder structure used in the File class. So you need a mapping between the identifier and the cache key, so you know which keys you need to delete if you delete "some/root". If you have a cache entry stored for "some/root/folder/key", this entry should be deleted.
If you have a better solution to store the index tree and perform lookups (perhaps some sort of btree algorithm?), you're free to suggest an update and send in a PR. Fuel is a community framework, we welcome all contributions.
looking at the code i thought "probably this has a reason" so i wanted to ask before moving further. I'll have a deeper look anyways while solving the bottleneck for our use case. Hope this results in an usable PR ;-)
As long as the functionality of the interface doesn't change, any solution will do.
So the tree structure of the identifier must remain, it can't be changed from a tree to a list, that would cause you to loose the ability to delete a part of the tree in a single go (like deleting a directory deletes all files and subdirectories in it).