- 存在问题
- IO 瓶颈
- 热点数据太多, 数据库缓存不足, 产生大量磁盘 IO, 效率较低, 请求数据太多, 带宽不够, 网络 IO 瓶颈
- CPU 瓶颈
- 排序, 分组, 连接查询, 聚合统计等 SQL 会消耗大量的 CPU 资源, 请求数太多, CPU 出现瓶颈
- 分库分表的中心思想都是将数据分散存储, 使得单一数据库/表的数据量变小来缓解单一数据库的性能问题, 从而达到提升数据库性能的目的
- 拆分策略
- 垂直拆分
- 垂直分库
- 以表为依据, 根据业务将不同的表拆分到不同的库中
- 特点
- 每个库的表结构都不一样
- 每个库的数据也不一样
- 所有库的并集是全量数据
- 垂直分表
- 以字段为依据, 根据字段属性将不同字段拆分到不同的表中
- 特点
- 每个表的结构都不一样
- 每个表的数据也不一样, 通过(主/外键)关联
- 所有表的并集是全量数据
- 水平拆分
- 水平分库
- 以字段为依据, 按照一定策略, 将一个库的数据拆分到多个库中
- 特点
- 每个库的表结构都一样
& * 每个库的数据都不一样
- 所有库的并集是全量数据
- 水平分表
- 以字段为依据, 按照一定的策略, 将一个表的数据拆分到多个表中
- 特点
- 每个表的结构都一样
- 每个表的数据都不一样
- 所有表的并集是全量数据
- 实现技术
- shardingJDBC
- 基于 AOP 原理, 在应用程序中对本地执行的 SQL 进行拦截, 解析, 改写, 路由处理
- 需要自行编码配置实现, 只支持 Java, 性能较高
- MyCat
- 数据库分库分表中间件, 不用调整代码即可实现分库分表, 支持多种语言, 性能不如前者
- 介绍
- MyCat 是开源的, 活跃的, 基于 Java 语言编写的 MySQL 数据库的中间件
- 可以像使用 MySQL 一样来使用 MyCat, 对开发人员来说是透明的
- 优势
- 目录结构
- 安装
名称 |
IP |
模块 |
描述 |
master |
192.168.100.100 |
JDK, MyCat |
中间件 |
slave1 |
192.168.100.101 |
MySQL |
分片 |
slave2 |
192.168.100.102 |
MySQL |
分片 |
slave3 |
192.168.100.103 |
MySQL |
分片 |
scp .\jdk-8u341-linux-x64.tar.gz root@master:/opt/software
scp .\Mycat-server-1.6.7.3-release-20210913163959-linux.tar.gz root@master:/opt/software
scp .\mysql-connector-java-8.0.30.jar root@master:/opt/software
# JDK
rpm -qa | grep java-1.8.0 | xargs rpm -e --nodeps # 卸载自带的JDK
cd /opt/
tar -xzvf software/jdk-8u341-linux-x64.tar.gz -C module/
cd module/
chown -hR root:root jdk1.8.0_341/
vim /etc/profile.d/module.sh
# jdk1.8.0_341
JAVA_HOME=/opt/module/jdk1.8.0_341
PATH=$PATH:$JAVA_HOME/bin
source /etc/profile.d/module.sh
java -version
# MyCat
cd /opt/
tar -xzvf software/Mycat-server-1.6.7.3-release-20210913163959-linux.tar.gz -C module/
cd module/mycat/lib
mv mysql-connector-java-5.1.35.jar mysql-connector-java-5.1.35.jar.bak
cp /opt/software/mysql-connector-java-8.0.30.jar .
chmod 777 mysql-connector-java-8.0.30.jar
cd ../..
chown -hR root:root mycat/
vim /etc/profile.d/module.sh # 可选配置
# Mycat-server-1.6.7.3-release-20210913163959-linux
MYCAT_HOME=/opt/module/mycat
PATH=$PATH:$MYCAT_HOME/bin
source /etc/profile.d/module.sh
mycat status
- 确保端口通行
- 分别创建数据库
- 分片配置
- 配置 schema.xml
- 配置 server.xml
- 启动
- 创建表
# slave1, slave2, slave3
create database `db01`;
show databases;
# master
cd $MYCAT_HOME/conf
vim schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="db01" checkSQLschema="true" sqlMaxLimit="100">
<table name="tb_order" dataNode="dn1,dn2,dn3" rule="auto-sharding-long"/>
</schema>
<dataNode name="dn1" dataHost="dhost1" database="db01"/>
<dataNode name="dn2" dataHost="dhost2" database="db01"/>
<dataNode name="dn3" dataHost="dhost3" database="db01"/>
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1"
url="jdbc:mysql://slave1:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
user="root" password="123456"/>
</dataHost>
<dataHost name="dhost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1"
url="jdbc:mysql://slave2:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
user="root" password="123456"/>
</dataHost>
<dataHost name="dhost3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1"
url="jdbc:mysql://slave3:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
user="root" password="123456"/>
</dataHost>
</mycat:schema>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">db01</property>
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">db01</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
mycat start
cat /opt/module/mycat/logs/wrapper.log
mysql -h master -u root -P 8066 -p123456
# 完成
show databases;
use `db01`;
show tables;
drop table if exists `tb_order`;
create table if not exists `tb_order`
(
id int primary key not null comment '编号',
title varchar(128) not null comment '标题'
) comment '订单表';
truncate table `tb_order`;
insert into `tb_order`(`id`, `title`)
values (1, 'Java从入门到精通'),
(2, 'C++从入门到精通'),
(3, 'Python从入门到精通');
insert into `tb_order`(`id`, `title`)
values (5000000, 'C#从入门到精通'),
(10000000, 'C从入门到精通'),
(15000000, 'Go从入门到精通');
select *
from `tb_order`;
-- ERROR
insert into `order`(`id`, `title`)
values (15000001, 'ERROR');
- schema.xml
- 涵盖 MyCat 的逻辑库, 逻辑表, 分片规则, 分片节点及数据源的配置
- 主要标签
- schema
- 定义逻辑库
- name
- checkSQLschema
- 在 SQL 语句操作时指定了数据库名称是否自动去除
- sqlMaxLimit
- table
- 定义逻辑表
- name
- dataNode
- 定义逻辑表所属的 dataNode, 与 dataNode 中 name 对应, 多个用逗号分隔
- rule
- primary key
- type
- 逻辑表的类型
- 目前只有全局表(global)和普通表, 默认普通表
- datanode
- 数据节点
- name
- dataHost
- 数据主机, 与 dataHost 中的 name 对应,
- database
- datahost
- 数据主机
- name
- maxCon/minCon
- balance
- writeType
- 写操作分发方式
- 0 按照 writeHost 顺序依次尝试
- 1 随机
- dbDriver
- rule.xml
- 定义所有拆分表的规则, 在使用过程中可以灵活地使用分片算法, 或对算法使用不同的参数
- 主要标签
- server.xml
# slave1, slave2, slave3
create database shopping;
# master
cd $MYCAT_HOME/conf
vim schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="shopping" checkSQLschema="true" sqlMaxLimit="100">
<table name="tb_goods_base" dataNode="dn1" primaryKey="id"/>
<table name="tb_goods_brand" dataNode="dn1" primaryKey="id"/>
<table name="tb_goods_cat" dataNode="dn1" primaryKey="id"/>
<table name="tb_goods_desc" dataNode="dn1" primaryKey="goods_id"/>
<table name="tb_goods_item" dataNode="dn1" primaryKey="id"/>
<table name="tb_order_item" dataNode="dn2" primaryKey="id"/>
<table name="tb_order_master" dataNode="dn2" primaryKey="order_id"/>
<table name="tb_order_pay_log" dataNode="dn2" primaryKey="out_trade_no"/>
<table name="tb_user" dataNode="dn3" primaryKey="id"/>
<table name="tb_user_address" dataNode="dn3" primaryKey="id"/>
<table name="tb_areas_provinces" dataNode="dn1,dn2,dn3" primaryKey="id" type="global"/>
<table name="tb_areas_city" dataNode="dn1,dn2,dn3" primaryKey="id" type="global"/>
<table name="tb_areas_region" dataNode="dn1,dn2,dn3" primaryKey="id" type="global"/>
</schema>
<dataNode name="dn1" dataHost="dhost1" database="shopping"/>
<dataNode name="dn2" dataHost="dhost2" database="shopping"/>
<dataNode name="dn3" dataHost="dhost3" database="shopping"/>
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1"
url="jdbc:mysql://slave1:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
user="root" password="123456"/>
</dataHost>
<dataHost name="dhost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1"
url="jdbc:mysql://slave2:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
user="root" password="123456"/>
</dataHost>
<dataHost name="dhost3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1"
url="jdbc:mysql://slave3:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
user="root" password="123456"/>
</dataHost>
</mycat:schema>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">shopping</property>
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">shopping</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
mycat restart
cat /opt/module/mycat/logs/wrapper.log
scp ./shopping-table.sql root@master:~/
scp ./shopping-insert.sql root@master:~/
ssh root@master "mysql -h master -P 8066 -u root -p123456 -e 'use shopping; source ~/shopping-table.sql; source ~/shopping-insert.sql;'"
-- MyCat
use shopping;
show tables;
select `user_id`, `contact`, `province`, `city`, `area`, `address`
from `tb_user_address` as `ua`,
`tb_areas_provinces` as `p`,
`tb_areas_city` as `c`,
`tb_areas_region` as `r`
where `ua`.`province_id` = `p`.`provinceid`
and `ua`.`city_id` = `c`.`cityid`
and `ua`.`town_id` = `r`.`areaid`;
select `order_id`, `payment`, `receiver`, `province`, `city`, `area`
from `tb_order_master` as `o`,
`tb_areas_provinces` as `p`,
`tb_areas_city` as `c`,
`tb_areas_region` as `r`
where `o`.`receiver_province` = `p`.`provinceid`
and `o`.`receiver_city` = `c`.`cityid`
and `o`.`receiver_region` = `r`.`areaid`
# slave1, slave2, slave3
create database `sub_table`;
# master
cd $MYCAT_HOME/conf
vim schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="sub_table" checkSQLschema="true" sqlMaxLimit="100">
<table name="tb_log" dataNode="dn1,dn2,dn3" primaryKey="id" rule="mod-long"/>
</schema>
<dataNode name="dn1" dataHost="dhost1" database="sub_table"/>
<dataNode name="dn2" dataHost="dhost2" database="sub_table"/>
<dataNode name="dn3" dataHost="dhost3" database="sub_table"/>
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1"
url="jdbc:mysql://slave1:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
user="root" password="123456"/>
</dataHost>
<dataHost name="dhost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1"
url="jdbc:mysql://slave2:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
user="root" password="123456"/>
</dataHost>
<dataHost name="dhost3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1"
url="jdbc:mysql://slave3:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
user="root" password="123456"/>
</dataHost>
</mycat:schema>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">sub_table</property>
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">sub_table</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
mycat restart
cat /opt/module/mycat/logs/wrapper.log
use `sub_table`;
show tables;
scp ./tb_log.sql root@master:~/
ssh root@master "mysql -h master -P 8066 -u root -p123456 -e 'use sub_table; source ~/tb_log.sql;'"
use
`sub_table`;
select *
from `tb_log`;
- 范围分片
- 根据指定的字段及其配置的范围与数据节点的对应情况, 来决定该数据属于哪一个分片
- 取模分片
- 根据指定的字段与节点数量进行求模运算, 根据运算结果, 来决定该数据属于哪一个分片
- 一致性 hash
- 所谓一致性哈希, 相同的哈希因子计算值总是被划分到相同的分区中, 不会应为分区节点的增加而改变原来数据的分区位置
- 枚举分片
- 通过在配置文件中配置可能的枚举值, 指定数据分布到不同的数据节点上, 本规则适用于按照省份, 性别, 拆分数据等业务
- 应用指定 substring
- 运行阶段由应用自主决定路由到哪个分片, 直接根据字字符串(必须是数字)计算分号
- 固定 hash
- 字符串 hash
- 截取字符串中指定位置的子字符串, 进行 hash, 算出分片
- 按天分片
- 按月分片
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="sub_table" checkSQLschema="true" sqlMaxLimit="100">
<table name="tb_log" dataNode="dn1,dn2,dn3" primaryKey="id" rule="mod-long"/>
<table name="tb_order" dataNode="dn1,dn2,dn3" primaryKey="id" rule="sharding-by-murmur"/>
<table name="tb_user" dataNode="dn1,dn2,dn3" primaryKey="id" rule="sharding-by-intfile-enumstatus"/>
<table name="tb_app" dataNode="dn1,dn2,dn3" primaryKey="id" rule="sharding-by-substring"/>
<table name="tb_longhash" dataNode="dn1,dn2,dn3" primaryKey="id" rule="sharding-by-long-hash"/>
<table name="tb_strhash" dataNode="dn1,dn2" primaryKey="name" rule="sharding-by-stringhash"/>
<table name="tb_datepart" dataNode="dn1,dn2,dn3" primaryKey="id" rule="sharding-by-date"/>
<table name="tb_monthpart" dataNode="dn1,dn2,dn3" primaryKey="id" rule="sharding-by-month"/>
</schema>
<dataNode name="dn1" dataHost="dhost1" database="sub_table"/>
<dataNode name="dn2" dataHost="dhost2" database="sub_table"/>
<dataNode name="dn3" dataHost="dhost3" database="sub_table"/>
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1"
url="jdbc:mysql://slave1:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
user="root" password="123456"/>
</dataHost>
<dataHost name="dhost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1"
url="jdbc:mysql://slave2:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
user="root" password="123456"/>
</dataHost>
<dataHost name="dhost3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1"
url="jdbc:mysql://slave3:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
user="root" password="123456"/>
</dataHost>
</mycat:schema>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="sharding-by-murmur">
<rule>
<columns>id</columns>
<algorithm>murmur</algorithm>
</rule>
</tableRule>
<function name="murmur" class="io.mycat.route.function.PartitionByMurmurHash">
<property name="seed">0</property>
<property name="count">3</property>
<property name="virtualBucketTimes">160</property>
</function>
<tableRule name="sharding-by-intfile-enumstatus">
<rule>
<columns>status</columns>
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
<function name="hash-int" class="io.mycat.route.function.PartitionByFileMap">
<property name="defaultNode">2</property>
<property name="mapFile">partition-hash-int.txt</property>
</function>
<tableRule name="sharding-by-substring">
<rule>
<columns>id</columns>
<algorithm>sharding-by-substring</algorithm>
</rule>
</tableRule>
<function name="sharding-by-substring" class="io.mycat.route.function.PartitionDirectBySubString">
<property name="startIndex">0</property>
<property name="size">2</property>
<property name="partitionCount">3</property>
<property name="defaultPartition">0</property>
</function>
<tableRule name="sharding-by-stringhash">
<rule>
<columns>user_id</columns>
<algorithm>sharding-by-stringhash</algorithm>
</rule>
</tableRule>
<function name="sharding-by-stringhash" class="io.mycat.route.function.PartitionByString">
<property name="partitionLength">512</property>
<property name="partitionCount">2</property>
<property name="hashSlice">0:2</property>
</function>
<tableRule name="sharding-by-long-hash">
<rule>
<columns>id</columns>
<algorithm>sharding-by-long-hash</algorithm>
</rule>
</tableRule>
<function name="sharding-by-long-hash" class="io.mycat.route.function.PartitionByLong">
<property name="partitionCount">2,1</property>
<property name="partitionLength">256,512</property>
</function>
<tableRule name="sharding-by-date">
<rule>
<columns>create_time</columns>
<algorithm>sharding-by-date</algorithm>
</rule>
</tableRule>
<function name="sharding-by-date" class="io.mycat.route.function.PartitionByDate">
<property name="dateFormat">yyyy-MM-dd</property>
<property name="sBeginDate">2022-01-01</property>
<property name="sEndDate">2022-01-30</property>
<property name="sPartionDay">10</property>
</function>
<tableRule name="sharding-by-month">
<rule>
<columns>create_time</columns>
<algorithm>partbymonth</algorithm>
</rule>
</tableRule>
<function name="partbymonth"
class="io.mycat.route.function.PartitionByMonth">
<property name="dateFormat">yyyy-MM-dd</property>
<property name="sBeginDate">2022-01-01</property>
<property name="sEndDate">2022-03-31</property>
</function>
</mycat:rule>
# partition-hash-int.txt
1=0
2=1
3=2
scp ./hash.sql root@master:~/
scp ./enum.sql root@master:~/
scp ./substring.sql root@master:~/
scp ./static-hash.sql root@master:~/
scp ./string-hash.sql root@master:~/
scp ./date.sql root@master:~/
scp ./month.sql root@master:~/
ssh root@master "mysql -h master -P 8066 -u root -p123456 -e 'use sub_table; source ~/hash.sql;'"
ssh root@master "mysql -h master -P 8066 -u root -p123456 -e 'use sub_table; source ~/enum.sql;'"
ssh root@master "mysql -h master -P 8066 -u root -p123456 -e 'use sub_table; source ~/substring.sql;'"
ssh root@master "mysql -h master -P 8066 -u root -p123456 -e 'use sub_table; source ~/static-hash.sql;'"
ssh root@master "mysql -h master -P 8066 -u root -p123456 -e 'use sub_table; source ~/string-hash.sql;'"
ssh root@master "mysql -h master -P 8066 -u root -p123456 -e 'use sub_table; source ~/date.sql;'"
ssh root@master "mysql -h master -P 8066 -u root -p123456 -e 'use sub_table; source ~/month.sql;'"
use `sub_table`;
select *
from `tb_order`;
select *
from `tb_user`;
select *
from `tb_app`;
select *
from `tb_longhash`;
select *
from `tb_strhash`;
select *
from `tb_datepart`;
select *
from `tb_monthpart`;
- MyCat 默认开通 2 个端口, 可在 server.xml 中配置
- 8066
- 9066
- 数据库管理端口, MyCat 服务管理功能, 用于管理 MyCat 的整个集群状态
- 常用命令
- show @@help
- show @@version
- reload @@config
- show @@datasource
- show @@datanode
- show @@threadpool
- show @@sql
- show @@sql.sum
- MyCat-eye
- MyCat-eye(MyCat-web)是对 MyCat-server 提供监控服务, 功能不局限于对 mycat-server 使用
- 通过 JDBC 连接对 MyCat, MySQL 监控, 监控远程服务器(目前仅限 Linux)的 CPU, 内存, 网络, 磁盘
- 依赖与 Zookeeper
scp .\apache-zookeeper-3.6.3-bin.tar.gz root@master:/opt/software
scp .\Mycat-web.tar.gz root@master:/opt/software
# zookeeper
tar -xzvf software/apache-zookeeper-3.6.3-bin.tar.gz -C module/
cd module/apache-zookeeper-3.6.3-bin/
mkdir data
cd conf/
cp zoo_sample.cfg zoo.cfg
vim zoo.cfg
dataDir=/opt/module/apache-zookeeper-3.6.3-bin/data
cd ..
bin/zkServer.sh start
bin/zkServer.sh status
# MyCat-eye
cd /opt
tar -xzvf software/Mycat-web.tar.gz -C module/
cd module/mycat-web/
./start.sh
MyCat-eye