分区和分片

数据库群组是由于各种各样的原因建立的,他可以提升处理能力、容忍错误,并且 提升大量服务器同时工作的的性能。群组有时会组合分区和共享功能,来将大量复杂的任务 分拆成更加简单的任务,更加可控的单元。

插件可以支持各种各样的 MySQL 群组,一些群组会内置一些分区和共享的方法,他们可以 被透明的使用。插件支持最常用的 MySQL 主从同步表过滤和共享 (应用级分区)。

MySQL 主从同步支持过滤方式的分区,他可以让你创建所有数据库同步,或者部分数据库同步。 这样就要求应用能够拥有同样的策略,你可以通过 node_groups 手动的支持这个策略,或者使用实验性质的表过滤器。

从 1.5.0 版本开始,可以通过节点组过滤和 SQL hints 完成手动的分区和共享。 节点组过滤器可以让你将 master 和 slave 命名成一个符号。 范例中, master_0slave_0 被放在一个命名为 Partition_A 的组中。他们能够完全的组成一个群组。 例如,你可以使用一个节点群组用于共享,并且使用使用群组名称作为一个地址共享, 就像 Shard_A_Range_0_100

Example #1 Cluster node groups

{
  "myapp": {
       "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "simulate_slave_failure",
                "port": "0"
            },
            "slave_1": {
                "host": "127.0.0.1",
                "port": 3311
            }
        },
        "filters": {
            "node_groups": {
                "Partition_A" : {
                    "master": ["master_0"],
                    "slave": ["slave_0"]
                }
            },
           "roundrobin": []
        }
    }
}

Example #2 通过 SQL hints 完成手动分区

<?php
function select($mysqli$msg$hint '') {
  
/* Note: weak test, two connections to two servers may have the same thread id */
  
$sql sprintf("SELECT CONNECTION_ID() AS _thread, '%s' AS _hint FROM DUAL"$msg);
  if (
$hint) {
    
$sql $hint $sql;
  }
  if (!(
$res $mysqli->query($sql))) {
    
printf("[%d] %s"$mysqli->errno$mysqli->error);
    return 
false;
  }
  
$row =  $res->fetch_assoc();
  
printf("%d - %s - %s\n"$row['_thread'], $row['_hint'], $sql);
  return 
true;
}

$mysqli = new mysqli("myapp""user""password""database");
if (!
$mysqli)
  
/* Of course, your error handling is nicer... */
  
die(sprintf("[%d] %s\n"mysqli_connect_errno(), mysqli_connect_error()));

/* All slaves allowed */
select($mysqli"slave_0");
select($mysqli"slave_1");

/* only servers of node group "Partition_A" allowed */
select($mysqli"slave_1""/*Partition_A*/");
select($mysqli"slave_1""/*Partition_A*/");
?>
6804 - slave_0 - SELECT CONNECTION_ID() AS _thread, 'slave1' AS _hint FROM DUAL
2442 - slave_1 - SELECT CONNECTION_ID() AS _thread, 'slave2' AS _hint FROM DUAL
6804 - slave_0 - /*Partition_A*/SELECT CONNECTION_ID() AS _thread, 'slave1' AS _hint FROM DUAL
6804 - slave_0 - /*Partition_A*/SELECT CONNECTION_ID() AS _thread, 'slave1' AS _hint FROM DUAL

默认的,插件使用所有配置的 master 和 slave 进行查询操作。但是如果一个查询,使用 /*node_group*/ 的 SQL hint,那么插件将只使用在 node_group 列出的服务器进行查询操作。所以,SELECT 查询操作,只会在 /*Partition_A*/ 列出的 slave_0 中进行。

User Contributed Notes

social at dotmanila dot com 01-Jul-2014 11:11
In the example #2, you can use the @@server_id variable combined with connection_id() for a more distinct combination i.e.:

"SELECT CONNECTION_ID(), @@server_id AS _thread, '%s' AS _hint FROM DUAL"