在文档中主要介绍了 kingshard 的 Hash 和 Range 方式的分表,最近又开发了按时间维度的分表方式。按时间维度分表的场景非常普遍,下面介绍一下 kingshard 的时间分表功能
kingshard 中的分表字段支持 MySQL 中三种类型的时间格式
kingshard 支持 MySQL 中三种格式的时间类型
kingshard 的配置文件如下所示:
# server listen addr
addr : 0.0.0.0:9696
# server user and password
user : kingshard
password : kingshard
# if set log_path, the sql log will write into log_path/sql.log,the system log
# will write into log_path/sys.log
#log_path : /Users/flike/log
# log level[debug|info|warn|error],default error
log_level : debug
# if set log_sql(on|off) off,the sql log will not output
log_sql: on
# only log the query that take more than slow_log_time ms
#slow_log_time : 100
# the path of blacklist sql file
# all these sqls in the file will been forbidden by kingshard
#blacklist_sql_file: /Users/flike/blacklist
# only allow this ip list ip to connect kingshard
#allow_ips: 127.0.0.1
# the charset of kingshard, if you don't set this item
# the default charset of kingshard is utf8.
#proxy_charset: gbk
# node is an agenda for real remote mysql server.
nodes :
-
name : node1
# default max conns for mysql server
max_conns_limit : 32
# all mysql in a node must have the same user and password
user : kingshard
password : kingshard
# master represents a real mysql master server
master : 127.0.0.1:3306
# slave represents a real mysql salve server,and the number after '@' is
# read load weight of this slave.
#slave : 192.168.59.101:3307@2,192.168.59.101:3307@3
down_after_noalive : 32
-
name : node2
# default max conns for mysql server
max_conns_limit : 32
# all mysql in a node must have the same user and password
user : kingshard
password : kingshard
# master represents a real mysql master server
master : 192.168.59.103:3307
# slave represents a real mysql salve server
slave :
# down mysql after N seconds noalive
# 0 will no down
down_after_noalive: 32
# schema defines sharding rules, the db is the sharding table database.
schema :
db : kingshard
nodes: [node1,node2]
default: node1
shard:
-
table: test_shard_year
key: ctime
type: date_day
nodes: [node1,node2]
date_range: [2015-2016,2017-2018]
按年分表的配置项设置如下:
table: test_shard_year
key: ctime
type: date_year
nodes: [node1,node2]
date_range: [2015-2016,2017-2018]
该配置表示:
date_year
。test_shard_year_2015, test_shard_year_2016
两个子表落在 node1 上,test_shard_year_2017 , test_shard_year_2018
两个子表落在 node2 上。date_range[2015,2017-2018]
。注意:子表的命名格式必须是:shard_table_YYYY,shard_table 是分表名,后面接具体的年。
在 node1 上创建两张子表test_shard_year_2015, test_shard_year_2016
,在 node2 上创建两种子表test_shard_year_2017 , test_shard_year_2018
。建表 SQL 如下
CREATE TABLE `test_shard_year_2016` (
`id` int(10) NOT NULL,
`name` varchar(40) DEFAULT NULL,
`ctime` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入数据:
mysql> insert into test_shard_year(id,name,ctime) values(12,"hello","2015-02-22 13:23:45");
Query OK, 1 row affected (0.01 sec)
mysql> insert into test_shard_year(id,name,ctime) values(13,"world","2016-03-22");
Query OK, 1 row affected (0.00 sec)
mysql> select * from test_shard_year where ctime < "2016-03-23";
+----+-------+---------------------+
| id | name | ctime |
+----+-------+---------------------+
| 12 | hello | 2015-02-22 13:23:45 |
| 13 | world | 2016-03-22 00:00:00 |
+----+-------+---------------------+
2 rows in set (0.00 sec)
对应的 SQL log 信息是:
2016/03/05 12:06:32 - OK - 1.2ms - 127.0.0.1:56597->127.0.0.1:3306:insert into test_shard_year_2015(id, name, ctime) values (12, 'hello', '2015-02-22 13:23:45')
2016/03/05 12:06:59 - OK - 2.0ms - 127.0.0.1:56597->127.0.0.1:3306:insert into test_shard_year_2016(id, name, ctime) values (13, 'world', '2016-03-22')
2016/03/05 12:08:30 - OK - 1.6ms - 127.0.0.1:56597->127.0.0.1:3306:select * from test_shard_year_2015 where ctime < '2016-03-23'
2016/03/05 12:08:30 - OK - 0.3ms - 127.0.0.1:56597->127.0.0.1:3306:select * from test_shard_year_2016 where ctime < '2016-03-23'
当然如果你把 id 作为一个 unix 时间戳,来分表的话, kingshard 也是支持的。具体配置就是这样的:
table: test_shard_year
key: id
type: date_year
nodes: [node1,node2]
date_range: [2015-2016,2017-2018]
插入数据:
mysql> insert into test_shard_year(id,name,ctime) values(1457410310,"world","2018-03-22");
Query OK, 1 row affected (0.01 sec)
mysql> select * from test_shard_year where id = 1457410310;
+------------+-------+---------------------+
| id | name | ctime |
+------------+-------+---------------------+
| 1457410310 | world | 2018-03-22 00:00:00 |
+------------+-------+---------------------+
1 row in set (0.00 sec)
1457410310 这个 unix 时间戳对应的日期是: 2016-3-8 12:11:50 。 kingshard 准确地将这条记录路由到了test_shard_year_2016
这张子表中了。
对应的 SQL log 是:
2016/03/08 12:12:49 - OK - 1.0ms - 127.0.0.1:56669->127.0.0.1:3306:insert into test_shard_year_2016(id, name, ctime) values (1457410310, 'world', '2018-03-22')
2016/03/08 12:13:23 - OK - 0.4ms - 127.0.0.1:56669->127.0.0.1:3306:select * from test_shard_year_2016 where id = 1457410310
按月分表的配置项设置如下:
table: test_shard_month
key: ctime
type: date_month
nodes: [node1,node2]
date_range: [201512-201602,201609-2016010]
该配置表示:
date_month
。test_shard_month_201512, test_shard_month_201601, test_shard_month_201602
两个子表落在 node1 上,test_shard_month_201609 , test_shard_month_201610
两个子表落在 node2 上。date_range[201501,201609-201610]
。注意:子表的命名格式必须是:shard_table_YYYYMM,shard_table
是分表名,后面接具体的年和月。
功能演示参考按年分表的操作。
按月分表的配置项设置如下:
table: test_shard_day
key: ctime
type: date_day
nodes: [node1,node2]
date_range: [20151222-20151224,20160901-20160902]
该配置表示:
date_day
。test_shard_day_20151222, test_shard_day_20151223, test_shard_day_20151224
两个子表落在 node1 上,test_shard_day_20160901 , test_shard_day_20160902
两个子表落在 node2 上。date_range[20150101,20160901-20161010]
。注意:子表的命名格式必须是:shard_table_YYYYMMDD,shard_table
是分表名,后面接具体的年,月和日。
功能演示参考按年分表的操作。
1
binnchx 2016-03-10 12:13:59 +08:00
支持
|
3
flikecn OP 目前 kingshard 已经在 10+公司的线上环境使用了,按时间分表是一个非常重要的 feature 。:)
|