BitPoet Posted February 27, 2020 Share Posted February 27, 2020 Here's a small new module that started as a spinoff of a memcache proof-of-concept. Cache your strings and partials in-memory using Redis as a backend. CacheRedis All you need is a running Redis database. The module supports connection through regular TCP, over TLS and via unix domain sockets. Host and port are configurable, and authentication is supported too. Here's a screenshot of the module configuration options: I'll not go into too many details about the usage, you can see everything explained in the README on GitHub, and just highlight the most important points. When the module is active, you'll have a wired $redis variable, which means you can reach the module as $redis, wire("redis") or within Wire classes / modules as $this->redis. CacheRedis is strongly influenced by WireCache, and its usage is (hopefully) straight forward. // Store an entry in the cache under the given key name with the given value: $redis->store("cached_value_number_one", $expire, $value); // Retrieve a value from the cache $value = $redis->fetch($key); // Delete a cache entry $redis->delete("my_other_cached_value"); // Clear the whole cache $redis->flush(); // Retrieve a value from the cache, and if not found, create it through the given function // and store it with a lifetime of 5 minutes (300 seconds) $value = $redis->fetch($key, 300, function() use($page) { return "Page last changed on " . strftime('%m/%d/%Y %H:%M', $page->modified | $page->created); }); // Render a file using wireRenderFile and store it in the cache. // We'll pass a selector as the expiry value so this cache gets // emptied every time a page matching the selector is saved. $news = $redis->renderFile("partials/news.php", 'template=blog-post', ["page" => $page]); The module is still very crude work in progress, but I hope some of you feel daring, try it out and let me know in case anything breaks. Have fun! 16 3 Link to comment Share on other sites More sharing options...
netcarver Posted December 15, 2020 Share Posted December 15, 2020 Hi @BitPoet This looks great. Are we able to get/save/flush using any kind of namespacing? Wirecache has getFor() / saveFor() / deleteFor() etc, which are very useful for classifying cache entries and doing targeted flushing. Link to comment Share on other sites More sharing options...
BitPoet Posted December 18, 2020 Author Share Posted December 18, 2020 On 12/15/2020 at 4:06 PM, netcarver said: This looks great. Are we able to get/save/flush using any kind of namespacing? Wirecache has getFor() / saveFor() / deleteFor() etc, which are very useful for classifying cache entries and doing targeted flushing. Built into the dev branch at https://github.com/BitPoet/CacheRedis/tree/dev are storeFor() / fetchFor() / deleteFor(). I'm not a thousand percent sure how reliable this is in large environments, since this uses SCAN and UNLINK to iterate with a wildcard over all keys in the namespace and deletes them asynchronously. You can pass TRUE as the third parameter to deleteFor to force synchronous deletion, but SCAN may at (rare) times return incomplete results anyway. Needs at least redis 2.8.0. 1 Link to comment Share on other sites More sharing options...
netcarver Posted December 18, 2020 Share Posted December 18, 2020 @BitPoet Fantastic, thank you. I guess you mean the flushing of a namespace regarding the SCAN with DEL/UNLINK operations? Hmm, I wonder if we could keep either a hash or set for all the keys within a namespace, then flushing the namespace could become something like a lua EVAL that iterates the hash/set doing the deletes and then empties the hash/set as one atomic operation without a load of network traffic. Will have a think about it, it's been years since I did any Lua scripting in Redis. 1 Link to comment Share on other sites More sharing options...
netcarver Posted December 18, 2020 Share Posted December 18, 2020 Even then, for large cardinalities, the Lua script idea (with or without a hash/set holding the key references) would be blocking on other processes using Redis. So this might not be ideal either. At least with your current implementation it's non-blocking as there are separate calls to redis. However, that needs to be weighed against the network overhead. Link to comment Share on other sites More sharing options...
netcarver Posted December 19, 2020 Share Posted December 19, 2020 @BitPoet I've cloned the module and pushed an experimental script for deleteFor() here. It uses a Lua script that's evaluated in the Redis server. My rough testing using 100k namespaced keys shows this to be much faster than iterating over the scan results in PHP and the PHP cpu + network load is also much lower. However, that is at the cost of blocking the Redis server whilst the delete is taking place. I've not massaged this into a pull request yet, as I'd like to get your feedback on it. 1 Link to comment Share on other sites More sharing options...
BitPoet Posted December 19, 2020 Author Share Posted December 19, 2020 6 hours ago, netcarver said: I've cloned the module and pushed an experimental script for deleteFor() here. It uses a Lua script that's evaluated in the Redis server. My rough testing using 100k namespaced keys shows this to be much faster than iterating over the scan results in PHP and the PHP cpu + network load is also much lower. However, that is at the cost of blocking the Redis server whilst the delete is taking place. I've not massaged this into a pull request yet, as I'd like to get your feedback on it. Thanks, this looks good at first glance. I'm going to give it a spin as soon as I find the time. I'll probably want to let the user choose between client and server side tradeoffs depending on the use case, which also means deciding which is the reasonable default. 1 Link to comment Share on other sites More sharing options...
netcarver Posted December 19, 2020 Share Posted December 19, 2020 Great, thank you @BitPoet Would be good to get the count of deleted keys back from deleteFor() rather than the value of the $force parameter. I've updated my dev fork to return the count of deleted keys. Link to comment Share on other sites More sharing options...
Ivan Gretsky Posted May 19 Share Posted May 19 Good day, @BitPoet! Are you planning to merge dev branch to have a new stable? 1 Link to comment Share on other sites More sharing options...
BitPoet Posted June 19 Author Share Posted June 19 On 5/19/2022 at 9:22 AM, Ivan Gretsky said: Good day, @BitPoet! Are you planning to merge dev branch to have a new stable? Hi @Ivan Gretsky, I will at one point for sure, but that will be late in the year. I‘m currently hiking across the U.S. and won‘t get my hands on a computer until October. 3 Link to comment Share on other sites More sharing options...
bernhard Posted June 20 Share Posted June 20 As I've never used redis I had to do some research what it is and what it does... Here's a good video that gives you a quick overview: Would be interesting to hear why/where/when one could use this module and what benefit one would get vs. using WireCache 🙂 1 Link to comment Share on other sites More sharing options...
netcarver Posted June 20 Share Posted June 20 @bernhard I use redis alongside PW on some client sites (using php-resque for background jobs like email composition and send) - though I do not use this particular module in production yet. I think bitpoet is aiming for an API-compatible drop-in for wirecache that leverages the lower latency of redis' in-memory accesses. 3 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now