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 ```