初试kingshard


## 简介

按照官网的介绍，kingshard其实就是一个用go写的mysql proxy。特点从给介绍看包括以下几个方面：

**基础功能**

* 支持SQL读写分离。
* 支持透明的MySQL连接池，不必每次新建连接。
* 支持平滑上线DB或下线DB，前端应用无感知。
* 支持多个slave，slave之间通过权值进行负载均衡。
* 支持强制读主库。
* 支持主流语言（java,php,python,C/C++,Go)SDK的mysql的prepare特性。
* 支持到后端DB的最大连接数限制。
* 支持SQL日志及慢日志输出。
* 支持SQL黑名单机制。
* 支持客户端IP访问白名单机制，只有白名单中的IP才能访问kingshard。
* 支持字符集设置。
* 支持last_insert_id功能。
* 支持热加载配置文件，动态修改kingshard配置项（具体参考管理端命令）。
* 支持以Web API调用的方式管理kingshard。
* 支持多用户模式，不同用户之间的表是权限隔离的，互补感知。

**sharding功能**

* 支持按整数的hash和range分表方式。
* 支持按年、月、日维度的时间分表方式。
* 支持跨节点分表，子表可以分布在不同的节点。
* 支持跨节点的count,sum,max和min等聚合函数。
* 支持单个分表的join操作，即支持分表和另一张不分表的join操作。
* 支持跨节点的order by,group by,limit等操作。
* 支持将sql发送到特定的节点执行。
* 支持在单个节点上执行事务，不支持跨多节点的分布式事务。
* 支持非事务方式更新（insert,delete,update,replace）多个node上的子表。

## Docker方式编译安装

克隆源代码

```shell

git clone https://github.com/flike/kingshard.git

```


Dockerfile

```dockerfile

FROM golang:1.7-alpine

ENV KINGSHARD_VERSION=1.5 \
	GO_VERSION=1.6 \
	PATH=$PATH:/usr/local/go/bin:/usr/local/kingshard/bin \
	GOPATH=/
	
EXPOSE 9696 9797
COPY kingshard /src/github.com/flike/kingshard
RUN apk add --no-cache bash git  make && \
	/bin/bash -c "source /src/github.com/flike/kingshard/dev.sh" && \
	make -C /src/github.com/flike/kingshard  && \
	mv /src/github.com/flike/kingshard/bin/kingshard /kingshard && \
	rm -rf /src && \
	apk del bash git make

COPY ks.yaml /etc/ks.yaml

ENTRYPOINT ["/kingshard"]

```

ks.yaml文件

```
# server listen addr
addr : 0.0.0.0:9696

# server user and password
user_list:
-
    user :  root
    password : root
-
    user :  kingshard
    password : kingshard

# the web api server
web_addr : 0.0.0.0:9797
#HTTP Basic Auth
web_user : admin
web_password : admin

# 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,192.168.0.14

# 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 :  root 
    password : root

    # master represents a real mysql master server 
    master : 127.0.0.1:3307

    # 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 :  root 
    password : root

    # master represents a real mysql master server 
    master : 127.0.0.1:3309

    # 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_list :
-
    user: root
    nodes: [node1,node2]
    default: node1
    shard:
    -

-
    user: kingshard
    nodes: [node1,node2]
    default: node1      
    shard:
    -   
        db : kingshard
        table: test_shard_hash
        key: id
        nodes: [node1, node2]
        type: hash
        locations: [4,4]

    - 
        db : hidb
        table: test_hash
        key: id
        nodes: [node1, node2]
        type: hash
        locations: [4,4]
    -   
        db : kingshard
        table: test_shard_range
        key: id
        type: range
        nodes: [node1, node2]
        locations: [4,4]
        table_row_limit: 10000
    -
        db : kingshard
        table: test_shard_time
        key: id
        nodes: [node1, node2]
        type: hash
        locations: [2,2]
    -
        db : kingshard
        table: test_shard_month
        key: dtime
        type: date_month
        nodes: [node1,node2]
        date_range: [201603-201605,201609-201612]
    -
        db : kingshard
        table: test_shard_day
        key: mtime
        type: date_day
        nodes: [node1,node2]
        date_range: [20160306-20160307,20160308-20160309]
```

根据需要修改配置文件，为了测试方便可以使用docker-compose对配置文件做挂载。


打包kingshard镜像

```shell
docker build -t kingshard .
```


用docker-compose来启动

docker-composel.yml

```
version: '3'
services:
    kingshard:
        image: kingshard:latest
        volumes:
            - "./ks-example.yml:/etc/ks.yaml" # ks-example.yml是测试yml文件，可以根据需要修改内容
        ports:
            - 9696:9696
            - 9797:9797
```


## 使用体验

* 主从分离

在配置文件中的 **nodes** 一段，可以配置mysql的master和slave。而且slave一段可以配置多个从库，同时指定权重。指定方式就是在从库配置后边加上@符号

示例

```
    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 :  root 
    password : root

    # master represents a real mysql master server 
    master : 127.0.0.1:3307

    # 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

```
通过测试，只要在node里配置了主从，kingshard可以自动根据mysql的语句来判断分配主从。也就是说如果通过kingshard，执行select语句，kingshard会把请求发送到从库上。

* 支持多用户

kingshard可以管理账号，通过在kingshard中增加用户可以避免去每个mysql服务器上配置账号。

在 **user_list** 数组中增加配置即可添加账号。
客户端使用这个账号连接kingshard就可以访问数据库。

* 分库分表hash模式

根据官方提供的例子，测试了一下分库分表。使用下来还是不错。

https://github.com/flike/kingshard/blob/master/doc/KingDoc/how_to_use_kingshard.md


* 便捷的指定node和强制读主库

## 使用问题

* 只支持单节点事务，这个还需要代码做配合。
* 非事务情况下，可以跨节点更新数据