您的位置:首页 > 手游攻略 > MariaDB Spider 数据库分库分表实践记录实用指南

MariaDB Spider 数据库分库分表实践记录实用指南

作者:互联网  时间: 2026-08-31 19:30:02  

平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“MariaDB Spider 数据库分库分表实践记录”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。

分库分表

一般来说,数据库分库分表,有以下做法:

  • 按哈希分片:根据一条数据的标识计算哈希值,将其分配到特定的数据库引擎中;
  • 按范围分片:根据一条数据的标识(一般是值),将其分配到特定的数据库引擎中;
  • 按列表分片:根据某些字段的标识,如果符合条件则分配到特定的数据库引擎中。

理解这一步时,分库分表的做法有很多种,比如编写代码库,在程序中兼容多数据库,程序需知道每个数据库的地址,并要编写代码进行兼容;采用中间件将多个数据库引擎连接起来,程序只需知道中间件地址。

结合项目来看,但是分库分表后,因为任意两个表可能在不同的数据库实例中,两个表进行连接查询时,两个数据库实例之间的交互变得复杂起来,当集群中的数据量较大时,便不能随意 join 了,可能需其他方式支撑聚合查询。

分库分表有优点有缺点,这里就不再多说,先学会再打算。

实际处理时,MariaDB Server 是开源的,目前最流行的关系型数据库之一,MariaDB 是从 Mysql 的分支开发而来,一直保持对 Mysql 的兼容性。因为甲骨文的收购,MySQL 属于 Oracle 所有,存在闭源的可能,以及逐渐商业化,变得不清真,于是 Mysql之父新建了 MariaDB,目的是完全兼容 Mysql,同时且开源、免费。

结合项目来看,MariaDB 采用 Spider 插件进行分库分表的兼容,Spider 存储引擎是一个内置分片功能的存储引擎。它兼容分区和xa 事务,同时允许处理不同 MariaDB 实例的表,就好像它们在同一个实例上一样。

请参考资料:(链接已移除)

结合项目来看,在这篇文章里,笔者将采用 MariaDB Spider 进行分库分表的实践。

部署 MariaDB 实例

实际处理时,为便于更好地新建分库分表实践环境,这里需三个 “物理”数据库,一个逻辑数据库,即四个 MariaDB 实例。MariaDB 实际占用的内存同时不大,笔者 4G 内存的服务器装了 Kubernetes,用 Docker 部署四个 MariaDB 数据库,运行速度正常,对于我们测试练习 4G 内存足以。

四个数据库的关系如图:

实际处理时,其中,逻辑数据库实例称为 Spider Proxy Node,实际存储数据的数据库实例被称为 Backend Node。

结合项目来看,典型的 Spider 部署具有无共享的集群架构。该系统适用来任何廉价的硬件,同时且对硬件或软件的特定要求最低。它由一组计算机组成,具有一个或多个 MariaDB 进程,称为节点。

存储数据的节点将被设计为Backend Nodes,同时且能够是任何 MariaDB、MySQL、Oracle 服务器实例,采用后端内可用的任何存储引擎。

Docker 部署

在这个场景下,若机器不够,采用虚拟机部署便会显得很麻烦,这里笔者采用 Docker 更快部署练习。

参考资料:(链接已移除)

查看 MariaDB 镜像版本列表:(链接已移除)

理解这一步时,直接新建四个数据库实例,其中一个是 Spider 实例,实例采用端口区分。

docker run --name mariadbtest1 -e MYSQL_ROOT_PASSWORD=123456 -p 13306:3306 -d docker.io/library/mariadb:10.7

docker run --name mariadbtest2 -e MYSQL_ROOT_PASSWORD=123456 -p 13307:3306 -d docker.io/library/mariadb:10.7
docker run --name mariadbtest3 -e MYSQL_ROOT_PASSWORD=123456 -p 13308:3306 -d docker.io/library/mariadb:10.7
docker run --name mariadbspider -e MYSQL_ROOT_PASSWORD=123456 -p 13309:3306 -d docker.io/library/mariadb:10.7

从实现思路看,接着,进入每个容器实例中,进入 /etc/mysql/mariadb.conf.d 目录,修改50-server.cnf文件,运行远程访问数据库实例。由于容器中没有 nano、vi 这些编辑命令,所以能够采用下面的命令更快替换文件内容:

echo '
[server]
[mysqld]
pid-file = /run/mysqld/mysqld.pid
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
lc-messages = en_US
skip-external-locking
bind-address = 0.0.0.0
expire_logs_days = 10
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
[embedded]
[mariadb]
[mariadb-10.7]
' > 50-server.cnf

然后查看每个容器的主机内 IP:

docker inspect --format='{{.NetworkSettings.IPAddress}}' mariadbtest1 mariadbtest2 mariadbtest3 mariadbspider

172.17.0.2
172.17.0.3
172.17.0.4
172.17.0.5

实际处理时,接着打开名为 mariadbspider 的容器,在里面按照 Spider 插件:

apt update
apt install mariadb-plugin-spider

虚拟机部署

从实现思路看,这里需四个虚拟机,每个虚拟机都需先安装 MariaDB 数据库引擎以及一些工具包。

可参考:(链接已移除)

在这个场景下,首先在每个虚拟安装 MariaDB Community Server,即数据库引擎。

从实现思路看,若采用虚拟机部署安装,需替换国内镜像源,以便更快下载需的包, Centos 服务器,能够直接以下命令更快更新镜像源,如果是 Debain 系列,可自行查找对应的镜像源。

wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
#清除缓存
yum clean all
#生成新的缓存
yum makecache

接着,设置 MariaDB 官方的软件包存储库:

sudo yum install wget
wget https://downloads.mariadb.com/MariaDB/mariadb_repo_setup
echo "fd3f41eefff54ce144c932100f9e0f9b1d181e0edd86a6f6b8f2a0212100c32c mariadb_repo_setup" | sha256sum -c -
chmod +x mariadb_repo_setup
sudo ./mariadb_repo_setup --mariadb-server-version="mariadb-10.7"

再次更新镜像源缓存:

#清除缓存
yum clean all
#生成新的缓存
yum makecache

安装 MariaDB 社区服务器和软件包依赖项:

sudo yum install MariaDB-server MariaDB-backup

接着,设置允许远程访问数据库。

落到代码里,MariaDB 的设置文件都在 /etc/my.cnf 中,打开 /etc/my.cnf.d/ 目录后,修改 server.cnf 文件,允许远程访问。找到 bind-address 属性,去掉 #

#bind-address=0.0.0.0

bind-address=0.0.0.0

如需了解每个设置的作用,请参考资料: (链接已移除)

修改密码。因为裸机部署的数据库,本身没有密码,所以需手动设置。

打开终端,执行以下命令:

mysql -u root -p
set password for root @localhost = password('123456');

随后执行 quit; 退出数据库操作终端。

实际处理时,若提示 root 不存在,则请采用 mysql -u mysql -p,密码为空,直接按下回车键即可。如果不行,则参考:(链接已移除)

然后重启数据库实例:

systemctl restart mariadb
systemctl status mariadb

接着检查防火墙设置,或执行 sudo iptables -F 清理防火墙设置。

MariaDB 设置

MariaDB 设置文件中,部分主要属性的说明如下所示如下所示:

字段说明
bind_address绑定访问地址
max_connections最大连接数
thread_handling设置 MariaDB 社区服务器如何处理客户端连接的线程
log_error错误日志输出文件

MariaDB 基础维护命令:

说明命令
启动sudo systemctl start mariadb
停止sudo systemctl stop mariadb
重新启动sudo systemctl restart mariadb
在启动期间启用sudo systemctl enable mariadb
启动时禁用sudo systemctl disable mariadb
状态sudo systemctl status mariadb

检查每个实例

部署数据库后,需连接每个数据库进行测试,以便检查数据库是否正常。

设置 Spider

结合项目来看,打开 mariadbspider 数据库实例,执行以下命令,加载 spider 插件,将其设置为 Spider 数据库实例。

INSTALL SONAME 'ha_spider';

执行命令查询是否已经启动 Spider 插件:

SELECT * FROM mysql.plugin;

请参考资料:(链接已移除)

远程表

MariaDB Spider 模式已经搭建好了,这里开始进行实践。

实际处理时,在这个模式里,Spider 中的一个表对应一个数据库实例中的同名数据库的同名表,即数据库名称系统,表名称相同。

实际处理时,首先在 三个数据库实例中,新建一个测试数据库,名称为 test1,随后执行命令新建表:

CREATE TABLE s(
  id INT NOT NULL AUTO_INCREMENT,
  code VARCHAR(10),
  PRIMARY KEY(id));

落到代码里,然后在 mariadbspider 实例中,执行命令,新建逻辑表,同时将这个表绑定到 mariadbtest1 实例中。

CREATE TABLE s(
  id INT NOT NULL AUTO_INCREMENT,
  code VARCHAR(10),
  PRIMARY KEY(id)
)
ENGINE=SPIDER
COMMENT 'host "172.17.0.2", user "root", password "123456", port "3306"';

实际处理时,注意替换你的 IP,另外注意端口,如果是容器访问容器,直接采用 3306。

若没有设置好,数据库不对应等,可能会出现:

> 1046 - No database selected
> 时间: 0.062s

然后在 mariadbspider 中,插入四条数据:

INSERT INTO s(code) VALUES ('a');
INSERT INTO s(code) VALUES ('b');
INSERT INTO s(code) VALUES ('c');
INSERT INTO s(code) VALUES ('d');

实际处理时,若分别打开三个实例,你会发现,插入的数据只会出现在 mariadbtest1 中出现,因为这个表只绑定了它。你还能够在 mariadbspider 上对这个表进行增删查改,所有操作都会同步到对应数据库实例中。

基准性能测试

结合项目来看,SysBench 是一个模块化、跨平台和多线程的基准测试工具,兼容 Windows 和 Linux,用来评估对于在高负载下运行数据库的系统很重要的操作系统参数。这个基准测试套件的想法是,在不设置复杂的数据库基准或甚至根本不安装数据库的情况下,更快获得系统性能的印象。它能够测试出:

  • 文件 i/o 性能
  • 调度器性能
  • 内存分配和传输速度
  • POSIX 线程实现性能
  • 数据库服务器性能(OLTP 基准)

项目地址:(链接已移除)

Linux 能够直接安装二进制包。

Debian/Ubuntu

curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh | sudo bash
sudo apt -y install sysbench

RHEL/CentOS:

curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
sudo yum -y install sysbench

Fedora:

curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash	
sudo dnf -y install sysbench

Arch Linux:

sudo pacman -Suy sysbench

sysbench 命令格式:

sysbench <TYPE> --threads=2 --report-interval=3 --histogram --time=50 --db-driver=mysql --mysql-host=<HOST> --mysql-db=<SCHEMA> --mysql-user=<USER> --mysql-password=<PASSWORD> run

首先,在当前特定数据库下新建模拟数据:

sysbench oltp_read_write --db-driver=mysql --mysql-user=root --mysql-password=123456 --mysql-host=123.123.123.123 --mysql-port=13309  --mysql-db=test1 prepare
sysbench 1.0.18 (using system LuaJIT 2.1.0-beta3)

Creating table 'sbtest1'...
Inserting 10000 records into 'sbtest1'
Creating a secondary index on 'sbtest1'...

接着运行测试:

sysbench oltp_read_write --db-driver=mysql --mysql-user=root --mysql-password=123456 --mysql-host=123.123.123.123 --mysql-port=13309  --mysql-db=test1 run
SQL statistics:
    queries performed:
        read: 112
        write: 32
        other: 16
        total: 160
    transactions: 8 (0.80 per sec.)
    queries: 160 (15.96 per sec.)
    ignored errors: 0 (0.00 per sec.)
    reconnects: 0 (0.00 per sec.)

General statistics:
    total time: 10.0273s
    total number of events: 8
Latency (ms):
         min: 1244.02
         avg: 1253.36
         max: 1267.87
         95th percentile: 1258.08
         sum: 10026.85
Threads fairness:
    events (avg/stddev): 8.0000/0.00
    execution time (avg/stddev): 10.0269/0.00

或者每 3 秒生成一次直方图:

sysbench oltp_read_write --threads=2 --report-interval=3 --histogram --time=50 --table-size=1000000 --db-driver=mysql --mysql-user=root --mysql-password=123456 --mysql-host=123.123.123.123 --mysql-port=13309 --mysql-db=test1 run

清理模拟生成的数据:

sysbench oltp_read_write --db-driver=mysql --mysql-user=root --mysql-password=123456 --mysql-host=123.123.123.123 --mysql-port=13309 --mysql-db=test1 cleanup

sysbench 跑测试时,可选参数如下所示:

  • 采用–time=<SECONDS>运行固定时间
  • 采用–events=0对执行的查询不设置限制
  • 采用–db-ps-mode=disable禁用准备好的语句
  • 采用–report-interval=<SECONDS>拿到绘图点
  • --histogram得到一个直方图

sysbench 有三个过程或执行模式:

  1. prepare:为需它们的测试执行准备操作,比如在磁盘上为fileio 测试新建必要的文件,或填充测试数据库以进行数据库基准测试。
  2. run:运行采用testname 参数指定的实际测试。此命令由所有测试提供。
  3. cleanup:在新建一个的测试中测试运行后删除临时数据。

你也能够参考笔者的另一篇文章,采用别的方法做基准测试:(链接已移除)

加入后端数据库

实际处理时,在远程表一节里,我们是在新建表的时候,再绑定一个数据库实例,其实也能够提前设置多个数据库实例到 Spider 中,下面是在 Spider 中执行的设置命令:

CREATE SERVER mariadbtest1 
  FOREIGN DATA WRAPPER mysql
OPTIONS(
  HOST '172.17.0.2',
  DATABASE 'test1',
  USER 'root',
  PASSWORD '123456',
  PORT 3306
);

CREATE SERVER mariadbtest2
  FOREIGN DATA WRAPPER mysql
OPTIONS(
  HOST '172.17.0.3',
  DATABASE 'test1',
  USER 'root',
  PASSWORD '123456',
  PORT 3306
);

CREATE SERVER mariadbtest3
  FOREIGN DATA WRAPPER mysql
OPTIONS(
  HOST '172.17.0.4',
  DATABASE 'test1',
  USER 'root',
  PASSWORD '123456',
  PORT 3306
);

哈希分片

在这个场景下,在这一小节里,我们将一个表进行分片,在插入数据时,数据自动分片到三个数据库实例中。

在三个数据节点数据库里,在 test1 数据库下,执行命令,新建表:

CREATE  TABLE shardtest
(
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
)

此时,三个数据库实例都具有相同的表。

理解这一步时,然后在 mariadbspider 实例中,执行命令,新建逻辑表,同时将此表借助切片的模式,连接到三个数据库实例中。

CREATE TABLE test1.shardtest
(
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=spider COMMENT='wrapper "mysql", table "shardtest"'
 PARTITION BY KEY (id)
(
 PARTITION pt1 COMMENT = 'srv "mariadbtest1"',
 PARTITION pt2 COMMENT = 'srv "mariadbtest2"',
 PARTITION pt3 COMMENT = 'srv "mariadbtest3"'
) ;

结合项目来看,随后打开 (链接已移除),找到 分片测试数据.sql 这个文件,里面有很多模拟数据。

你能够观察到,三个数据库实例的数据是不同的。

根据值范围分片

分片方式的选择在于 PARTITION BY 属性,比如哈希分片是根据一个键进行计算的,则设置命令为 PARTITION BY KEY (id),如果是根据值范围分片,则是 PARTITION BY range columns (<字段名称>)

) ENGINE=spider COMMENT='wrapper "mysql", table "shardtest"'
 PARTITION BY range columns (k)
(
 PARTITION pt1 values less than (5000) COMMENT = 'srv "mariadbtest1"',
 PARTITION pt2 values less than (5100) COMMENT = 'srv "mariadbtest2"'
 PARTITION pt3 values less than (5200) COMMENT = 'srv "mariadbtest3"'
) ;

根据列表分片

结合项目来看,根据列表分片,一般是某个字段,能够将数据划分为不同类型,能够根据这个字段的内容对数据进行分组。

) ENGINE=spider COMMENT='wrapper "mysql", table "shardtest"'
 PARTITION BY list columns (k)
(
 PARTITION pt1 values in ('4900', '4901', '4902') COMMENT = 'srv "mariadbtest1"',
 PARTITION pt2 values in ('5000', '5100') COMMENT = 'srv "mariadbtest2"'
 PARTITION pt3 values in ('5200', '5300') COMMENT = 'srv "mariadbtest3"'
) ;

从实现思路看,当数据的 k 字段,值是 4900、4901 或 4902 时,将被分片到 mariadbtest1 实例中。

到此这篇关于MariaDB Spider 数据库分库分表实践的文章就介绍到这了,更多相关MariaDB Spider 分库分表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多兼容脚本之家!

您可能感兴趣的文章:
  • Docker实现Mariadb分库分表及读写分离功能

最新游戏

更多

Copyright©2010-2019. All rights reserved | 波波三国游戏官网|[email protected]

备案编号:湘ICP备2022015115号-4