Fork me on GitHub

版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | https://vearne.cc

起因:之前的相当长时间一直在寻找mysql的分布式解决方案,一直没有特别理想的答案,有同事给推荐了kingshard,所以决定一探究竟。

1.安装

机器共3台

机器 IP 说明
机器1 192.168.122.1 安装kingshard
机器1 192.168.122.3 安装mysql实例(node1) master 没有slave
机器1 192.168.122.4 安装mysql实例(node2) master 没有slave

安装请参考官方资料
https://github.com/flike/kingshard/blob/master/doc/KingDoc/kingshard_install_document.md

我安装的kingshard 2016年8月9日的版本,目前kingshard还没有参数或配置,把kingshard以后台守护进程的方式启动,因此作者建议使用supervisor进行管理。

因为我主要是为了观察效果,所以直接在终端中启动

./kingshard -config=../etc/ks.yaml

以下是我的配置文件 ks.yaml

# 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 : 192.168.122.3: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.122.4:3306

    # 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_day
        key: mtime     # 指定分表所用的时间字段
        type: date_day
        nodes: [node1,node2]
        date_range: [20160306-20160307,20160308-20160309]

由于我主要是用到kingshard的按时间分表功能,所以这里只配置了

2. 感受

2.1 kingshard 和后端node不断尝试连接,在一定的连接后就会认为后端node挂了,日志中会打印相应信息

2016/08/14 22:57:02 - ERROR - node.go:[113] - [Node] "checkMaster" "Ping" "db.Addr=192.168.122.4:3306|error=connection was bad" conn_id=0
2016/08/14 22:57:18 - ERROR - node.go:[113] - [Node] "checkMaster" "Ping" "db.Addr=192.168.122.4:3306|error=dial tcp 192.168.122.4:3306: getsockopt: connection refused" conn_id=0
2016/08/14 22:57:34 - ERROR - node.go:[113] - [Node] "checkMaster" "Ping" "db.Addr=192.168.122.4:3306|error=dial tcp 192.168.122.4:3306: getsockopt: connection refused" conn_id=0
2016/08/14 22:57:34 - INFO - node.go:[129] - [Node] "checkMaster" "Master down" "db.Addr=192.168.122.4:3306|Master_down_time=32" conn_id=0

同时可以使用终端管理命令查看所有节点的状态

admin server(opt,k,v) values('show','proxy','config');

在线上,完全可以基于这个命令来实现简单的监控报警

2.2 将SQL路由到指定node上

kingshard中支持将sql路由到指定的node上

/*node1*/ show tables;  # 将sql发送到node1
/*node2*/ show tables;  # 将sql发送到node2

这个功能真的很棒,但是在使用mysql-client的时候必须带上-c 参数

mysql -h127.0.0.1 -ukingshard -pkingshard -P9696 -c;

--comments, -c

Whether to preserve comments in statements sent to the server. The default is --skip-comments (discard comments), enable with --comments (preserve comments).

如果不带-c,默认注释会被丢弃

2.3 kingshard不会自动创建任何表,所有用到的表必须自己创建

建表语句形如:

CREATE TABLE `test_shard_day_20160307` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `money` int DEFAULT 0,
  `mtime` timestamp NOT NULL,
   PRIMARY KEY (`id`)
) ENGINE=InnoDB;

2.4 真实的读写例子

2.4.1 读操作
mysql> /*node1*/show tables;
+-------------------------+
| Tables_in_kingshard     |
+-------------------------+
| test_shard_day_20140102 |
| test_shard_day_20140103 |
| test_shard_day_20140104 |
| test_shard_day_20160306 |
| test_shard_day_20160307 |
| test_shard_day_20160308 |
| test_shard_day_20160309 |
+-------------------------+
7 rows in set (0.01 sec)

mysql> /*node2*/show tables;
+-------------------------+
| Tables_in_kingshard     |
+-------------------------+
| test_shard_day_20160308 |
| test_shard_day_20160309 |
+-------------------------+
2 rows in set (0.01 sec)

我在kingshard中的设定是这样的
date_range: [20160306-20160307,20160308-20160309]
不包含20140102、20140103、20140104
执行sql 查看test_shard_day 表中的所有数据

mysql> select * from test_shard_day;
+----+---------------------+-------+
| id | mtime               | money |
+----+---------------------+-------+
|  1 | 2016-03-06 00:00:00 |     0 |
|  2 | 2016-03-07 00:00:00 |    20 |
|  3 | 2016-03-08 00:00:00 |    10 |
|  4 | 2016-03-08 00:10:00 |    15 |
+----+---------------------+-------+
4 rows in set (0.03 sec)

在kingshard的日志中

2016/08/15 08:18:16 - OK - 9.7ms - 127.0.0.1:35925->192.168.122.3:3306:select * from test_shard_day_20160306
2016/08/15 08:18:16 - OK - 4.3ms - 127.0.0.1:35925->192.168.122.3:3306:select * from test_shard_day_20160307
2016/08/15 08:18:16 - OK - 16.0ms - 127.0.0.1:35925->192.168.122.4:3306:select * from test_shard_day_20160308
2016/08/15 08:18:16 - OK - 2.0ms - 127.0.0.1:35925->192.168.122.4:3306:select * from test_shard_day_20160309

一次性的触发了4条SQL
也就是对kingshard中没有设定过的表(test_shard_day_20140102、test_shard_day_20140103、test_shard_day_20140104),kingshard不会自动发现和访问、这其实是减少了不必要的开销,也大大简化了处理逻辑

在线上,如果可以实现动态的配置shard表,某种意义就达到动态的关闭和打开表的作用,比如只让用户访问最近三个月的数据

2.4.2 写操作

这里只讲特殊情况,如果插入数据的时间区间,不在 date_range: [20160306-20160307,20160308-20160309] 范围内,写请求也是可以进行的

insert into test_shard_day(id, mtime, money) values (15, '2016-03-06 01:00:00', 1);

kingshard日志

2016/08/15 08:37:37 - OK - 4.3ms - 127.0.0.1:35925->192.168.122.3:3306:insert  into test_shard_day_20160306(id, mtime, money) values (15, '2016-03-06 01:00:00', 1)

写操作被默认发给了node1
test_shard_day_20160306 是我提前建好的

3. 总结

kingshard能够被非常简单的部署和使用
1. 无需修改 mysql-client
2. 安装方便,快捷
可以考虑在线上使用