-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multple persistent connections to the same Redis host with different databases: database number changes #1920
Comments
1, found the same issue in our environment. |
This issue still persists, |
issue still persists on phpredis: 5.3.4 |
For me, it looks like last selected database is chosen in all connections. |
For anyone with the same problem: try to avoid using databases when possible. If you need logical separation of data (e.g. session storage vs cache vs Prometheus data), spin up another Redis instance. It doesn't add much overhead, but it isolates your data and makes debugging so much easier. |
ini_set('redis.pconnect.pooling_enabled', 0); // Default is 1 Works as expected after set "redis.pconnect.pooling_enabled=0". I think, "redis.pconnect.pooling_enabled=1" means sharing idle redis connections across php-fpm progress by host and port.
I found commit 8206b14749e2583895023312c2143116c2480a50 caused this problem My Suggest:
This is my test code: <?php
// Switch this config and refresh page to test.
// =0; getDbNum() keep same to getDbIndexFromConnection()
// =1; getDbNum() same as getDbIndexFromConnection() on first time, but show random result after.
ini_set('redis.pconnect.pooling_enabled', 0);
function makeConnection($id) {
$redis = new Redis();
// Change to your own redis params
$redis->pconnect('127.0.0.1', 6379, 5, $id);
return $redis;
}
/**
* Show Redis ClientID
*/
function getConnectionId($redis) {
return $redis->client('ID');
}
/**
* Retrieve the REAL dbIndex from Redis Connection
*/
function getDbIndexFromConnection($redis) {
$conns = $redis->client('LIST');
$clientId = $redis->client('ID');
foreach ($conns as $conn) {
if ($conn['id'] === $clientId) {
return $conn['db'];
}
}
return null;
}
$redis0 = makeConnection('redis0');
$redis1 = makeConnection('redis1');
$redis1->select(1);
$redis2 = makeConnection('redis2');
$redis2->select(2);
echo 'PID: ', getmypid(), PHP_EOL;
echo
getConnectionId($redis0), ' ',
$redis0->getDbNum(), ' ',
getDbIndexFromConnection($redis0), PHP_EOL;
$redis0->set('REDIS_0', '0');
echo
getConnectionId($redis1), ' ',
$redis1->getDbNum(), ' ',
getDbIndexFromConnection($redis1), PHP_EOL;
$redis1->set('REDIS_1', '1');
echo
getConnectionId($redis2), ' ',
$redis2->getDbNum(), ' ',
getDbIndexFromConnection($redis2), PHP_EOL;
$redis2->set('REDIS_2', '2'); |
I can still reproduce this behaviour and I consider this a critical bug. At least it should be documented in the description of pconnect(). I am not happy with the recommendation to not use different DBs because saving everything to DB 0 makes it impossible to use FLUSHDB to quickly delete logical portions of the stored data (and other things). If turning off persistent connections and using several Redis instances, instead of using one existing connection (from the pool) or connecting one single time I would have to connect (for instance) 4 Times during the handling of one Request (if I want to access 4 different instances instead of 4 DBs). This has a huge performance impact, as connecting (an sending a subsequent AUTH command) is probably the slowest thing many scripts do. Please fix this, my recommendation would be to save the selected DB alongside the connection and if it is not 0, issue a "SELECT 0" before handing a connection from the pool over to another PHP script. |
Does this issue also happen on |
ini_set('redis.pconnect.pooling_enabled', 0); Disable pconnect pooling should fix your problem, it just disable pconnect pooling, pconnect is still a long-live connection, the difference is: with redis.pconnect.pooling_enabled=1 connection shares across php-fpm, with redis.pconnect.pooling_enabled=0 connection bound to php-fpm process which created it. |
Currently, I'm debugging an issue where cache keys were written into the wrong database after adding a new persistent connection (separate This code seems to not use the Lines 3090 to 3119 in 008ec53
Is this not a bug where the What I don't understand yet: what are the implications of disabling |
This hit us when trying to use a dedicated database for a Symfony RedisSessionHandler. Cache keys kept appearing in the wrong database. In fact, only keys for db I've asked if they would consider a workaround in Symfony, too. |
…stent_id string Fixes phpredis#1920
…tions (uncaught) This PR was merged into the 5.4 branch. Discussion ---------- [Cache] Always select database for persistent redis connections | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | Fix #51578 | License | MIT Even though the `dbindex` is supposed to be `0` by default for any new redis connection, when dealing with a persistent connection pool, due to a [bug in phpreds](phpredis/phpredis#1920) you can actually end up on a different database. This PR will call `select` even for a `dbindex` of `0` under these conditions to assure you are actually on the right database. Commits ------- ce4f815 bug #51578 [Cache] always select database for persistent redis connections
Did you configure |
Expected behaviour
Redis documentation for the SELECT command says that
So subsequent SELECT commands on different connections should not change the database number for other connections, even if the database 0 was not explicitly selected.
And if the database for connection was changed for any reason,
Redis::getDbNum()
method should return database number being used.Actual behaviour
I have the following script which runs in PHP-FPM:
On the first and second requests the keys appear in correct databases (MONITOR output from redis-cli):
Checking the keys in redis-cli:
However, on the third request (without flushall between requests) the "REDIS_0" key appears in the database 2:
Checking the keys:
Meanwhile, during all the requests
$redisN->getDbNum();
outputs correct database numbers:0 1 2
.I'm seeing this behaviour on
I've checked
develop
branch - not sure how do I check thatThe text was updated successfully, but these errors were encountered: