github.com/XiaoMi/Gaea@v1.2.5/docs/shard.md (about)

     1  # 分片表配置
     2  
     3  Gaea支持kingshard分表规则和mycat分库规则, 用户可以在不迁移任何数据的情况下, 从kingshard和mycat切换到Gaea.
     4  
     5  ### kingshard分表配置
     6  
     7  Gaea支持kingshard常用分表规则, 对应关系如下:
     8  
     9  | kingshard规则名称 | Gaea规则名称 |
    10  | ---------------- | ---------- |
    11  | hash             | hash       |
    12  | mod              | mod        |
    13  | range            | range      |
    14  | date_year        | date_year  |
    15  | date_month       | date_month |
    16  | date_day         | date_day   |
    17  
    18  ##### hash 
    19  分片方式说明:基于分表键的hash值计算子表下标。   
    20  我们想将`db_example`库的`tbl_example`表配置为分片表, 共4个分片, 分布到2个slice上, 每个slice上有1个库, 每个库2张表, 即:
    21  
    22  | slice | 后端数据库名 | 后端表名 |
    23  | ----- | ---------- | ------- |
    24  | slice-0 | db_example | tbl_example_0000 |
    25  | slice-0 | db_example | tbl_example_0001 |
    26  | slice-1 | db_example | tbl_example_0002 |
    27  | slice-1 | db_example | tbl_example_0003 |
    28  
    29  则namespace配置文件中的分片表规则可参考以下示例配置:
    30  
    31  ```
    32  // namespace配置文件
    33  // {
    34  // ...
    35  // "shard_rules": [
    36  
    37  {
    38      "db": "db_example",
    39      "table": "tbl_example",
    40      "type": "hash",
    41      "key": "id",
    42      "locations": [
    43          2,
    44          2
    45      ],
    46      "slices": [
    47          "slice-0",
    48          "slice-1"
    49      ]
    50  }
    51  
    52  // ]
    53  ```
    54  配置说明:
    55  -   该配置中的locations字段包含两个元素, locations[0]=2 代表slices字段数组slices[0]包含两个分片,即slice-0的master实例包含两个子表。locations[1]=2 代表slices字段数组slices[1]包含两个分片,即slice-1的master实例包含两个子表。
    56  -   key字段代表用于分表的键。
    57  
    58  ##### mod
    59  分片方式说明:基于分表键对子表数量的取模运算值计算子表下标。    
    60  我们想将`db_example`库的`shard_mod`表配置为分片表, 共4个分片, 分布到2个slice上, 每个slice上有1个库, 每个库2张表, 即:
    61  
    62  | slice | 后端数据库名 | 后端表名 |
    63  | ----- | ---------- | ------- |
    64  | slice-0 | db_example | shard_mod_0000 |
    65  | slice-0 | db_example | shard_mod_0001 |
    66  | slice-1 | db_example | shard_mod_0002 |
    67  | slice-1 | db_example | shard_mod_0003 |
    68  
    69  则namespace配置文件中的分片表规则可参考以下示例配置:
    70  
    71  ```
    72  // namespace配置文件
    73  // {
    74  // ...
    75  // "shard_rules": [
    76  
    77  {
    78      "db": "db_example",
    79      "table": "shard_mod",
    80      "type": "mod",
    81      "key": "id",
    82      "locations": [
    83          2,
    84          2
    85      ],
    86      "slices": [
    87          "slice-0",
    88          "slice-1"
    89      ]
    90  }
    91  
    92  // ]
    93  ```
    94  配置说明:
    95  -   该配置中的locations字段包含两个元素, locations[0]=2 代表slices字段数组slices[0]包含两个分片,即slice-0的master实例包含两个子表。locations[1]=2 代表slices字段数组slices[1]包含两个分片,即slice-1的master实例包含两个子表。
    96  -   key字段代表用于分表的键。
    97  
    98  ##### range
    99  分片方式说明:基于分表键的所在范围计算子表下标。  
   100  该方式的优点:基于范围的查询或更新速度快,因为查询(或更新)的范围有可能落在同一张子表中。这样可以避免全部子表的查询(更新)。缺点:数据热点问题。因为在一段时间内整个集群的写压力都会落在一张子表上。此时整个mysql集群的写能力受限于单台mysql server的性能。并且,当正在集中写的mysql 节点如果宕机的话,整个mysql集群处于不可写状态。     
   101  我们想将`db_example`库的`tbl_example`表配置为分片表, 共4个分片, 分布到2个slice上, 每个slice上有1个库, 每个库2张表, 即:
   102  
   103  | slice | 后端数据库名 | 后端表名 |
   104  | ----- | ---------- | ------- |
   105  | slice-0 | db_example | tbl_example_0000 |
   106  | slice-0 | db_example | tbl_example_0001 |
   107  | slice-1 | db_example | tbl_example_0002 |
   108  | slice-1 | db_example | tbl_example_0003 |
   109  
   110  则namespace配置文件中的分片表规则可参考以下示例配置:
   111  
   112  ```
   113  // namespace配置文件
   114  // {
   115  // ...
   116  // "shard_rules": [
   117  
   118  {
   119      "db": "db_example",
   120      "table": "tbl_example",
   121      "type": "range",
   122      "key": "id",
   123      "locations": [
   124          2,
   125          2
   126      ],
   127      "slices": [
   128          "slice-0",
   129          "slice-1"
   130      ],
   131      "table_row_limit": 100
   132  }
   133  
   134  // ]
   135  ```
   136  
   137  配置说明:
   138  -   该配置中的locations包含两个元素, locations[0]=2 代表slices字段数组slices[0]包含两个分片,即slice-0的master实例包含两个子表。locations[1]=2 代表slices字段数组slices[1]包含两个分片表,即slice-1的master实例包含两个子表。
   139  -   key字段代表用于分表的键。
   140  -   table_row_limit字段的值为100,代表每张子表的记录数。id字段的值为[0,100)在tbl_example_0000上,[100,200)在tbl_example_0001上,依此类推...
   141  
   142  ##### date_year
   143  分片方式说明:基于分表键日期(年)计算子表下标。  
   144  我们想将`db_example`库的`shard_year`表配置为分片表, 共4个分片, 分布到2个slice上, 每个slice上有1个库, 每个库2张表, 即:
   145  
   146  | slice | 后端数据库名 | 后端表名 |
   147  | ----- | ---------- | ------- |
   148  | slice-0 | db_example | shard_year_2016 |
   149  | slice-0 | db_example | shard_year_2017 |
   150  | slice-1 | db_example | shard_year_2018 |
   151  | slice-1 | db_example | shard_year_2019 |
   152  
   153  则namespace配置文件中的分片表规则可参考以下示例配置:
   154  
   155  ```
   156  // namespace配置文件
   157  // {
   158  // ...
   159  // "shard_rules": [
   160  
   161  {
   162      "db": "db_example",
   163      "table": "shard_year",
   164      "type": "date_year",
   165      "key": "create_time",
   166      "slices": [
   167          "slice-0",
   168          "slice-1"
   169      ]
   170     "date_range": [
   171          "2016-2017",
   172          "2018-2019"
   173      ]
   174  }
   175  
   176  // ]
   177  ```
   178  
   179  配置说明:
   180  -   key:该配置表示shardding key是create_time 
   181  -   data_range:表示shard_year_2016、shard_year_2017两个表在slice-0上,shard_year_2018、shard_year_2019在slice-1上, 左闭右闭。  
   182  
   183  gaea 支持Mysql中三种格式的时间类型
   184  -   date类型,格式:YYYY-MM-DD,例如:2016-03-04,注意:2016-3-04,2016-03-4,2016-3-4等格式都是不支持的。
   185  -   datetime,格式:YYYY-MM-DD HH:MM:SS,例如:2016-03-04 13:23:43,注意:2016-3-04 13:23:43,2016-03-4 13:23:43,2016-3-4 13:23:43等格式都是不支持的。
   186  -   timestamp,整数类型。   
   187  
   188  注意:子表的命名格式必须是:shard_table_YYYY,shard_table是分表名,后面接具体的年。传入范围必须是有序递增,不能是[2018-2019,2016-2017],且不能重叠,不能是[2017-2018,2018-2019]。
   189  
   190  ##### date_month 
   191  分片方式说明:基于分表键日期(月)计算子表下标。   
   192  我们想将`db_example`库的`shard_month`表配置为分片表, 共4个分片, 分布到2个slice上, 每个slice上有1个库, 每个库2张表, 即:
   193  
   194  | slice | 后端数据库名 | 后端表名 |
   195  | ----- | ---------- | ------- |
   196  | slice-0 | db_example | shard_month_201405 |
   197  | slice-0 | db_example | shard_month_201406 |
   198  | slice-1 | db_example | shard_month_201408 |
   199  | slice-1 | db_example | shard_month_201409 |
   200  
   201  则namespace配置文件中的分片表规则可参考以下示例配置:
   202  
   203  ```
   204  // namespace配置文件
   205  // {
   206  // ...
   207  // "shard_rules": [
   208  
   209  {
   210      "db": "db_example",
   211      "table": "shard_month",
   212      "type": "date_month",
   213      "key": "create_time",
   214      "slices": [
   215          "slice-0",
   216          "slice-1"
   217      ]
   218      "date_range": [
   219           "201405-201406",
   220           "201408-201409"
   221      ]
   222  }
   223  
   224  // ]
   225  ```
   226  
   227  配置说明:
   228  -   key: sharding key 是create_time
   229  -   type: 按月的分表类型是date_month
   230  -   data_range: shard_month_201405、shard_month_201406两个子表在slice-0上,shard_month_201408、shard_month_201409在slice-1上,如果一个slice上只包含一张表,可以这样配置date_range[201609,201610-201611]
   231  
   232  注意:子表的命名格式必须是:shard_table_YYYYMM,shard_table是分表名,后面接具体的年和月。传入范围必须是有序递增的,不能是[201609-201610,201501]。
   233  
   234  ##### date_day
   235  分片方式说明:基于分表键日期(天)计算子表下标。     
   236  我们想将`db_example`库的`shard_day`表配置为分片表, 共4个分片, 分布到2个slice上, 每个slice上有1个库, 每个库2张表, 即:
   237  
   238  | slice | 后端数据库名 | 后端表名 |
   239  | ----- | ---------- | ------- |
   240  | slice-0 | db_example | shard_day_20201201 |
   241  | slice-0 | db_example | shard_day_20201202 |
   242  | slice-1 | db_example | shard_day_20201203 |
   243  | slice-1 | db_example | shard_day_20201204 |
   244  
   245  则namespace配置文件中的分片表规则可参考以下示例配置:
   246  
   247  ```
   248  // namespace配置文件
   249  // {
   250  // ...
   251  // "shard_rules": [
   252  
   253  {
   254      "db": "db_example",
   255      "table": "shard_day",
   256      "type": "date_day",
   257      "key": "create_time",
   258      "slices": [
   259          "slice-0",
   260          "slice-1"
   261      ]
   262      "date_range": [
   263           "20201201-20201202",
   264           "20201203-20201204"
   265      ]
   266  }
   267  
   268  // ]
   269  ```
   270  
   271  配置说明:
   272  -   key: 分表键是create_time
   273  -   type: 按天的分表类型是date_day
   274  -   data_range: 表示shard_day_20201201、shard_day_20201202两个子表在slice-0上,shard_day_20201203、shard_day_20201204在slice-1上, 如果一个slice上只包含一张表,可以这样配置date_range[20160901,20161001-20161101]
   275  
   276  注意:子表的命名格式必须是:shard_table_YYYYMMDD,shard_table是分表名,后面接具体的年、月和日。传入范围必须是有序递增的,不能是[20160901-20160902,20150901]。
   277  
   278  ### mycat分库配置
   279  
   280  Gaea支持mycat的常用分库规则, 对应关系如下:
   281  
   282  | mycat规则名称          | Gaea规则名称       |
   283  | --------------------- | ----------------- |
   284  | PartitionByMod        | mycat_mod         |
   285  | PartitionByLong       | mycat_long        |
   286  | PartitionByMurmurHash | mycat_murmur      |
   287  | PartitionByString     | mycat_string      |
   288  
   289  ##### PartitionByMod
   290  分片方式说明:基于分片键对子库数量的取模运算值计算子库下标。   
   291  我们想将`db_mycat`库的`tbl_mycat`表配置为分片表, 共4个分片, 分布到2个slice上面, 每个slice上有2个库, 每个库1张表, 即:
   292  
   293  | slice | 后端数据库名 | 后端表名 |
   294  | ----- | ---------- | ------- |
   295  | slice-0 | db_mycat_0 | tbl_mycat |
   296  | slice-0 | db_mycat_1 | tbl_mycat |
   297  | slice-1 | db_mycat_2 | tbl_mycat |
   298  | slice-1 | db_mycat_3 | tbl_mycat |
   299  
   300  则namespace配置文件中的分片表规则可参考以下示例配置:
   301  
   302  ```
   303  // namespace配置文件
   304  // {
   305  // ...
   306  // "shard_rules": [
   307  
   308  {
   309      "db": "db_mycat",
   310      "table": "tbl_mycat",
   311      "type": "mycat_mod",
   312      "key": "id",
   313      "locations": [
   314          2,
   315          2
   316      ],
   317      "slices": [
   318          "slice-0",
   319          "slice-1"
   320      ],
   321      "databases": [
   322          "db_mycat_[0-3]"
   323      ]
   324  }
   325  
   326  // ]
   327  ```
   328  
   329  注: databases配置项, 指定了每个分片表的实际库名, 这里采用了简写的方式, 与以下配置等价:
   330  
   331  ```
   332  "databases": [
   333      "db_mycat_0",
   334      "db_mycat_1",
   335      "db_mycat_2",
   336      "db_mycat_3"
   337  ]
   338  ```
   339  
   340  如果指定的实际库名不是递增的, 也可以手动指定, 如:
   341  
   342  ```
   343  "databases": [
   344      "db_mycat_0",
   345      "db_mycat_1",
   346      "db_mycat_3",
   347      "db_mycat_4"
   348  ]
   349  ```
   350  
   351  ##### PartitionByLong
   352  分片方式说明:基于分片键固定分片hash算法计算子库下标。  
   353  mycat_long的配置规则如下:
   354  
   355  ```
   356  {
   357      "db": "db_mycat",
   358      "table": "tbl_mycat_long",
   359      "type": "mycat_long",
   360      "key": "id",
   361      "locations": [
   362          2,
   363          2
   364      ],
   365      "slices": [
   366          "slice-0",
   367          "slice-1"
   368      ],
   369      "databases": [
   370          "db_mycat_[0-3]"
   371      ],
   372      "partition_count": "4",
   373      "partition_length": "256"
   374  }
   375  ```
   376  
   377  其中`partition_count`, `partition_length`配置项的含义与mycat `PartitionByLong`规则中的同名配置项的含义相同.
   378  -   该配置中的locations字段包含两个元素, locations[0]=2 代表slices字段数组slices[0]包含两个分片,即slice-0的master实例包含两个子库。locations[1]=2 代表slices字段数组slices[1]包含两个分片,即slice-1的master实例包含两个子库。
   379  -   partition_count标识分片个数,需要与设置的分片数量相等,由于定义了4个分片,因此这里只能是4
   380  -   partition_length代表分片范围列表
   381      1. 配置"partition_count":"4"、"partition_length":"256"代表希望将数据水平分成4份,每份各占25%
   382      2. 配置"partition_count":"2,2"、"partition_length":"128,384"代表希望将数据水平分成4份,前两份占128/1024、后两份占384/1024 
   383      3. 配置"partition_count":"2,1"、"partition_length":"256,512"代表希望将数据水平分成3份,前两份各占25%,第三份占50%  
   384  -   分区长度:默认为最大2^n=1024 ,即最大支持1024分区。
   385  -   约束:1024 = sum((count[i]*length[i])). count和length两个向量的点积恒等于1024。如上述示例中,4 * 256=1024、128 * 2 + 384 * 2=1024、256 * 2 + 512=1024。
   386  
   387  ##### PartitionByMurmurHash
   388  分片方式说明:基于分片键一致性hash算法计算子库下标。  
   389  mycat_murmur的配置规则如下:
   390  
   391  ```
   392  {
   393      "db": "db_mycat",
   394      "table": "tbl_mycat_murmur",
   395      "type": "mycat_murmur",
   396      "key": "id",
   397      "locations": [
   398          2,
   399          2
   400      ],
   401      "slices": [
   402          "slice-0",
   403          "slice-1"
   404      ],
   405      "databases": [
   406          "db_mycat_0","db_mycat_1","db_mycat_2","db_mycat_3"
   407      ],
   408      "seed": "0",
   409      "virtual_bucket_times": "160"
   410  }
   411  ```
   412  -   该配置中的locations字段包含两个元素, locations[0]=2 代表slices字段数组slices[0]包含两个分片,即slice-0的master实例包含两个子库。locations[1]=2 代表slices字段数组slices[1]包含两个分片,即slice-1的master实例包含两个子库。
   413  -   其中`seed`, `virtual_bucket_times`配置项的含义与mycat `PartitionByMurmurHash`规则中的同名配置项的含义相同,代表一个实际的数据库节点被映射出该值对应的虚拟节点,这里设置160即虚拟节点数是物理节点数的160倍. 
   414  -   目前Gaea中不支持配置weight, 所有bucket weight都是1.
   415  
   416  ##### PartitionByString
   417  分片方式说明:基于分片键字串hash值计算子库下标。 
   418  mycat_string的配置规则如下:
   419  
   420  ```
   421  {
   422      "db": "db_mycat",
   423      "table": "tbl_mycat_string",
   424      "type": "mycat_string",
   425      "key": "id",
   426      "locations": [
   427          2,
   428          2
   429      ],
   430      "slices": [
   431          "slice-0",
   432          "slice-1"
   433      ],
   434      "databases": [
   435          "db_mycat_[0-3]"
   436      ],
   437      "partition_count": "4",
   438      "partition_length": "256",
   439      "hash_slice": "-2:0"
   440  }
   441  ```
   442  
   443  其中`partition_count`, `partition_length`, `hash_slice`配置项的含义与mycat `PartitionByString`规则中的同名配置项的含义相同.
   444  -   该配置中的locations字段包含两个元素, locations[0]=2 代表slices字段数组slices[0]包含两个分片,即slice-0的master实例包含两个子库。locations[1]=2 代表slices字段数组slices[1]包含两个分片,即slice-1的master实例包含两个子库。
   445  -   partition_count代表分片数
   446  -   partition_length代表字符串hash求模基数
   447  -   hash_slice是hash运算位即根据子字符串hash运算.  
   448  其中,hash_slice支持一下格式:  
   449      -   "2"代表(0,2)
   450      -   "1:2"代表(1,2)
   451      -   "1:"代表(1,0)
   452      -   "-1:"代表(-1,0)
   453      -   ":-1"代表(0,-1)  
   454  例1:值“45abc”,hash运算位0:2 ,取其中45进行计算   
   455  例2:值“aaaabbb2345”,hash预算位-4:0 ,取其中2345进行计算  
   456  
   457  ### 关联表和全局表
   458  
   459  Gaea分片SQL要求多个表具有关联关系 (一个分片表, 多个关联表), 或者只存在一个分片表, 其余均为全局表.
   460  
   461  ##### 关联表
   462  
   463  关联表需要与同数据库的某个分片表关联. 例如, 将`db_mycat`库的`tbl_mycat_child`配置为关联表, 分片列名为`id`, 父表为`tbl_mycat`, 则需要在`shard_rules`中添加以下配置:
   464  
   465  ```
   466  {
   467      "db": "db_mycat",
   468      "table": "tbl_mycat_child",
   469      "type": "linked",
   470      "parent_table": "tbl_mycat",
   471      "key": "id"
   472  }
   473  ```
   474  
   475  此时即可执行分片内的关联查询:
   476  
   477  ```
   478  SELECT * FROM tbl_mycat, tbl_mycat_child WHERE tbl_mycat_child.id=5 AND tbl_mycat.user_name='hello';
   479  ```
   480  
   481  ##### 全局表
   482  
   483  全局表是在各个slice上 (准确的说是各个slice的各个DB上) 数据完全一致的表, 方便执行一些跨分片查询, 配置如下:
   484  
   485  ```
   486  {
   487      "db": "db_mycat",
   488      "table": "tbl_mycat_global",
   489      "type": "global",
   490      "locations": [
   491          2,
   492          2
   493      ],
   494      "slices": [
   495          "slice-0",
   496          "slice-1"
   497      ],
   498      "databases": [
   499          "db_mycat_[0-3]"
   500      ]
   501  }
   502  ```