Current Location: Home> Latest Articles> How to avoid apcu_entry cache penetration problem

How to avoid apcu_entry cache penetration problem

gitbox 2025-05-28

In PHP's cache strategy, the apcu_entry() function is widely used to simplify cache read and write operations. It makes the code more concise by providing a callback function that automatically generates and stores data when the cache does not exist. However, if used improperly, it may cause "cache penetration" problems, which will cause additional burden on the system.

This article will explore how to effectively avoid cache penetration in the process of using apcu_entry() .

What is cache penetration?

Cache penetration refers to the situation where the cache system query is missed and the backend database cannot find data. Attackers or crawlers can constantly request non-existent data, bypass the cache layer and directly access the database, causing a sudden increase in database pressure.

In the context of apcu_entry() , if a database query is performed on each missed key, it is equivalent to giving the cache a green channel.

Basic usage of apcu_entry()

 $value = apcu_entry("user_123", function() {
    // Get data from the database
    return fetch_user_from_db(123);
});

This code is logically concise. If the key does not exist, the callback function will be automatically called and the return result will be stored in the cache. However, if fetch_user_from_db() returns null (such as the user does not exist), will null be cached too? The default is yes. The problem is:

  • If null is not cached, the database will be triggered every request;

  • If null is cached, you should also pay attention to the cache time and how to distinguish between "checking no data" and "data expiration".

How to prevent cache penetration?

1. Explicitly cache "null values"

When the database cannot find data, a special flag value is returned and a short expiration time is set. For example:

 $value = apcu_entry("user_123", function() {
    $user = fetch_user_from_db(123);
    return $user !== null ? $user : '__NULL__';
});

When using it, judge:

 if ($value === '__NULL__') {
    // The data does not exist,Safely ignore or return 404
} else {
    // Normal use of data
}

Doing so can effectively avoid the problem of repeated access to the database.

2. Control the cache time of empty values

In order to avoid cached large amounts of "invalid" data, you can set the cache time of null values, such as using apcu_store() instead of apcu_entry() :

 $key = "user_123";
if (!apcu_exists($key)) {
    $user = fetch_user_from_db(123);
    $value = $user !== null ? $user : '__NULL__';
    apcu_store($key, $value, $user !== null ? 600 : 60);
} else {
    $value = apcu_fetch($key);
}

This method is more flexible and suitable for scenarios where fine-grained control is required.

3. Strengthen key filtering

Cache penetration is often caused by illegal or random keys. You can verify the key, such as whether the user ID is an integer or whether it is within the legal range:

 function is_valid_user_id($id) {
    return is_numeric($id) && $id > 0 && $id < 1000000;
}

if (!is_valid_user_id($id)) {
    exit('Invalid user ID');
}

Only a legitimate ID allows continued access to the database or cache system.

Summarize

When using apcu_entry() , if there is no null value processing strategy, it is very easy to cause cache penetration problems. We can effectively avoid this risk by caching null values, controlling expiration time, and key verification. Rational use of cache strategies can not only improve performance, but also enhance the system's compressive resistance.

Remember, the goal of cache design is not to "save all the data", but to "stay most requests at the cache layer".

To further practice these suggestions, you can deploy in your own environment, for example:

 $url = "https://gitbox.net/api/user/123";

Using real-life scenarios to test cache hit and penetration logic, it helps to deepen understanding and optimize implementation.