Detailed explanation of PHP using Redis long connection method

  • 2021-09-11 19:43:55
  • OfStack

This article illustrates how PHP uses Redis long connections. Share it for your reference, as follows:

Project address of php-redis on github: https://github.com/phpredis/phpredis

pconnect Function Declaration

Where time_out indicates how many seconds the client is idle before disconnecting. Function connection returns true for success and false for failure:


pconnect(host, port, time_out, persistent_id, retry_interval)
    host: string. can be a host, or the path to a unix domain socket
    port: int, optional
    timeout: float, value in seconds (optional, default is 0 meaning unlimited)
    persistent_id: string. identity for the requested persistent connection
    retry_interval: int, value in milliseconds (optional)

The following example details the reuse of pconnect connections.


$redis->pconnect('127.0.0.1', 6379);
$redis->pconnect('127.0.0.1'); //  Default port 6379, Use the same connection as the above example. 
$redis->pconnect('127.0.0.1', 6379, 2.5); //  Set 2.5 The expiration time of seconds. Will be a new connection different from the above 
$redis->pconnect('127.0.0.1', 6379, 2.5, 'x'); // Object with persistent connections set id Will be a new connection different from the one above 
$redis->pconnect('/tmp/redis.sock'); // unix domain socket - would be another connection than the four before.

Introduction to the use of pconnect

Brief description of pconnect method

Using this method to create a connection, the connection will not be closed after the close method is called, but will be closed only after the process ends.

[Pending Verification] If you are using a long connection, the timeout configuration entry in the Redis configuration file needs to be set to 0, otherwise connections in the connection pool will expire due to timeout

For PHP-FPM, explain pconnect under 1

Long connections end only after the PHP-FPM process ends, and the life cycle of the connection is the life cycle of the PHP-FPM process.
Compared to shorter connections, one redis connection is generated during every PHP-FPM call, and the table form on the server is excessive time_out connection state.
In contrast to long connections, all CGIs called by PHP-FPM will only share one long connection, so only a fixed number of time_out will be generated.

Close long connections

You can call close and unset methods, but the two are quite different:

-The function of close is only to make the current PHP process no longer make redis requests, but it can't really close the redis long connection, and the connection will still be reused in subsequent requests until the life cycle of FPM process ends. So close does not destroy the redis object, it just disconnects.

-The unset variable is destroyed. It should also be noted that close is not needed if pconnect is used. If the current script takes a long time to execute, it will take up 1 connection directly.

How to judge whether the current Redis is connected or not

The equivalent problem is to determine whether the current instance is valid in singleton mode.

It is customary to call echo to determine whether the string itself is returned normally, or call ping to see if the return value is + PONG.

Be careful, however, when echo and ping (return '+ POMG') are called after redis is disconnected, exceptions are thrown. Therefore, it should be handled by exception catching mechanism.

Code analysis of pconnect connection reuse

Case 1: Non-singleton mode.

Description: a instance and b instance share a connection, b instance will be a instance connection modification:
Therefore, the following example causes the final $a instance to get a value of 2, which requires special attention.


$a = pconnect(host, port, time_out);
select(3);
$a -> setex(id, 3);
echo $a -> get(id);
// After that, perform the following connection 
$b = pconnect(host, port, time_out);
select(2);
$b->set(id,2)
echo $a->get(id);  // This id Operational db Become 2 , no longer the previous one 3 It's over. Because these two connections share 1 Connecting channels. 

Case 2: Singleton mode.

Modifying the above code, both a and b are generated through getInstance. The premise of generation is to judge whether the current instance exists. The confusion of singleton pattern lies in:

$a generates an instance, $b is generated, $b uses the instance of $a, then modifies the connection of $a, and then calling $a must be the modified instance of the called $b. With situation 21.
The code for the singleton pattern is as follows:


public static function getInstance($db = 0)
{
  if (!isset(self::$_instance)) {
    self::$_instance = new Redis();
  }
  self::_connect();
  self::$_instance->select($db);
  return self::$_instance;
}

Both cases illustrate the problem of connection reuse. How do I fix this bug? Two points:

1. Generate 1 singleton for every 1 db.
2. Avoid connection reuse issues.

So the code can be adjusted to return a singleton array:


public static function getInstance($db = 0)
{
  try{
    if (isset(self::$_instance[$db]) && self::$_instance[$db]->Ping() == 'Pong') {
      return self::$_instance[$db];
    }
  } catch (Exception $e) {
  }
  self::$_instance[$db] = new Redis();
  self::_connect($db);
  return self::$_instance[$db];
}

Places to pay attention to

Avoid using redis objects in Task class member variables.

In the singleton schema of redis, the expiration time of time_out is declared. If redis handles a task, and the interval between tasks calling redis is relatively long. When the interval is greater than time_out, redis will be disconnected, and all operations on redis will fail at this time. The solution is to avoid this invocation by dynamically declaring the redis class where it is called. This kind of problem is indistinguishable between long connection and short link, which belongs to the wrong way of calling.

For more readers interested in PHP related content, please check the topics on this site: "Summary of php+redis Database Programming Skills", "Introduction to php Object-Oriented Programming", "Introduction to PHP Basic Syntax", "Encyclopedia of PHP Array (Array) Operation Skills", "Summary of php String (string) Usage", "Introduction to php+mysql Database Operation Skills" and "Summary of php Common Database Operation Skills"

I hope this paper is helpful to everyone's PHP programming.


Related articles: