Connection processing parsing of MongoDB PHP driver

Source: Internet
Author: User
Tags deprecated findone mongoclient mongodb driver mongodb server php mongodb
The 1.3 version of PHP MongoDB driver has rewritten the connection processing library, and there have been significant changes in both persistent connections and connection pooling compared to previous versions.

Connection management for version 1.2

The 1.2 version of the driver introduces a connection pool, and when any query is executed, a connection is requested from the connection pool and then returned to the connection pool. The completion here means that the variable holding the connection leaves its scope, and here is an example.

The simplest version:

 
  demo->test; $c->insert (Array (' Test ' = ' yes ')); >

← $m Leave the scope, the connection is returned to the connection pool

In the function:

 
  demo->test;        $c->insert (Array (' Test ' = ' yes '));} ← $m Leave the scope, the connection is returned to the connection pool?>

In some cases, the system may generate a large number of connections, such as referencing a connection object in a complex structure of ORMS/ODMS, as in the following example:

 
  

Connection management for version 1.3

In version 1.3, connection management has made a lot of changes. In each worker process (thread, PHP-FPM, or Apache worker), the driver separates the connection management from the Mongo* object, reducing the complexity of the drive. The following is a single-node MongoDB instance that describes how the drive handles the connection.

When a worker process starts, the MongoDB driver initializes the connection Manager to manage the connection, and there is no connection by default.

When the first request calls New Mongoclient (), the driver creates a new connection and identifies the connection with a hash value. This hash value includes the following parameters: hostname, port, process ID, and optional replica set name, and if it is a password-authenticated connection, the hash value of the database name, user name, and password (for password-authenticated connections, discussed later in detail). Call the Mongoclient::getconnections () method to see the hash value for the connection:

 
  GetConnections () [0][' Hash ']);? >

Output:

String ("whisky:27017;-; X;22835″

The "-" in the output indicates that the connection does not belong to a replica set, "X" is a placeholder without a user name, database, and password, and 22835 is the process ID of the current process.

The connection is then registered in the Connection Manager:

Whenever a connection is required, including inserting, deleting, updating, finding, or executing commands, the driver requests an appropriate connection to the manager for execution. The parameters of the new Mongoclient () and the ID of the current process are used when the connection is requested. Each worker process/thread, the Connection Manager will have a list of connections, and each PHP worker will run only one request at a time, so there is only one connection to each mongodb, and it is constantly reused until the PHP The worker terminates or explicitly calls Mongoclient::close () to close the connection.

Replica Sets

In environments where replication sets exist, the situation is somewhat different. In the connection string for new Mongoclient (), you need to specify multiple hosts and indicate that a copy set is currently being applied:

$m = new Mongoclient ("Mongodb://whisky:13000,whisky:13001/?replicaset=seta");

The Replicaset parameter cannot be omitted, otherwise the driver will assume that you are ready to connect three different mongos processes.

When instantiated, the driver examines the topology of the replica set. The output of the following example shows that after calling New Mongoclient (), all the visible data nodes in the replication set will register a connection in the manager:

 
  GetConnections () as $c) {    echo $c [' hash '], ' \ n ';}? >

Output:

Whisky:13001;seta; x;32315 Whisky:13000;seta; x;32315

Although there are no whisky:13000 nodes in the connection string, there are two connections registered in the manager:

The manager contains not only the hash value of the connection and the TCP/IP socket, but also which node is the primary node and the "distance" for each node. The following script shows these additional information;

 
  GetConnections () as $c) {    echo $c [' hash '], ": \ n",        "-{$c [' connection '] [' Connection_type_desc ']},",        "{$c [ ' Connection ' [' Ping_ms ']} ms\n ";}? >

Output:

Whisky:13001;seta; x;5776:? Secondary, 1 Ms Whisky:13000;seta; x;5776:? PRIMARY, 0 ms

The drive divides the operations into two types: write operations, including INSERT, UPDATE, delete, and command, and read operations, including find and FindOne. By default, if the read preference parameter is not set, the manager always returns the connection to the primary node. The read preferences can be set through the Setslaveokay () or in the connection string:

$m = new Mongoclient ("mongodb://whisky:13000,whisky:13001/?replicaset=seta&readpreference=secondarypreferred" );

With these parameters, the connection string becomes exceptionally long, so the PHP driver allows the option to be placed in an array and passed in as a second parameter:

$options = Array (        ' replicaset ' = ' seta ',        ' readpreference ' = ' secondarypreferred ',); $m = new Mongoclient ("mongodb://whisky:13000,whisky:13001/", $options);

For each operation, the driver requests to the manager for an appropriate connection. For a write operation, the connection to the primary node is always returned, and for a read operation, the secondary node's connection is returned if the secondary node is available and the distance is not far away.

Authenticated connection

If MongoDB enables authentication, the concatenated hash value contains the validation-related hash value. This allows different scripts to connect to different databases on the same mongodb using different usernames and passwords, without misusing the connection. The following example uses the admin username to connect to the Admin database and then observe the change in the hash value:

 
  GetConnections () [0][' Hash ']);? >

Output:

String ("Whisky:27017;-;admin/admin/bda5cc70cd5c23f7ffa1fda978ecbd30;8697″")

The "X" section in the previous example has been replaced with a database name, admin, username admin, and hash value bda5cc70cd5c23f7ffa1fda978ecbd30, which is calculated based on the user name, database name, and password hash.

To verify that it works correctly, you need to include the database name in the connection string, otherwise it will default to admin.

To use a database after a connection is established, you need to select the database first, such as:

$collection = $m->demodb->collection; $collection->findone ();

If the selected database is the database specified in the connection string, or if the database in the connection string is admin, everything will work. Otherwise, the driver creates a new connection, preventing the validation from being bypassed as follows:

 
  test2; $collection = $db->collection;var_dump ($collection->findone ());? >

Output:

Fatal error:uncaught exception ' mongocursorexception ' with message ' whisky:27017:unauthorized db:test2 NS: Test2.collection lock type:0 client:127.0.0.1′in .../mongo-connect-5.php.txt:6

This failed because our connection did not perform authorization validation for the TEST2 database. If we perform the validation, it will work:

 
  Test2, $db->authenticate (' user2 ', ' user2 '); $collection = $db->collection; $collection->findone (); foreach ($ M->getconnections () as $c) {    echo $c [' hash '], ' \ n ';}? >

Output:

whisky:27017;-;test/user/602b672e2fdcda7b58a042aeeb034376;26983 whisky:27017;-;test2/user2/ 984b6b4fd6c33f49b73f026f8b47c0de;26983

Now there are two authenticated connections in the manager:

Incidentally, if you turn on the e_deprecated level error, you will see:

Deprecated:function mongodb::authenticate () is Deprecated in .../mongo-connect-6.php.txt on line 5

Driver recommendations complete this type of task by creating two Mongoclient objects:

 
  FALSE); $mTest 2 = new Mongoclient (' Mongodb://user2:user2@whisky:27017/test2 ', array (' Connect ' = False); $mTest 1- >test->test->findone (); $mTest 2->test2->test->findone (); foreach ($mTest 2->getconnections () As $c) {    echo $c [' hash '], ' \ n ';}? >

A single MongoDB server can support a fairly limited number of concurrent connections, and if you use PHP-FPM, each worker process has its own separate pool of connections, which makes it easy to reach the upper limit of connections. Therefore, in a production environment, whether or not you are using a replica set, you deploy MONGOs, and then PHP-FPM Connect MONGOs, which reduces the number of mongod connections, and you can use short connections between PHP-FPM and MONGOs ( That is, each request ends with an explicit call to the close function to close the MongoDB connection.

Source: Wind of the Edge of the blog

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.