- 本文地址: https://www.yangdx.com/2022/09/221.html
- 转载请注明出处
什么是 Apache ShardingSphere
Apache ShardingSphere 是一款分布式的数据库生态系统,可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。
根据编程语言场景不同,其又分为2个产品:
- ShardingSphere-JDBC:定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。
- ShardingSphere-Proxy:定位为透明化的数据库代理端,通过实现数据库二进制协议,对异构语言提供支持。
官网:https://shardingsphere.apache.org/index_zh.html
Java 以为的语言需要用 ShardingSphere-Proxy,本篇将阐述如何在 docker 环境下做 mysql 数据分片。
使用 docker 镜像演示
1)编写 docker-compose.yml
内容如下
version: "3.3"
networks:
ShardingSphere:
ipam:
config:
- subnet: 172.12.0.0/24
gateway: 172.12.0.1
services:
sharding_proxy:
container_name: sharding_proxy
environment:
TZ: Asia/Shanghai
image: apache/shardingsphere-proxy:latest
networks:
- ShardingSphere
ports:
- "3312:3307"
restart: always
volumes:
- ./conf:/opt/shardingsphere-proxy/conf
- ./logs:/opt/shardingsphere-proxy/logs
- ./ext-lib:/opt/shardingsphere-proxy/ext-lib
ShardingSphere-Proxy 默认端口是3307,我将其映射到宿主机的3312端口。
挂载了3个目录,其中 conf
目录是放配置文件的,logs
是日志文件存储目录,ext-lib
目录放扩展依赖包。
2)获取配置文件
刚开始我们是没有配置文件的,需要将默认配置文件从容器中拷贝出来:
docker run -d --name tmp --entrypoint=bash apache/shardingsphere-proxy
docker cp tmp:/opt/shardingsphere-proxy/conf /host/path/to/conf
docker rm tmp
执行完后,将 /host/path/to/conf 目录下的文件拷贝的挂载的 conf
目录下,可以看到有7个文件:
config-database-discovery.yaml
config-encrypt.yaml
config-readwrite-splitting.yaml
config-shadow.yaml
config-sharding.yaml
logback.xml
server.yaml
3)下载 mysql 连接依赖包
ShardingSphere-Proxy 连接 MySQL 数据库,需要用到 mysql-connector-java 驱动包,请下载 mysql-connector-java-5.1.49.jar 或者 mysql-connector-java-8.0.30.jar,并将其放入 ext-lib
目录。
4)修改配置文件 server.yaml
默认整个文件是全部注释的,需要将下图圈起来的部分取消注释(删除行首的 # 号),同时更改 sql-show 为 true(方便观察 SQL 日志):
此处配置的授权用户 root 可从任意主机连接,密码是 root;而用户 sharding 只能从本机连接,密码是 sharding。
5)修改配置文件 config-sharding.yaml
这个文件用于配置数据分片(分表分库),默认也是全部注释的。
找到 “If you want to connect to MySQL” 这一行,将后面的注释全部取消,同时按实际情况配置你已有的 MySQL 主机地址和账号密码:
此配置文件定义了库和表的分片规则,具体解释如下图:
6)在 MySQL 服务器上创建数据库和数据表
根据上一步的数据分片配置规则,得知,需要创建2个数据库:demo_ds_0、demo_ds_1,每个库还要创建4个表:t_order_0、t_order_1、t_order_item_0、t_order_item_1。
建表 sql 如下:
CREATE TABLE `t_order_0` (
`order_id` bigint(20) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
`remarks` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `t_order_1` (
`order_id` bigint(20) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
`remarks` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `t_order_item_0` (
`order_item_id` bigint(20) unsigned NOT NULL,
`order_id` bigint(20) unsigned NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`price` decimal(10,2) NOT NULL,
PRIMARY KEY (`order_item_id`),
KEY `order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `t_order_item_1` (
`order_item_id` bigint(20) unsigned NOT NULL,
`order_id` bigint(20) unsigned NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`price` decimal(10,2) NOT NULL,
PRIMARY KEY (`order_item_id`),
KEY `order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
7)启动服务
打开终端,切换到 docker-compose.yml 目录,执行 docker-compose up
(为了方便观察日志所以没有加 -d
):
由输出结果可知,启动成功了,后端连接的数据库是 MySQL 5.7.36。若没有启动成功,请检查配置的 MySQL 主机地址是否可 ping 通,账号密码是否正确。
8)使用 MySQL 客户端连接 ShardingSphere-Proxy
跟连接普通的 MySQL 服务器一样,前面我们映射的端口号是3312,配置的用户名和密码都是 root,所以执行:
mysql -h192.168.1.6 -P3312 -uroot -proot
登录成功,可以看到虚拟的库名 sharding_db 和两个虚拟表 t_order、t_order_item:
root@5e29717d68e6:/# mysql -h192.168.1.6 -P3312 -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 5.7.22-ShardingSphere-Proxy 5.1.2 MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| schema_name |
+--------------------+
| sharding_db |
| mysql |
| information_schema |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.01 sec)
mysql> use sharding_db;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-----------------------+------------+
| Tables_in_sharding_db | Table_type |
+-----------------------+------------+
| t_order_item | BASE TABLE |
| t_order | BASE TABLE |
+-----------------------+------------+
2 rows in set (0.00 sec)
mysql>
9)插入数据
执行以下 SQL 插入订单数据(只演示 t_order 表):
INSERT INTO `t_order`(`user_id`, `remarks`) VALUES (1, '1-1');
INSERT INTO `t_order`(`user_id`, `remarks`) VALUES (1, '1-2');
INSERT INTO `t_order`(`user_id`, `remarks`) VALUES (2, '2-1');
INSERT INTO `t_order`(`user_id`, `remarks`) VALUES (2, '2-2');
INSERT INTO `t_order`(`user_id`, `remarks`) VALUES (3, '3-1');
INSERT INTO `t_order`(`user_id`, `remarks`) VALUES (3, '3-2');
INSERT INTO `t_order`(`user_id`, `remarks`) VALUES (4, '4-1');
INSERT INTO `t_order`(`user_id`, `remarks`) VALUES (4, '4-2');
观察 docker 容器 sharding_proxy 的输出日志,如下:
Logic SQL
就是我们输入的 SQL 语句,而 Actual SQL
是被 ShardingSphere 转换后的真实 SQL,还自动追加了雪花算法生成的 order_id 主键,数据分片算法根据 order_id 和 user_id 的不同取值将数据插入到对应的库节点和分表里。
10)查询数据
分别执行下面3个 SQL 语句:
SELECT * FROM t_order WHERE order_id=774342042821066753;
SELECT * FROM t_order WHERE order_id=774342042821066753 AND user_id=4;
SELECT * FROM t_order;
观察 docker 容器 sharding_proxy 的输出日志,如下:
通过输出日志可知:
- 第1个 SQL 只提供 orde_id 时,ShardingSphere 可以确定分表的名称,但不能确定库节点,所以底层要查询2个节点才能得到结果;
- 第2个 SQL 同时提供了 order_id 和 user_id,可以确定分表名称和库节点,所以底层只需要执行了一条 SQL 便可得到结果;
- 第3个 SQL 未提供 order_id 和 user_id,底层则需要查询所有库节点和的所有分表。
总结
使用 ShardingSphere-Proxy 做数据分片的演示就到此结束,如果原来的业务代码是未分库分表,引入 ShardingSphere 做分表分库几乎无须改动代码。
快来评论一下吧!
发表评论