MySQL Cluster如何确定要搜索SELECT查询的数据节点?

时间:2013-06-22 19:35:13

标签: mysql sharding

我正在研究如何解决客户需要将特定客户的所有数据(以及该客户的数据)存储在地理位置不同的数据库服务器上的情况。

例如,所有数据都应存储在主云上的数据库服务器中,但与客户ID 92相关的所有数据除外,这些数据应存储在另一个位置的不同云上的服务器中。

我正在使用的一些限制使得这有点棘手,但到目前为止,MySQL Cluster似乎是最好的方法。

但是,我不清楚它在执行查询时如何选择数据节点。例如,如果我要提交一个不需要客户ID 92的任何数据的查询,它是否仍会ping另一个云中的数据节点并引入延迟?

MySQL Cluster如何确定在SELECT查询期间要搜索哪些数据节点?有没有办法可以在查询中暗示可以忽略某些数据节点?

3 个答案:

答案 0 :(得分:5)

哎呀......这不是MySQL Cluster的工作方式。

默认情况下,MySQL Cluster在PRIMARY KEY上分区数据。但是,可以在PRIMARY KEY的一部分上使用用户定义的分区和分区。这对于将相关数据组合在一起并确保一个分区内的数据的位置非常有用。由于相关数据随后保存在一个分区中,因此可以在不牺牲性能的情况下从2个数据节点扩展到48个数据节点 - 它将保持不变。 请参阅http://dev.mysql.com/doc/refman/5.5/en/partitioning-key.html

了解更多详情

默认情况下,API将在PRIMARY KEY(或主键的已使用定义部分)上计算散列(使用LH3 *算法,使用md5)来确定要发送查询的分区。计算的散列是128位,64位确定分区,64位确定分区上的散列索引中的位置。作为用户,您无法准确了解具有数据的节点(或将存储数据的人),但实际上并不重要。

关于跨两个云分配一个MySQL群集和分区数据的原始问题。数据节点需要可靠的低延迟相互访问,因此您不希望将节点分散开,除非它们彼此相距50-100英里。

答案 1 :(得分:2)

嗨,我担心答案是“不”。 MySQL集群有时被称为分片,但实际上并不是......它是PK的每个表的任意数据分配,没有控制,也没有考虑哪些数据一起访问,以及每个访问和每个查询或事务需要哪些节点。

分片和良好的数据分发策略是在同一个数据库中保存一起访问的数据的策略,因此当事务需要数据时,它最终会使用这个1 DB,处理(加入,分组)将被推送到这个数据库(更接近数据,好!)和其他数据库将留下来处理其他交易(并有很多.......)。

因此,我们通过在一个数据库中存储一起访问的数据得到两件事:

  1. 需要此数据和查找的查询/事务的延迟更少 它在1节点上
  2. 查询/事务是分布式的,而不是在所有数据库上相乘
  3. 因此,如果我理解你的问题,这就是你想要实现的目标,MySQL Cluster无法提供,如果现在可以,那么当数据/并发/写入增长时,它会回来并咬你。

    你可能需要一个很好的旧分片,或者今天有一些实际上自动分片过程的工具(免责声明:我为ScaleBase工作,一个选项,仅使用数据库,是的,也支持提示(通常不需要) )。

答案 2 :(得分:2)

首先请注意,Mysql Cluster不是为WAN设计的,通常最好在节点之间传播延迟小于20ms。

Mysql Cluster进行分片(在数据节点之间均匀分布数据)+复制(每个数据片段存储两次)。

如此简单的表格,

| test  | CREATE TABLE `test` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `v1` char(255) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=ndbcluster AUTO_INCREMENT=1871780 DEFAULT CHARSET=latin1

如果您查看information_schema,您将看到此表的分区

mysql> select partition_name,table_rows from information_schema.PARTITIONS where     table_name='test' and table_schema='test1';
+----------------+------------+
| partition_name | table_rows |
+----------------+------------+
| p0             |     518667 |
| p1             |     518900 |
| p2             |     517385 |
| p3             |     519050 |
+----------------+------------+
4 rows in set (0.02 sec)

分区p0,p2代表数据节点1,p1代表节点2的p3。数据基于PRIMARY KEY(或者是人工密钥,如果现在是主键定义的)分配。

选择基于此分区选择要读取的节点,因此如果使用说明

mysql> explain partitions select id,v1 from test where id=1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test
   partitions: p3
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 8
          ref: const
         rows: 1
        Extra: NULL
1 row in set (0.00 sec)

mysql> explain partitions select id,v1 from test where id=2\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test
   partitions: p2
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 8
          ref: const
         rows: 1
        Extra: NULL

id = 92的记录将仅从一个数据节点(可能是地理分布的数据节点)中读取,但不幸的是,它不只是用于id 92。

最好是为客户ID 92(在单独的节点上)创建一个单独的表,并重写您的应用程序以从该表/节点读取。要使解决方案对应用程序透明,您可以使用Mysql Proxy