Intro to PECL/mysqlnd_ms
Chris Barber
Minnesota PHP User Group
April 7, 2011
About Me

Chris Barber
Lead Software Engineer @ Appcelerator
CEO/Technology Consultant @ CB1, INC.
JavaScript, PHP, C++
http://www.cb1inc.com
@cb1kenobi on Twitter, Slideshare
What is mysqlnd?
What is mysqlnd?

MySQL Native Driver for PHP
PHP 5.3+
Replaces libmysql
Used by ext/mysql, ext/mysqli, PDO_MYSQL
Use configure options: --with-mysql=mysqlnd --with-
mysqli=mysqlnd --with-pdo-mysql=mysqlnd
Not compiled into Ubuntu’s PHP 5.3 package :(
What is mysqlnd_ms?
What is mysqlnd_ms?



A PHP Extension that provides transparent MySQL
load balancing across master and slave servers
How it works


Create a mysqlnd_ms_config.ini with your settings
Make MySQL calls from your PHP code
INSERT, UPDATE, & DELETE statements go to master
SELECT statements go to slaves
Getting started
php.ini

extension=mysqlnd_ms.so
mysqlnd_ms.enable=1
mysqlnd_ms.ini_file=mysqlnd_ms_config.ini
mysqlnd_ms_config.ini

[myapp]
master[]=192.168.1.120
slave[]=192.168.1.121
slave[]=192.168.1.122
PHP Usage
<?php

$db = mysqli(“myapp”, “user”, “password”);

$results = $db->query(“SELECT ...”);

$db->query(“INSERT ...”);

?>
Which server to connect to?
Choosing a server

Available load balancing algorithms:
  random
  round-robin
  user defined (custom PHP function)
  random_once (sticky)
Specify algorithm in the mysqlnd_ms_config.ini file
Choosing a server
       [myapp]
       master[]=192.168.1.120
       slave[]=192.168.1.121
       slave[]=192.168.1.122
       pick[]=user
       pick[]=random




<?php

function pick_server($connected_host, $query, $master, $slaves, $last_used_connection) {
 if (stristr($query, “FROM table_a”))
   return “hostname_of_slave_for_table_a”;

    return NULL; // resort to random/random-once/round-robin
}

mysqlnd_ms_set_user_pick_server(“pick_server”);

?>
Issues...
Issues

INSERT and immediate SELECT
  Replication lag
Transactions
  Need server stickiness
Failover
Hints

  Prefix query with a comment!
<?php

$db = mysqli(“myapp”, “user”, “password”);
$results = $db->query(“/* HINT_GOES_HERE */SELECT ...”);

?>
Built-in Hints
 MYSQLND_MS_MASTER_SWITCH
 MYSQLND_MS_SLAVE_SWITCH
 MYSQLND_MS_LAST_USED_SWITCH
 MYSQLND_MS_ALL_SERVER_SWITCH
 MYSQLND_MS_QUERY_USE_MASTER
 MYSQLND_MS_QUERY_USE_SLAVE
 MYSQLND_MS_QUERY_USE_LAST_USED
Hints

<?php

$db->query(sprintf(“/*%s*/SET @a=1”, MYSQL_MS_SLAVE_SWITCH));

$db->query(sprintf(“/*%s*/SET @a=@a+1”, MYSQL_MS_LAST_USED_SWITCH));

$db->query(sprintf(“/*%s*/SELECT @a as _a”, MYSQL_MS_LAST_USED_SWITCH));

?>
Custom Hints

<?php

function pick_server($connected_host, $query, $master, $slaves, $last_used_connection) {
  if (preg_match("@^/*.+*/@ismU", $query, $matches)) {
    $json = json_decode($matches[1])
    if ($json && $json->something_enabled) {
      return “some_special_hostname”;
    }
  }

  return NULL; // resort to random/random-once/round-robin
}

mysqlnd_ms_set_user_pick_server(“pick_server”);

$db->query(“/* {“something_enabled”:true} */SELECT ...”);

?>
Server Picking Ideas


 Geo-load balancing
 Routing around server maintenance
 Sharding
 Dynamically add/override master/slave hostnames
Failover

 mysqlnd_ms does not do failover
 Do it in your application!
 Retry query N number of times before falling on sword
 Have pick_server() “disable” dead servers for a minute
   Perhaps use APC to cache which servers are dead
Getting mysqlnd_ms
svn co http://svn.php.net/repository/pecl/mysqlnd_ms/
trunk mysqlnd_ms
cd mysqlnd_ms
phpize
configure
make
sudo make install
More Info


Authors: Andrey Hristov, Ulf Wendel, & Johannes
Schlueter
http://blog.ulf-wendel.de
http://svn.php.net/viewvc/pecl/mysqlnd_ms
Thanks
Questions?

Intro to PECL/mysqlnd_ms (4/7/2011)