Highly Available MySQL/PHP Applications with mysqlnd

Post on 15-Jan-2015

1.037 views 3 download

Tags:

description

PHP Users Group Philippines July Meetup

Transcript of Highly Available MySQL/PHP Applications with mysqlnd

Highly Available PHP/MySQL Applications with mysqlnd

Jervin Real PHP-UGPH, June 2014

Highly Available Applications

• … how much your application is able to serve its end users within a time period

Highly Available Applications

• … how much your application is able to serve its end users within a time period

• Usually referred to as 99[..]% uptime

Highly Available Applications

• … how much your application is able to serve its end users within a time period

• Usually referred to as 99[..]% uptime

• It actually depends on whose perspective

Highly Available Applications

Keep PHP<>MySQL downtime to a minimum

WTF are you saying? I’m a “devloper"!

No no no no no no!

Lack of knowledge

Limited resources

How?

MySQL

MySQL HA

• MySQL Native Replication (Single Primary)

MySQL HA

• MySQL Native Replication (Single Primary)

• MySQL Native Replication (Multi-Master)

MySQL HA

• MySQL Native Replication (Single Primary)

• MySQL Native Replication (Multi-Master)

• MySQL NDB Cluster

MySQL HA

• MySQL Native Replication (Single Primary)

• MySQL Native Replication (Multi-Master)

• MySQL NDB Cluster

• Galera based

MySQL HA

• MySQL Native Replication (Single Primary)

• MySQL Native Replication (Multi-Master)

• MySQL NDB Cluster

• Galera based • Percona XtraDB Cluster • MariaDB Galera Cluster • MySQL+Galera

MySQL HA

• MySQL Native Replication (Single Primary)

• MySQL Native Replication (Multi-Master)

• MySQL NDB Cluster

• Galera based • Percona XtraDB Cluster • MariaDB Galera Cluster • MySQL+Galera

• Tungsten Replicator

MySQL HA

• MySQL Native Replication (Single Primary)

• MySQL Native Replication (Multi-Master)

• MySQL NDB Cluster

• Galera based • Percona XtraDB Cluster • MariaDB Galera Cluster • MySQL+Galera

• Tungsten Replicator

• … and many more

• MySQL Master HA

MySQL HA (External Support)

MySQL HA (External Support)

• MySQL Master HA

• Percona Replication Manager (Pacemaker)

MySQL HA (External Support)

• MySQL Master HA

• Percona Replication Manager (Pacemaker)

• Haproxy

MySQL HA (External Support)

• MySQL Master HA

• Percona Replication Manager (Pacemaker)

• Haproxy

• Load Balancers

MySQL HA (External Support)

• MySQL Master HA

• Percona Replication Manager (Pacemaker)

• Haproxy

• Load Balancers

• MySQL Multi Master

MySQL HA (External Support)

• MySQL Master HA

• Percona Replication Manager (Pacemaker)

• Haproxy

• Load Balancers

• MySQL Multi Master

PHP (Application)

HA via Application

• Traditionally complex to implement

• Unnecessary overhead

• No single point of failure

mysqlnd

mysqlnd

• MySQL Native Driver

mysqlnd

• MySQL Native Driver

• Written C (as all extensions should be!)

mysqlnd

• MySQL Native Driver

• Written C (as all extensions should be!)

• MySQL Client Libraries no more

mysqlnd

• MySQL Native Driver

• Written C (as all extensions should be!)

• MySQL Client Libraries no more

• Smaller memory footprint in many cases

mysqlnd

• MySQL Native Driver

• Written C (as all extensions should be!)

• MySQL Client Libraries no more

• Smaller memory footprint in many cases

• Performance statistics

mysqlnd

• MySQL Native Driver

• Written C (as all extensions should be!)

• MySQL Client Libraries no more

• Smaller memory footprint in many cases

• Performance statistics

• Compression

mysqlnd

• MySQL Native Driver

• Written C (as all extensions should be!)

• MySQL Client Libraries no more

• Smaller memory footprint in many cases

• Performance statistics

• Compression

• Plugins

mysqlnd Plugins

• mysqlnd_qc - query result cache

mysqlnd Plugins

• mysqlnd_qc - query result cache

• mysqlnd_mux - connection multiplexing

mysqlnd Plugins

• mysqlnd_qc - query result cache

• mysqlnd_mux - connection multiplexing

• mysqlnd_uh - user handler

mysqlnd Plugins

• mysqlnd_qc - query result cache

• mysqlnd_mux - connection multiplexing

• mysqlnd_uh - user handler

• mysqlnd_memcache - Memcache (MySQL interface)

mysqlnd Plugins

• mysqlnd_qc - query result cache

• mysqlnd_mux - connection multiplexing

• mysqlnd_uh - user handler

• mysqlnd_memcache - Memcache (MySQL interface)

• mysqlnd_ms - replication and load balancing

mysqlnd_ms

mysqlnd_ms Supported Clusters

• All previously mentioned with few limitations

Limitations (Master-Slave)

• Master is a single point of failure

• Need external help for failover

• . . or, shoot the other node in the foot, this is still HA!

Limitations (Master-Slave)

Limitations (Master-Slave)

Limitations (Master-Slave)

Limitations (Master-Master)

• Risky, even if you try segregating writes per master you can still lose data

Limitations (Master-Master)

db1

db1

Limitations (Master-Master)

db1

db1

Limitations (Master-Master)

db2

db1

Limitations (Master-Master)

db1 + db2

• Not good if sync_binlog = 0 AND/OR innodb_flush_log_at_trx_commit <> 1

• Not really recommended in general, use appropriate technologies instead

Some More Limitations

• Lazy connections is on by default

• Each request will create its own connections when needed, persistent connections may be required

• https://bugs.php.net/bug.php?id=67564

• https://bugs.php.net/bug.php?id=67565

• https://bugs.php.net/bug.php?id=67574

• Be careful with multi-statements and read-write splitting, they are likely to be executed on slave!

SELECT  *  FROM  tbl;  DELETE  FROM  tbl;

• Single Primary - one writable node

• Multiple Primary - all nodes writable

mysqlnd_ms Supported Clusters

• Master-Slave

mysqlnd_ms Supported Clusters

• Master-Slave

• Declare 2 clusters

mysqlnd_ms Supported Clusters

• Master-Slave

• Declare 2 clusters

• When primary fails, mark it permanently dead and switch to secondary

mysqlnd_ms Supported Clusters

• Master-Slave

• Declare 2 clusters

• When primary fails, mark it permanently dead and switch to secondary

{      "primary":  {          "master":  {              "master_1":  {                  "host":  "127.0.0.1",                  "port":  33001              }          },          "slave":  {              "slave_0":  {                  "host":  "127.0.0.1",                  "port":  33002              }          }      },      "standby":  {          "master":  {              "master_1":  {                  "host":  "127.0.0.1",                  "port":  33002              }          },          "slave":  {          }      }  }

mysqlnd_ms Supported Clusters

• Master-Slave

• Declare 2 clusters

• When primary fails, mark it permanently dead and switch to secondary

• Works better with master-master!

{      "primary":  {          "master":  {              "master_1":  {                  "host":  "127.0.0.1",                  "port":  33001              }          },          "slave":  {              "slave_0":  {                  "host":  "127.0.0.1",                  "port":  33002              }          }      },      "standby":  {          "master":  {              "master_1":  {                  "host":  "127.0.0.1",                  "port":  33002              }          },          "slave":  {          }      }  }

mysqlnd_ms Supported Clusters

• Master-Slave Demo

• https://github.com/dotmanila/demo-me/phpugph201407/

• master-slave.ini

• mysqlnd_ms_ms.ini

• master-slave.php

mysqlnd_ms Supported Clusters

• Multi-Masters (NDB, Galera)

• Declare all nodes as masters

mysqlnd_ms Supported Clusters

• Multi-Masters (NDB, Galera)

mysqlnd_ms Supported Clusters

• Multi-Masters (NDB, Galera)

• Declare all nodes as masters

mysqlnd_ms Supported Clusters

 {        "primary":  {            "master":  {                "master_1":  {                    "host":  "192.168.56.44",                    "port":  "3306"                },                "master_2":  {                    "host":  "192.168.56.43",                    "port":  "3306"                },                "master_3":  {                    "host":  "192.168.56.42",                    "port":  "3306"                }            },            "slave":  {  },            "filters":  {  "random":  [  ]  },            "failover":  {                  "strategy":  "loop_before_master",                  "remember_failed":  true              }        }    }

• Multi-Masters (NDB, Galera)

mysqlnd_ms Supported Clusters

 {        "primary":  {            "master":  {                "master_1":  {                    "host":  "192.168.56.44",                    "port":  "3306"                },                "master_2":  {                    "host":  "192.168.56.43",                    "port":  "3306"                },                "master_3":  {                    "host":  "192.168.56.42",                    "port":  "3306"                }            },            "slave":  {  },            "filters":  {  "random":  [  ]  },            "failover":  {                  "strategy":  "loop_before_master",                  "remember_failed":  true              }        }    }

• Multi-Masters (NDB, Galera)

• Declare all nodes as masters

• roundrobin - single node writer (first node in config)

mysqlnd_ms Supported Clusters

 {        "primary":  {            "master":  {                "master_1":  {                    "host":  "192.168.56.44",                    "port":  "3306"                },                "master_2":  {                    "host":  "192.168.56.43",                    "port":  "3306"                },                "master_3":  {                    "host":  "192.168.56.42",                    "port":  "3306"                }            },            "slave":  {  },            "filters":  {  "random":  [  ]  },            "failover":  {                  "strategy":  "loop_before_master",                  "remember_failed":  true              }        }    }

• Multi-Masters (NDB, Galera)

• Declare all nodes as masters

• roundrobin - single node writer (first node in config)

• random - all nodes

mysqlnd_ms Supported Clusters

 {        "primary":  {            "master":  {                "master_1":  {                    "host":  "192.168.56.44",                    "port":  "3306"                },                "master_2":  {                    "host":  "192.168.56.43",                    "port":  "3306"                },                "master_3":  {                    "host":  "192.168.56.42",                    "port":  "3306"                }            },            "slave":  {  },            "filters":  {  "random":  [  ]  },            "failover":  {                  "strategy":  "loop_before_master",                  "remember_failed":  true              }        }    }

• Multi-Masters (NDB, Galera)

• Declare all nodes as masters

• roundrobin - single node writer (first node in config)

• random - all nodes

• remember_failed is not what it says it is

 {        "primary":  {            "master":  {                "master_1":  {                    "host":  "192.168.56.44",                    "port":  "3306"                },                "master_2":  {                    "host":  "192.168.56.43",                    "port":  "3306"                },                "master_3":  {                    "host":  "192.168.56.42",                    "port":  "3306"                }            },            "slave":  {  },            "filters":  {  "random":  [  ]  },            "failover":  {                  "strategy":  "loop_before_master",                  "remember_failed":  true              }        }    }

mysqlnd_ms Supported Clusters

• Master-Master Demo

• https://github.com/dotmanila/demo-me/phpugph201407/

• master-master.ini

• mysqlnd_ms_mm.ini

• master-master.php

mysqlnd_ms Supported Clusters

Am I Using mysqlnd? (rpm)

[revin@forge  ~]$  rpm  -­‐q  php-­‐mysql.x86_64  -­‐-­‐requires  […]  libmysqlclient_r.so.16()(64bit)  libmysqlclient_r.so.16(libmysqlclient_16)(64bit)  libmysqlclient.so.16()(64bit)  libmysqlclient.so.16(libmysqlclient_16)(64bit)  […]

[revin@forge  ~]$  rpm  -­‐q  php-­‐mysqlnd.x86_64  -­‐-­‐requires  php-­‐pdo(x86-­‐64)  =  5.4.30-­‐36.el6.art  rpmlib(VersionedDependencies)  <=  3.0.3-­‐1  rpmlib(FileDigests)  <=  4.6.0-­‐1  rpmlib(PayloadFilesHavePrefix)  <=  4.0-­‐1  rpmlib(CompressedFileNames)  <=  3.0.4-­‐1  libc.so.6()(64bit)  libc.so.6(GLIBC_2.2.5)(64bit)  libc.so.6(GLIBC_2.3.4)(64bit)  libc.so.6(GLIBC_2.4)(64bit)  libpthread.so.0()(64bit)  libpthread.so.0(GLIBC_2.2.5)(64bit)  rtld(GNU_HASH)  rpmlib(PayloadIsXz)  <=  5.2-­‐1

Am I Using mysqlnd? (rpm)

[revin@forge  ~]$  php  -­‐i  […]  !mysql  !MySQL  Support  =>  enabled  Active  Persistent  Links  =>  0  Active  Links  =>  0  Client  API  version  =>  5.1.59  MYSQL_MODULE_TYPE  =>  external  MYSQL_SOCKET  =>  /var/lib/mysql/mysql.sock  MYSQL_INCLUDE  =>  -­‐I/usr/include/mysql  MYSQL_LIBS  =>  -­‐L/usr/lib64/mysql  -­‐lmysqlclient

Am I Using mysqlnd? (phpinfo)

[revin@forge  ~]$  php  -­‐i  […]  !mysqlnd  !mysqlnd  =>  enabled  Version  =>  mysqlnd  5.0.10  -­‐  20111026  -­‐  $Id:  c85105d7c6f7d70d609bb4c000257868a40840ab  $  Compression  =>  supported  SSL  =>  supported  Command  buffer  size  =>  4096  Read  buffer  size  =>  32768  Read  timeout  =>  31536000  Collecting  statistics  =>  Yes  Collecting  memory  statistics  =>  No  Tracing  =>  n/a  Loaded  plugins  =>  mysqlnd,example,debug_trace,     auth_plugin_mysql_native_password,     auth_plugin_mysql_clear_password  API  Extensions  =>  mysql,mysqli,pdo_mysql

Am I Using mysqlnd? (phpinfo)

Conclusion

• Yes, we can achieve HA with mysqlnd_ms

• Not for the faint of heart

• Do not rely on for HA (writes) on critical production systems

• Good for intended use case, rw-splitting

Q&A

• http://dotmanila.com/blog/ • http://www.mysqlperformanceblog.com/ • @dotmanila

Percona is Hiring!!http://www.percona.com/about-us/careers/open-positions

$t  =  true  AND  false;  echo  (int)  $t;