原来的libmysql用的好好的,为什么还要搞一个mysqlnd出来呢?
原因一: license问题
libmysql是MYSQL AB公司开发的,现在已经是Oracle集团所属的了,它使用MYSQL license发布。
This ultimately led to MySQL support being disabled by default in PHP
mysqlnd 是php的一部分,使用PHP license发布。
从此 licensing 的问题就算是解决了。
原因二:编译问题
使用libmysql的时候,如果要正常编译php,必须首先安装好mysql。
如果是单纯的一台WEB服务器,装个mysql似乎有点浪费了。
mysqlnd的话,就不必安装mysql,直接可用。
原因三:性能问题
由于mysqlnd是一个php扩展,使用了php memory management system,在内存使用方面效率相当高。
举个例子:
使用libmysql的时候,mysql结果集中的每一行都在内存中储存了二次 !
使用mysqlnd,结果集只会储存一次。
而且它还服从于php.ini中memory_limit的设置。
Using MySQL Native Driver leads to comparable or better performance than using MySQL Client Library。
mysqlnd的新特性
1 改进的persistent connection。
2 特殊函数 mysqli_fetch_all()
二.mysqlnd插件
这个扩展, 主要实现了, 连接保持和切换, 负载均衡和读写分离等, 也就是说, 这个扩展会去分别PHP发给MySQL的query, 如果是”读”的query, 就会把query发送给从库(配置中指明), 并且支持负载均衡; 而如果是”写”的query, 就会把query发送给主库.
不过这个扩展需要搭配mysqlnd一起使用(从PHP5.4 beta1开始, 我们已经把mysqlnd作为mysql, mysqli, pdo的默认链接目标, 当然, 你也可以通过–with-mysql=***来制定你想要链接到libmysql).
这个扩展使用的方法也很简单, 首先在php.ini中定义配置:
mysqlnd_ms.enable=1
mysqlnd_ms.ini_file=/path/to/mysqlnd_ms_plugin.ini
之后, 在你指明的mysqlnd_ms_plugin.ini中配置好MySQL的主从库就好了:
[myapp]
master[]=localhost:/tmp/mysql.sock
slave[]=192.168.2.27:3306
从1.1.0开始, 配置文件改为JSON格式:
[mysqlnd_ms]
extension = mysqlnd_ms.so
mysqlnd_ms.enable = On
mysqlnd_ms.config_file = /etc/php5/conf.d/mysqlnd_ms.conf
然后在mysqlnd_ms.conf 配制
mysqlnd_qc介绍
query cache查询缓存.
<?php
/* Use constants for maximum portability /
$query = “/” . MYSQLND_QC_ENABLE_SWITCH . “*/SELECT id FROM test”;
/* Valid but less portable: default TTL /
$query = “/qc=on*/SELECT id FROM test”;
mysqlnd 作为一个 PHP 扩展完成主从同步和负载均衡。他使用 C 语言编写, 从底层嵌入 PHP。伴随 PHP 解释器的启动,他以模块的方式嵌入 PHP 引擎。 他使用 mysqlnd 名称注册在引擎中, 并且使用 mysqlnd 自己的 C 方法替换系统默认操作。
在 PHP 脚本运行期间,他检查所有通过 mysqlnd 发送给 MySQL 服务器的指令。 如果指令时只读的,那么将会发送给排至的 slave 服务器。通过判断语句 是否以 SELECT 开头,决定他是否是只读指令。或者通过 SQL hints /ms=slave/ 指定 slave 运行,或者通过 SQL hints /ms=last_used/ 指定通过上一条查询的连接运行。 其他情况下,指令会被发送到 MySQL 主从同步的 master 服务器执行。
为了更好的移植性,应用应该使用 MYSQLND_MS_MASTER_SWITCH, MYSQLND_MS_SLAVE_SWITCH, 和 MYSQLND_MS_LAST_USED_SWITCH mysqlnd_ms 预定义常量, 替代 SQL hints 的使用,例如:/ms=slave/。
插件控制所有到 master 和 slave 的链接。对于应用来说,只需要控制一个连接。 然而这个应用控制的链接,其实是插件管理的连接池中的一个。插件代理了这些 到 master 的链接,并且管理很多的到达 slave 的链接。
数据库连接的状态,由事务、状态、事务设定、字符集设定、临时表等内容组成。 插件在事务执行的过程中和自动提交指令执行中,维护同样的链接状态。有效维护这些 状态并不容易,当运行 BEGIN TRANSACTION 指令后,插件将 控制权移交给用户。
http://php.net/manual/zh/book.mysqlnd-ms.php#book.mysqlnd-ms
Mysql 主从复制和负载均衡插件 (mysqlnd_ms) 可以帮助我们很简单的支 持所有使用 mysqlnd 的 PHP MySQL 扩展。
自从 PHP 5.3.3 版本,MySQL native driver 以一个 C API 接口的方式存在。这个 C 插件, 可以通过 mysqlnd 完成对 MySQL 主从复制和负载均衡 的相关功能扩展。
从 PHP 5.3.0 以后,MySQL native driver 可以以 C 库的方式工作。它以插入的方式替代 MySQL Client 库 (libmysqlclient) 的作用。使用 mysqlnd 有几个好处: 不需要特别下载内容, 他已经被内置在 PHP 当中; 他基于 PHP 许可协议; 他会消耗更小的内存; 并且他包含很多新的 函数方法 (例如:异步查询).
Mysqlnd 插件 (例如 mysqlnd_ms) 都是从用户的使用要求中提炼出来. mysqlnd_ms 支持所有的 PHP 应用, 和所有的 MySQL PHP 扩展. 他并不改变现有的 APIs, 所以他可以很容易的在现有的 PHP 应用环境中使用.
Key Features ¶
主要功能
透明使用, 并且容易使用.
支持所有的 PHP MySQL 扩展
支持 SSL
一致的 API 接口
只需要很小的基于使用需要的方案设定
被动连接,只有实际的 SQL 执行时,才会与 Master 和 Slaver 进行连接
可选:从 Web request 的第一个写以后自动使用 Master, 降低可能的主从复制的延时影响
可以在 MySQL Cluster 中使用
MySQL Replication: 实现读写分离, 插件主要为 MySQL Replication 编写
MySQL Cluster: 可以禁用读写分离, 可以使用多个 Master
第三方解决方案: 插件为 MySQL Replication 定制开发, 但是也可以适用于其他的 MySQL Cluster 解决方案
读写分离策略
自动检测 SELECT 语句
Supports SQL hints to overrule automatism.
用户自定义
可以被禁用,例如在使用同步 Cluster 时
负载均衡策略
Round Robin: 针对每一个 slave 查询,使用不同的 slave,轮循方式
Random: 随机选择 slave
Random once (sticky): 随机选取一个 slave, 在这个页面的请求过程中, 都是用这个 slave
User-defined: 应用可以在 mysqlnd_ms 中注册一个 callback
从 PHP 5.4.0 以后版本,事务可以通过事务控制的 API 调用进行处理。
Weighted load balancing: Slave 可以被分配不同的优先级, 例如; 可以让更多的查询在一个更好的设备上执行, 或者在一个更近的设备查询以降低延时影响
Global transaction ID
Client-side emulation. Makes manual master server failover and slave promotion easier with asynchronous clusters, such as MySQL Replication.
支持 MySQL 5.6.5 以上版本内置的 GTID.
在 Session 一致性策略下,可以通过 GTID 完成异步 slave 读取最新的数据。
Throttling: optionally, the plugin can wait for a slave to become “synchronous” before continuing.
服务和一致性级别
应用可以在连接中选择:最终、session 和强一致性服务级别。最合适的通讯节点 将自动进行选择。
最终一致性时,MySQL 主从同步的 slave 可以被本地 cache 替换,用于降低服务器负载。
分区和共享
数据库群组中的服务器,可以被定义到组中,利用 SQL hints 可以手动的指定在特定的组中进行查询。 组可以完成数据分区,或者完成数据热点的更新。
MySQL 主从同步过滤可以通过表过滤器支持。
限制 ¶
内置的读写分离机制非常基础, 任何一个以 SELECT 开头的查询, 都被认为是读操作, 从而发送给 slave 服务器. 所有其他的查询 (包括 SHOW) 都会被认为是写操作, 而被发送给 master 服务器. 内置的操作方法可以通过重写 SQL hints 改变, 或者使用一个用户定义的 callback 实现.
读写分离不能提供对于多查询的结构支持, 多查询结果会被认为是一个单一查询. 通过开头的字符串来决定如何执行这些查询. 例如, 如果使用 mysqli_multi_query() 执行多查询 SELECT id FROM test; INSERT INTO test(id) VALUES (1) 将会被认为是一个查询操作, 而被发送给 slave 服务器, 以为他开头使用了 SELECT. 其中的 INSERT 结构,将不会被发送给 master 服务器.
Note:
应用必须知道连接切换的重要性, 他是负载均衡的墓地. 可以查看相关说明: connection pooling and switching, transaction handling, failover load balancing 和 read-write splitting.
插件是一个 PHP 的扩展, 可以查看 installation instructions 学习如何安装 » PECL/mysqlnd_ms 扩展。
编译或配置 PHP MySQL 扩展 (API) (mysqli、 PDO_MYSQL、 mysql),也就是你打算使用的、支持 mysqlnd 的库。 PECL/mysqlnd_ms 是一个 mysqlnd 库的插件。使用任意 PHP MySQL 扩展时,要使用 mysqlnd 必须使用该插件。
然后,使用 mysqlnd_ms.enable 在 PHP 配置文件中装载和激活插件。
Example #1 启用插件(php.ini)
mysqlnd_ms.enable=1
mysqlnd_ms.config_file=/path/to/mysqlnd_ms_plugin.ini
插件使用他自己的配置文件。使用 PHP 指令 mysqlnd_ms.config_file 定义插件配置文件的完整路径。 该文件必须能被 PHP 读取(比如 web 服务器的用户)。 请注意,从 1.4.0 版本开始配置文件变量使用 mysqlnd_ms.config_file, 以前的 mysqlnd_ms.ini_file 不再使用。 使用旧的、不再有效的指令是一个很常见的错误。
在 mysqlnd_ms.config_file 指定的目录中,创建保存插件的配置文件。
插件的 配置文件 基于 JSON 格式。 配置写在一个或者多个章节中。每个章节都包含一个名称,例如: myapp。 每个章节包含自己的配置信息。
一个章节的配置中,至少要包含 MySQL 主从复制中的 master 服务器和相关 slave 服务器。 每个章节只能使用一个 master 服务器。 目前还不能完全支持多 master(Multi-master)的设置。 master 用于设定 MySQL master 服务器的 hostname、port 或 socket。 而 MySQL slave 服务器信息使用 slave 来设定。
Example #2 最基本的插件配置文件 (mysqlnd_ms_plugin.ini)
{
“myapp”: {
“master”: {
“master_0”: {
“host”: “localhost”
}
},
“slave”: [
]
} } 必须配置 MySQL slave 服务器列表,当然它也可以是空的列表。我们建议至少配置一个 slave 服务器。
服务器列表可以使用 匿名或者非匿名语法。 非匿名列表包含一个别名,例如 master_0 可用于上面的例子。 在这里,将使用更详细的非匿名语法。
Example #3 建议最基本的插件配置文件 (mysqlnd_ms_plugin.ini)
{
“myapp”: {
“master”: {
“master_0”: {
“host”: “localhost”,
“socket”: “\/tmp\/mysql.sock”
}
},
“slave”: {
“slave_0”: {
“host”: “192.168.2.27”,
“port”: “3306”
}
}
}
}
如果这里至少有两个服务器,插件可以负载均衡、切换连接。切换链接并不总是透明的,在某些具体条件下会导致问题。本参考中包含 连接池和切换, 事务处理, 故障转移 负载均衡 和 读写分离。稍后在本指南中将具体描述更多潜在的陷阱。
应用需要处理连接切换过程中潜在的问题,配置一个 master 和至少一个 slave,这样就可以切换,因此能发现相关问题。
MySQL 主从同步并不需要你配置 master 和 slave。 为了测试的目的,你可以使用单个 MySQL 服务器,让插件认为是 master 和 slave 服务器,就像以下的设置。这样可以帮助你在连接切换中检测到很多潜在问题。 不过,这样的设置不容易发生因为主从同步延迟而导致的问题。
Example #4 使用一个服务器同时作为 master 和 slave(仅用于测试!)
{
“myapp”: {
“master”: {
“master_0”: {
“host”: “localhost”,
“socket”: “\/tmp\/mysql.sock”
}
},
“slave”: {
“slave_0”: {
“host”: “127.0.0.1”,
“port”: “3306”
}
}
}
}
插件将尝试通知你不合理的配置. 从 1.5.0 版本开始, 下列情况它抛出一个 PHP warning, 配置文件不可读; 空配置或者 JSON 配置语法错误. 通过 PHP 本身的配置,可能这些报警信息 会被放置在某些错误 LOG 文件当中。在验证完毕后,通过配置文件中有效的章节,连接会被建立。 设置 mysqlnd_ms.force_config_usage 可以帮助你进行 DEBUG