MySQL · 2017-08-13 4

MySQL ProxySQL 分片

MySQL Sharding with ProxySQL

2016年8月30日

 

本文演示了MySQL和ProxySQL分片是如何工作的。

最近我的一位同事让我写一个关于ProxySQL如何进行分片简单的例子。

作为回应,我写这个简短的教程,希望它能很好的说明ProxySQL分片功能,并帮助人们更好地理解如何使用它。

ProxySQL是一个功能强大的平台,它能让我们用一个简单而有效的方法操作和管理数据库连接和查询。本文将向您展示ProxySQL是如何做到的。

 

开始前,让我们理解一些基本概念。

  • ProxySQL组织其内部设置的服务器主机组(HG),并且每个HG可以与users和查询规则(Query Rules:QR)关联;
  • 每个QR可以作为结尾(apply= 1),或者让ProxySQL继续解析其他QRs;
  • QR可以是重写操作,可以是一个简单的匹配,可以有一个特定的目标主机组(HG),或者是通用的;
  • QRs使用正则表达式定义。

 

可以看到,查询规则(QRs)像一个的过滤器和转换的序列,你可以随意编排它。

 

这些简单的基本规则给我们巨大的灵活性。它允许我们创建非常简单的动作,比如一个简单的查询、重写,或者非常复杂的数十个QR的连接链。可以去here找到相关文档。

 

HGs和QRs的相关信息可以使用ProxySQL管理员接口方便的访问,在表mysql_servers, mysql_query_rules stats.stats_mysql_query_rules。最后一张表可以评估这些规则是否以及如何使用的( The last one allows us to evaluate if and how the rule(s) is used )。

 

至于分片,ProxySQL能做些什么来帮助我们实现我们需要的(以一个相对简单的方法)?一些程序员和企业在应用程序中引入分片逻辑,使用多个连接达到不同的目标,或者使一些逻辑跨多个schema/table分割负载。ProxySQL allows us to simplify the way connectivity and query distribution is supposed to work reading data in the query or accepting HINTS.

 

不管是什么需求,分片(sharding)可以归纳为一下几个不同的类别:

  • 通过分割相同的容器中的数据(如有碎片的状态,每个状态都是一个模式)
  • 通过物理数据位置(在同一个空间里可以有多个MySQL服务器,页可以是在地理上的分布)
  • 两者的结合,使用专用服务器通过State做分割,同时随意分割schema/table (say by gender)

 

在下面的例子中,我将展示如何使用ProxySQL完成上面定义的三种不同的场景(并多加了一些情况)。

 

下面的例子将从管理ProxySQL接口和MySQL控制台给出报告文本。我将做如下标记:

  • Mc作为MySQL console
  • Pa 作为ProxySQL Admin

请注意,MySQL控制台必须使用 – c标志通过查询中的comments。这是因为MySQL控制台的默认行为是删除comments。

 

我将演示整个过程,你也可以在笔记本电脑上做同样的实验,并在可能的情况下我将提到真正的实现过程。因为我想让你直接测试ProxySQL功能。

 

对于下面描述的示例,我将使用ProxySQL v1.2.2版本,它将在不久之后成为主流。你可以去下面的地址下载:

git clone https://github.com/sysown/proxysql.git

git checkout v1.2.2

编译:

cd <path to proxy source code>

make

make install

如果你需要如何安装和配置ProxySQL完整的说明,请阅读 herehere

最后,您需要加载WORLD test DB。WORLD test DB可以去here找到。

 

Shard inside the same MySQL Server using three different schemas split by continent

显然,您可以拥有任意数量的分片和相关的schema。这里将演示流量(traffic)如何被重定向(redirected)到不同的目标(schemas),并保持相同的结构(表),基于数据中相关信息识别目标,或者通过应用程序。

OK, let us roll the ball.(让我们滚球)
[Mc]
+---------------+-------------+
| Continent | count(Code) |
+---------------+-------------+
| Asia | 51 | <--
| Europe | 46 | <--
| North America | 37 |
| Africa | 58 | <--
| Oceania | 28 |
| Antarctica | 5 |
| South America | 14 |
+---------------+-------------+

对于这个练习,我将使用3个主机。

总结一下,我将需要:

  • 3台主机:168.1.[5-6-7]
  • 3个schema:Continent X + world schema
  • 1个用户:user_shardRW
  • 3个主机组:10,20,30(以后会用到)

首先,创建schema:Asia, Africa, Europe:
[Mc]
Create schema [Asia|Europe|North_America|Africa];
create table Asia.City as select a.* from world.City a join Country on a.CountryCode = Country.code where Continent='Asia' ;
create table Europe.City as select a.* from world.City a join Country on a.CountryCode = Country.code where Continent='Europe' ;
create table Africa.City as select a.* from world.City a join Country on a.CountryCode = Country.code where Continent='Africa' ;
create table North_America.City as select a.* from world.City a join Country on a.CountryCode = Country.code where Continent='North America' ;
create table Asia.Country as select * from world.Country where Continent='Asia' ;
create table Europe.Country as select * from world.Country where Continent='Europe' ;
create table Africa.Country as select * from world.Country where Continent='Africa' ;
create table North_America.Country as select * from world.Country where Continent='North America' ;

再创建user:
grant all on *.* to user_shardRW@'%' identified by 'test';

现在,可以开始配置ProxySQL了:
[Pa]
insert into mysql_users (username,password,active,default_hostgroup,default_schema) values ('user_shardRW','test',1,10,'test_shard1');
LOAD MYSQL USERS TO RUNTIME;SAVE MYSQL USERS TO DISK;
INSERT INTO mysql_servers (hostname,hostgroup_id,port,weight) VALUES ('192.168.1.5',10,3306,100);
INSERT INTO mysql_servers (hostname,hostgroup_id,port,weight) VALUES ('192.168.1.6',20,3306,100);
INSERT INTO mysql_servers (hostname,hostgroup_id,port,weight) VALUES ('192.168.1.7',30,3306,100);
LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;

到此,我们已经定义了用户,服务器和主机组。

现在开始定义查询规则(query rules)的逻辑:
[Pa]
delete from mysql_query_rules where rule_id > 30;
INSERT INTO mysql_query_rules (rule_id,active,username,match_pattern,replace_pattern,apply) VALUES (31,1,'user_shardRW',"^SELECT\s*(.*)\s*from\s*world.(\S*)\s(.*).*Continent='(\S*)'\s*(\s*.*)$","SELECT \1 from \4.\2 WHERE 1=1 \5",1);
LOAD MYSQL QUERY RULES TO RUNTIME;SAVE MYSQL QUERY RULES TO DISK;

我现在去查询主节点(或某个单节点),但是我希望ProxySQL能重定向查询到正确的分片,获取continent的值:
[Mc]
SELECT name,population from world.City  WHERE Continent='Europe' and CountryCode='ITA' order by population desc limit 1;
+---------+---------------+
| name | population |
+---------+------------+
| Roma |  2643581 |
+---------+---------------+

你也许会说:“你在查询World schema,当然会得到正确的数据。”

事实是这并没有发生,ProxySQL并没有去查询World库,而是查了Europe库。

让我们看一下细节:
[Pa]
select * from stats_mysql_query_digest;
Original    :SELECT name,population from world.City  WHERE Continent='Europe' and CountryCode='ITA' order by population desc limit 1;
Transformed :SELECT name,population from Europe.City WHERE ?=? and CountryCode=? order by population desc limit ?

让我来解释一下发生了什么。

ProxySQL中的31号规则将获取我们需要查询的所有字段,它可以在WHERE子句中获取CONTINENT字段,它将采用WHERE后面的所有条件,并用正则重组所有的queries。

这种机制适用于所有的分片(schema)吗?答案是肯定的。

像这样的查询:SELECT name,population from world.Country WHERE Continent=’Asia’ ;

将被转换为:SELECT name,population from Asia.Country WHERE ?=?
[Mc]
+---------------------------+------------------+
| name             | population  |
+---------------------------+------------------+
| Afghanistan        |   22720000 |
| United Arab Emirates |    2441000 |
| Armenia           |    3520000 |
<snip ...>
| Vietnam           |   79832000 |
| Yemen            |   18112000 |
+---------------------------+-------------------+

另一个可能的方案是通过注释里的提示指导ProxySQL分片,让我们看看是怎么做的。

首先,禁用刚才插入的规则,这不是必须的,但我会这样做以便你们能理解整个过程。
[Pa]
mysql> update mysql_query_rules set active=0 where rule_id=31;
Query OK, 1 row affected (0.00 sec)
mysql> LOAD MYSQL QUERY RULES TO RUNTIME;SAVE MYSQL QUERY RULES TO DISK;
Query OK, 0 rows affected (0.00 sec)

Done.

现在我所希望的是:对包含注释/* continent=X */的所有查询,都指向continent X 库,相同的服务器。

为此,我让ProxySQL替换所有查询中有引用World库的语句。
[Pa]
delete from mysql_query_rules where rule_id in (31,33,34,35,36);
INSERT INTO mysql_query_rules (rule_id,active,username,match_pattern,replace_pattern,apply,FlagOUT,FlagIN) VALUES (31,1,'user_shardRW',"\S*\s*\/\*\s*continent=.*Asia\s*\*.*",null,0,23,0);
INSERT INTO mysql_query_rules (rule_id,active,username,match_pattern,replace_pattern,apply,FlagIN,FlagOUT) VALUES (32,1,'user_shardRW','world.','Asia.',0,23,23);
INSERT INTO mysql_query_rules (rule_id,active,username,match_pattern,replace_pattern,apply,FlagOUT,FlagIN) VALUES (33,1,'user_shardRW',"\S*\s*\/\*\s*continent=.*Europe\s*\*.*",null,0,25,0);
INSERT INTO mysql_query_rules (rule_id,active,username,match_pattern,replace_pattern,apply,FlagIN,FlagOUT) VALUES (34,1,'user_shardRW','world.','Europe.',0,25,25);
INSERT INTO mysql_query_rules (rule_id,active,username,match_pattern,replace_pattern,apply,FlagOUT,FlagIN) VALUES (35,1,'user_shardRW',"\S*\s*\/\*\s*continent=.*Africa\s*\*.*",null,0,24,0);
INSERT INTO mysql_query_rules (rule_id,active,username,match_pattern,replace_pattern,apply,FlagIN,FlagOUT) VALUES (36,1,'user_shardRW','world.','Africa.',0,24,24);
LOAD MYSQL QUERY RULES TO RUNTIME;SAVE MYSQL QUERY RULES TO DISK;

它是怎么工作的呢?

我定义了2个级联规则。

第一条规则:抓取包含有期望值的查询(如continent = Asia),如果匹配了,ProxySQL退出此查询,同时去查询Apply字段。如果Apply值为0,就去读FlagOUT的值。此时会应用第一条规则(FlagIN=FlagOUT)。

第二条规则:获取请求,并用我定义的值替换world的值。简单来说,它将用replace_pattern里的值替换任何match_pattern里的值。

ProxySQL用正则实现了Re2 Google library。Re2速度非常快但有一些局限性,比如它不支持flag option g。换句话说,如果我select多张表,也就有多个”world”,Re2将只替换第一个实例。

因此,一个这样的查询:

Select /* continent=Europe */ * from world.Country join world.City on world.City.CountryCode=world.Country.Code where Country.code='ITA' ;

将被转换为:

Select /* continent=Europe */ * from Europe.Country join world.City on world.City.CountryCode=world.Country.Code where Country.code='ITA' ;

并且查询失败。

第二天,Rene和我讨论如何解决Re2这个问题。最后,我们选择了递归操作

这是什么意思呢?这以为着ProxySQL v1.2.2版本现在有一个新功能,即允许递归操作调用查询规则。ProxySQL可以运行的最大迭代数由全局变量mysql-query_processor_iterations管理。mysql-query_processor_iterations定义了一个查询进程可以执行多少个操作(从开始到结束)。

这个新的实现方法允许一个查询规则引用其本身,从而多次执行。

如果你回去看你会注意到QR 34使 FlagIN和FlagOUT指向相同的值25和Apply= 0。这让ProxySQL递归地调用规则34直到它改变world这个词的所有值。

结果如下:

[Mc]
Select /* continent=Europe */ Code, City.Name, City.population  from world.Country join world.City on world.City.CountryCode=world.Country.Code where City.population > 10000 group by Name order by City.Population desc limit 5;
+------+---------------+------------+
| Code | Name          | population |
+------+---------------+------------+
| RUS  | Moscow        |    8389200 |
| GBR  | London        |    7285000 |
| RUS  | St Petersburg |    4694000 |
| DEU  | Berlin        |    3386667 |
| ESP  | Madrid        |    2879052 |
+------+---------------+------------+

可以用下面的查询看到ProxySQL的内部信息:
[Pa]
select active,hits, mysql_query_rules.rule_id, match_digest, match_pattern, replace_pattern, cache_ttl, apply,flagIn,flagOUT FROM mysql_query_rules NATURAL JOIN stats.stats_mysql_query_rules ORDER BY mysql_query_rules.rule_id;
+--------+------+---------+---------------------+----------------------------------------+-----------------+-----------+-------+--------+---------+
| active | hits | rule_id | match_digest        | match_pattern                          | replace_pattern | cache_ttl | apply | flagIN | flagOUT |
+--------+------+---------+---------------------+----------------------------------------+-----------------+-----------+-------+--------+---------+
| 1      | 1    | 33      | NULL                | \S*\s*\/\*\s*continent=.*Europe\s*\*.* | NULL            | NULL      | 0     | 0      | 25      |
| 1      | 4    | 34      | NULL                | world.                                 | Europe.         | NULL      | 0     | 25     | 25      |
| 1      | 0    | 35      | NULL                | \S*\s*\/\*\s*continent=.*Africa\s*\*.* | NULL            | NULL      | 0     | 0      | 24      |
| 1      | 0    | 36      | NULL                | world.                                 | Africa.         | NULL      | 0     | 24     | 24      |
+--------+------+---------+---------------------+----------------------------------------+-----------------+-----------+-------+--------+---------+

And:

[Pa]
select * from stats_mysql_query_digest;
<snip and taking only digest_text>
Select Code, City.Name, City.population from Europe.Country join Europe.City on Europe.City.CountryCode=Europe.Country.Code where City.population > ? group by Name order by City.Population desc limit ?

可以看到ProxySQL已经在查询中很好地用Europe取代了world,它运行QR34四次。

这对insert/update/delete操作显然也是有用的。

这样的查询:

insert into  /* continent=Europe */  world.City values(999999,'AAAAAAA','ITA','ROMA',0) ;

将被转换为:
[Pa]
select digest_text from stats_mysql_query_digest;
+-------------------------------------------+
| digest_text                               |
+-------------------------------------------+
| insert into Europe.City values(?,?,?,?,?) |
+-------------------------------------------+

并且只在需要的schema上执行。

 

Sharding by host(主机分片)

Using hint

如何分片且重定向查询到host(而不是schema)?这其实更容易!

最主要的一点是,无论什么查询匹配了规则都应该传到定义的HG。没有重写,这意味着更少的工作。

这是如何实现的呢?和之前一样,我有三个节点:192.168.1.[5-6-7]。对于这个例子,我将使用world DB(没有continent schema),分布在每一个节点,我将检索绑定到IP的节点确保我去了正确的位置。

我指示ProxySQL通过HINT发送查询到特定主机。我选择hint ”shard_host_HG”,我将把hint作为一个comment插入到查询中。

因此查询规则将会是:
[Pa]
delete from mysql_query_rules where rule_id in (40,41,42, 10,11,12);
INSERT INTO mysql_query_rules (rule_id,active,username,match_pattern,destination_hostgroup,apply) VALUES (10,1,'user_shardRW',"\/\*\s*shard_host_HG=.*Europe\s*\*.",10,0);
INSERT INTO mysql_query_rules (rule_id,active,username,match_pattern,destination_hostgroup,apply) VALUES (11,1,'user_shardRW',"\/\*\s*shard_host_HG=.*Asia\s*\*.",20,0);
INSERT INTO mysql_query_rules (rule_id,active,username,match_pattern,destination_hostgroup,apply) VALUES (12,1,'user_shardRW',"\/\*\s*shard_host_HG=.*Africa\s*\*.",30,0);
LOAD MYSQL QUERY RULES TO RUNTIME;SAVE MYSQL QUERY RULES TO DISK;

我将测试的查询是:
[Mc]
Select /* shard_host_HG=Europe */ City.Name, City.Population from world.Country join world.City on world.City.CountryCode=world.Country.Code where Country.code='ITA' limit 5; SELECT * /* shard_host_HG=Europe */ from information_schema.GLOBAL_VARIABLES where variable_name like 'bind%';
Select /* shard_host_HG=Asia */ City.Name, City.Population from world.Country join world.City on world.City.CountryCode=world.Country.Code where Country.code='IND' limit 5; SELECT * /* shard_host_HG=Asia */ from information_schema.GLOBAL_VARIABLES where variable_name like 'bind%';
Select /* shard_host_HG=Africa */ City.Name, City.Population from world.Country join world.City on world.City.CountryCode=world.Country.Code where Country.code='ETH' limit 5; SELECT * /* shard_host_HG=Africa */ from information_schema.GLOBAL_VARIABLES where variable_name like 'bind%';

执行Africa的查询,将得到:
[Mc]
Select /* shard_host_HG=Africa */ City.Name, City.Population from world.Country join world.City on world.City.CountryCode=world.Country.Code where Country.code='ETH' limit 5; SELECT * /* shard_host_HG=Africa */ from information_schema.GLOBAL_VARIABLES where variable_name like 'bind%';
+-------------+------------+
| Name        | Population |
+-------------+------------+
| Addis Abeba |    2495000 |
| Dire Dawa   |     164851 |
| Nazret      |     127842 |
| Gonder      |     112249 |
| Dese        |      97314 |
+-------------+------------+

+—————+—————-+
| VARIABLE_NAME | VARIABLE_VALUE |
+—————+—————-+
| BIND_ADDRESS  | 192.168.1.7    |
+—————+—————-+

将给我的结果:
[Pa]
select active,hits, mysql_query_rules.rule_id, match_digest, match_pattern, replace_pattern, cache_ttl, apply,flagIn,flagOUT FROM mysql_query_rules NATURAL JOIN stats.stats_mysql_query_rules ORDER BY mysql_query_rules.rule_id;
+--------+------+---------+---------------------+----------------------------------------+-----------------+-----------+-------+--------+---------+
| active | hits | rule_id | match_digest        | match_pattern                          | replace_pattern | cache_ttl | apply | flagIN | flagOUT |
+--------+------+---------+---------------------+----------------------------------------+-----------------+-----------+-------+--------+---------+
| 1      | 0    | 40      | NULL                | \/\*\s*shard_host_HG=.*Europe\s*\*.    | NULL            | NULL      | 0     | 0      | 0       |
| 1      | 0    | 41      | NULL                | \/\*\s*shard_host_HG=.*Asia\s*\*.      | NULL            | NULL      | 0     | 0      | 0       |
| 1      | 2    | 42      | NULL                | \/\*\s*shard_host_HG=.*Africa\s*\*.    | NULL            | NULL      | 0     | 0      | 0       | <-- Note the HITS (2 as the run queries)
+--------+------+---------+---------------------+----------------------------------------+-----------------+-----------+-------+--------+---------+

在这个例子中,我们没有replace_patter。只有一个匹配和重定向规则,目标HG在插入时由destination_hostgroup属性值定义。Africa 的HG 是30。

HG 30中的主机:
[Pa]
select hostgroup_id,hostname,port,status from mysql_servers ;
+--------------+-------------+------+--------+
| hostgroup_id | hostname    | port | status |
+--------------+-------------+------+--------+
| 10           | 192.168.1.5 | 3306 | ONLINE |
| 20           | 192.168.1.6 | 3306 | ONLINE |
| 30           | 192.168.1.7 | 3306 | ONLINE | <---
+--------------+-------------+------+--------+

这完美的匹配了我们的返回值。

你可以自己试试另外2个continent。

 

Using destination_hostgroup(使用目标主机组)

另外一个标记最终主机的方法是用目标主机组(destination_hostgroup),在查询中设置Schema_name属性并使用use schema语法。

例如:
[Pa]
INSERT INTO mysql_query_rules (active,schemaname,destination_hostgroup,apply) VALUES
(1, 'shard00', 1, 1), (1, 'shard01', 1, 1), (1, 'shard03', 1, 1),
(1, 'shard04', 2, 1), (1, 'shard06', 2, 1), (1, 'shard06', 2, 1),
(1, 'shard07', 3, 1), (1, 'shard08', 3, 1), (1, 'shard09', 3, 1);

然后在查询中执行:

use shard02; Select * from tablex;

这可能会产生一个错误,因为shard03可能不在包含shard01的主机上。

因此只有当你100%确定你在做什么的时候才能使用这种方法,当你确定没有查询有显式申明的schema。

 

Shard by host and by schema(通过主机和schema分片)

最后,显然是可以结合这上面两种方法的,即通过主机和schema的一个子集分片。

为此,让我们用所有的三个节点且他们的schema分布如下:

  • Europe on Server 192.168.1.5 -> HG 10
  • Asia on Server 192.168.1.6 -> HG 20
  • Africa on Server 192.168.1.7 -> HG 30

我已经用HINT设置过查询规则,我所要做的就是使用它们来连接操作:
[Mc]
Select /* shard_host_HG=Asia */ /* continent=Asia */  City.Name, City.Population from world.Country join world.City on world.City.CountryCode=world.Country.Code where Country.code='IND' limit 5; SELECT * /* shard_host_HG=Asia */ from information_schema.GLOBAL_VARIABLES where variable_name like 'bind%';
+--------------------+------------+
| Name               | Population |
+--------------------+------------+
| Mumbai (Bombay)    |   10500000 |
| Delhi              |    7206704 |
| Calcutta [Kolkata] |    4399819 |
| Chennai (Madras)   |    3841396 |
| Hyderabad          |    2964638 |
+--------------------+------------+
5 rows in set (0.00 sec)
+---------------+----------------+
| VARIABLE_NAME | VARIABLE_VALUE |
+---------------+----------------+
| BIND_ADDRESS  | 192.168.1.6    |
+---------------+----------------+
1 row in set (0.01 sec)

[Pa]
mysql> select digest_text from stats_mysql_query_digest;
+--------------------------------------------------------------------------------------------------------------------------------------------+
| digest_text                                                                                                                                |
+--------------------------------------------------------------------------------------------------------------------------------------------+
| SELECT * from information_schema.GLOBAL_VARIABLES where variable_name like ?                                                               |
| Select City.Name, City.Population from Asia.Country join Asia.City on Asia.City.CountryCode=Asia.Country.Code where Country.code=? limit ? |
+--------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql> select active,hits, mysql_query_rules.rule_id, match_digest, match_pattern, replace_pattern, cache_ttl, apply,flagIn,flagOUT FROM mysql_query_rules NATURAL JOIN stats.stats_mysql_query_rules ORDER BY mysql_query_rules.rule_id;
+--------+------+---------+---------------------+----------------------------------------+-----------------+-----------+-------+--------+---------+
| active | hits | rule_id | match_digest        | match_pattern                          | replace_pattern | cache_ttl | apply | flagIN | flagOUT |
+--------+------+---------+---------------------+----------------------------------------+-----------------+-----------+-------+--------+---------+
| 1      | 0    | 10      | NULL                | \/\*\s*shard_host_HG=.*Europe\s*\*.    | NULL            | NULL      | 0     | 0      | NULL    |
| 1      | 2    | 11      | NULL                | \/\*\s*shard_host_HG=.*Asia\s*\*.      | NULL            | NULL      | 0     | 0      | NULL    |
| 1      | 0    | 12      | NULL                | \/\*\s*shard_host_HG=.*Africa\s*\*.    | NULL            | NULL      | 0     | 0      | NULL    |
| 1      | 0    | 13      | NULL                | NULL                                   | NULL            | NULL      | 0     | 0      | 0       |
| 1      | 1    | 31      | NULL                | \S*\s*\/\*\s*continent=.*Asia\s*\*.*   | NULL            | NULL      | 0     | 0      | 23      |
| 1      | 4    | 32      | NULL                | world.                                 | Asia.           | NULL      | 0     | 23     | 23      |
| 1      | 0    | 33      | NULL                | \S*\s*\/\*\s*continent=.*Europe\s*\*.* | NULL            | NULL      | 0     | 0      | 25      |
| 1      | 0    | 34      | NULL                | world.                                 | Europe.         | NULL      | 0     | 25     | 25      |
| 1      | 0    | 35      | NULL                | \S*\s*\/\*\s*continent=.*Africa\s*\*.* | NULL            | NULL      | 0     | 0      | 24      |
| 1      | 0    | 36      | NULL                | world.                                 | Africa.         | NULL      | 0     | 24     | 24      |
+--------+------+---------+---------------------+----------------------------------------+-----------------+-----------+-------+--------+---------+

可以看到,Rule11 有2个命中,这意味着我的查询将去到相关的HG。但给定到Rule11的Apply= 0,ProxySQL会继续处理查询规则。

因此也会把查询传到Rule 31和32,每一个都有预期命中数(第一为1,第二个为4,因为循环数)。

这是我们在ProxySQL中执行两层分片的所有操作。

 

Conclusion(结论)

ProxySQL允许用户用一种非常简单的方法,通过分片访问数据。查询规则遵循正则表达式的模式,结合查询规则和主机组的方法的可能性,给了我们巨大且相对简单的应用灵活性。

 

References

https://github.com/sysown/proxysql/tree/v1.2.2/doc
https://github.com/google/re2/wiki/Syntax
http://www.proxysql.com/2015/09/proxysql-tutorial-setup-in-mysql.html
https://github.com/sysown/proxysql/blob/v1.2.2/doc/configuration_howto.md
https://github.com/sysown/proxysql/blob/v1.2.2/INSTALL.md
https://dev.mysql.com/doc/index-other.html

 

注:本文译自Percona官方的一篇博客,其中标出原文的地方译者自觉翻译不佳,欢迎访客留言指正。原文请看这里