Range 方式
如上图中, shard Key范围在0-1000的数据存放在DbGroup0中, 范围在1000-2000的数据存放在DbGroup1中, 2000-MaxInt 的数据存放在DbGroup2 中. 这些范围的大小不需要相同.比如id为shard key的话, sql: "select * from test where id = 1500;", Atlas会将此语句发往DbGroup1. 暂时Atlas的range是静态的, 不支持动态的增加范围.
优点:
对于range的sql查询如(where id > 100 or id < 1000), range方式的sharding可以精确的命中后端的数据组, 不需要将sql发到各个mysql去请求数据, 节约了网络传输的消耗.
缺点
如果shard key是递增的, 那么可能会在一段时间内的所有sql都命中到同一个数据组, 没有体现出sharding的优势, range不适用于这种场景.
适用场景
range适用于对范围查询有大量需求, 并且shard key相对离散插入的情景
hash 方式
目前Atlas使用取模的方式实现Hash, 也就是说Hash(id) = id % dbgroup_count, 如id = 10, id % 3 = 1, 所以会命中到DbGroup1中.
优缺点
hash跟range方式是恰好相反的, hash 可以应对数据递增的情景, 即使是在递增的情况下, sharding的数据也是均匀分布在各个数据组内的, 但是其缺点就是对于范围的查询通常都需要查询所有的dbgroup, 网络的消耗比较大.
适用场景
hash 适用于shard key顺序增长, 并对范围查询的需求比较小的情景
关于支持的语句
Atlas sharding只对sql语句提供有限的支持, 目前支持基本的Select, insert/replace, delete, update语句, 支持全部的Where语法, 但是对于以下语句, 如果语句命中了多台dbgroup, Atlas均未做支持(如果语句只命中了一个dbgroup, 如select count(*) from test where id < 1000, 其中dbgroup0范围是0 - 1000, 那么这些特性都是支持的)
- Limit Offset(支持Limit)
- Order by
- Group by
- Join
- ON
- Count, Max, Min等函数
这些语句Atlas会返回"ERROR 1105 (HY000): Proxy Warning - Sharing Hit Multi Dbgroup Not Support SQL"错误. 请不要在Sharding的表上使用这些特性, 如果对这种特性有需求请不要让此表sharding.
注意:
- 子查询在Sharding中可能会返回不正确的结果, 也请不要使用子查询. 请把语句拆分成多句执行
- 对于写操作, 如果写操作命中了多个数据库组, 由于部分成功(某个组执行失败)需要回滚的问题, 暂时不支持写操作命中多个数据组的语句.请拆分成多个sql语句执行.
- Atlas可能会在接下来的版本中对其中的一些特性中做出支持.
关于事务支持
事务在Atlas的非sharding的表是完全支持的, 但是对于sharding的表, Atlas只能提供部分的支持(不支持跨dbgroup的事务). Atlas只支持事务中涉及单个dbgroup的语句, 例如有两个dbgroup0, dbgroup1, 其切分方式是range, 规则是dbgroup0: 0 - 999, dbgroup1: 1000 - 2000,
- mysql> begin;
- Query OK, 0 rows affected (0.00 sec)
- mysql> insert into sharding_test(id, name, age) values(1, 'test', 0);
- Query OK, 1 row affected (0.00 sec)
- mysql> insert into sharding_test(id, name, age) values(1500, 'test', 0);
- ERROR 1179 (sqlst): Proxy Warning - sharding dbgroup is in trans, transaction will not work across multi dbgroup
- mysql> /*master*/select * from sharding_test where id < 1000;
- +----+------+------+----------+----------+
- | id | name | age | birthday | nickname |
- +----+------+------+----------+----------+
- | 1 | test | 0 | NULL | NULL |
- +----+------+------+----------+----------+
- 1 row in set (0.00 sec)
- mysql> /*master*/select * from sharding_test;
- ERROR 1179 (sqlst): Proxy Warning - sharding dbgroup is in trans, transaction will not work across multi dbgroup
- mysql> commit;
- Query OK, 0 rows affected (0.00 sec)
- mysql> /*master*/select * from sharding_test;
- +----+------+------+----------+----------+
- | id | name | age | birthday | nickname |
- +----+------+------+----------+----------+
- | 1 | test | 0 | NULL | NULL |
- +----+------+------+----------+----------+
- 1 row in set (0.00 sec)
请注意第二条语句, 由于之前将insert与dbgroup0绑定了, 所以从此之后Atlas在此事务中只接受涉及dbgroup0的语句, 其他语句将会执行失败. "/*master*/select * from sharding_test;" 执行失败是因为, 这个语句会命中所有的dbgroup, 也是同理, 不支持这种语句. 在commit之后, sharding dbgroup不再处于事务状态, 就可以执行跨shard的操作了
换句话说, 如果是hash方式sharding的表, 基本上事务是无法支持的, 因为hash的表, 大部分操作都是会涉及多个dbgroup的.
增加节点
注意: 暂时只支持range方式的节点扩展, hash方式由于需要数据迁移, 暂时未做支持.
扩展节点在保证原来节点的范围不改变的情况下, 如已有dbgroup0为范围0 - 999, dbgroup1为范围 1000 - 1999, 这个时候可以增加范围>2000的节点. 如增加一个节点为2000 - 2999, 修改配置文件, 重启Atlas即可.