In high concurrent PHP applications, rational use of cache is a key means to improve performance. APCu is a memory-level cache that is suitable for intermediate data cache in a stand-alone environment. It is fast response and easy to use. However, the life cycle of the cache is also limited, and once the data expires or is cleared, it may lead to cache avalanches or instantaneous concurrency bottlenecks if handled improperly.
This article will introduce how to use the apcu_entry() function and explore how to use it to elegantly solve the performance problems that may arise when cache expires.
apcu_entry() is a function introduced in PHP 5.5+, and its function is:
Try to get a key value from the cache;
If it does not exist, the cache is calculated and written using the provided callback function;
Returns the cached value.
The basic syntax is as follows:
mixed apcu_entry(string $key, callable $callback, int $ttl = 0)
$key : cache key;
$callback : A function executed when the cache does not exist, used to generate values;
$ttl : The valid time of the cache (seconds), default 0 means permanently valid (until the memory is cleared or the script ends).
The so-called "cache breakdown" refers to the fact that a hotspot cached data just expires, and many concurrent requests bypass the cache and directly request back-end resources, resulting in a sudden increase in server pressure.
The traditional method may be as follows:
$key = 'user_profile_123';
$data = apcu_fetch($key);
if ($data === false) {
$data = get_user_profile_from_db(123); // Query from the database
apcu_store($key, $data, 300); // cache 5 minute
}
The problem is that if the cache happens to fail, a large number of requests will execute get_user_profile_from_db() at the same time, which may destroy the database.
And apcu_entry() can be handled like this:
$userId = 123;
$key = "user_profile_$userId";
$data = apcu_entry($key, function() use ($userId) {
// Only one request will be executed here,其他请求会等待结果cache后直接获取
return get_user_profile_from_db($userId);
}, 300); // cache 5 minute
The advantages of doing this are:
Atomic operation to avoid multiple requests triggering slow queries at the same time;
Simple to use and clearer logic;
Built-in "breakdown" mechanism, no additional locking is required.
Suppose we have an interface that is frequently called, for example:
https://api.gitbox.net/weather?city=shanghai
To reduce the frequency of call, we want to cache the result for 60 seconds. Use apcu_entry() to write:
$city = 'shanghai';
$key = "weather_api_result_$city";
$result = apcu_entry($key, function() use ($city) {
$url = "https://api.gitbox.net/weather?city=$city";
$json = file_get_contents($url);
return json_decode($json, true);
}, 60);
In this way, when the cache fails, only one request will actually access the interface, and other requests will wait for the cache to complete and share the result, greatly reducing the pressure on external requests.
Applicable scenarios : APCu is suitable for stand-alone environments except for CLI mode, and is not suitable for multi-process or distributed systems;
Cache penetration : apcu_entry() does not solve cache penetration (i.e., repeated requests for data that do not exist in the cache). You can determine whether the result is null in the callback and then decide whether to write it;
Failure control : Set TTL reasonably to avoid frequent cache failure and excessive memory usage;
Exception handling : It is recommended to do an exception catch internally to prevent exception interruptions in the cache process.
Using apcu_entry() is an elegant caching strategy that PHP developers should master, especially when processing hotspot data and high concurrent access, which can effectively prevent performance jitter problems caused by cache failure. It makes the cache logic simpler, more reliable, and more suitable for the performance optimization needs of modern PHP applications.
In the process of building high-performance web applications, the rational use of apcu_entry() will become a tool for you to improve response speed and system stability.