尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

本地部署PolarDB-X:分布式数据库实操全记录

本地部署PolarDB-X:分布式数据库实操全记录 最近“本地部署”这个词在技术圈里真是火得不行前脚大家还在折腾本地跑大模型后脚就有人开始问数据库能不能也在自己机器上跑起来。答案当然是可以而且跑起来比你想的简单不少。这篇文章就记录我这次把 PolarDB-X 部署到本地全流程的实操经历包括架构理解、部署步骤、连接测试和踩坑记录。PolarDB-X 是阿里云开源的一款分布式关系型数据库完整兼容 MySQL 协议本地部署之后你可以在自己电脑上体验分库分表、分布式事务、全局二级索引这些能力非常适合正在学习分布式数据库的开发者、做技术选型评测的架构师以及想在离线环境里搭一套 MySQL 增强版数据库的运维同学。1. 项目概述PolarDB-X 为什么值得本地部署1.1 PolarDB-X 是什么PolarDB-X 的源头可以追溯到阿里巴巴电商系统的分布式数据库中间件经历了 TDDL、DRDS 等多个阶段最终演进为今天这个计算存储分离架构的云原生分布式数据库并且对外开源。它对外暴露的是标准 MySQL 协议也就是说你手里现有的 MySQL 客户端、JDBC 驱动、ORM 框架几乎不需要改动就能连上去用这对开发者的迁移成本非常友好。从能力上看PolarDB-X 解决了传统单机 MySQL 在数据量爆炸后很难水平扩展的问题。它可以把一份逻辑表按照某个分区键自动打散到多个存储节点上应用层看到的仍然是一张表实际底层已经拆成了几十甚至上百个物理分片。开发者不需要自己在业务代码里做分库分表逻辑也不需要引入额外的中间件这是它与 ShardingSphere、MyCat 这类中间件方案最本质的差别。PolarDB-X 还有一个特点它不只是把数据分片存起来还保证了分布式场景下的事务一致性。传统分库分表后跨库事务经常要引入分布式事务框架PolarDB-X 内置了基于全局时间戳的事务机制业务代码就像操作单机数据库一样简单。这也是我在训练营里印象最深的部分后面我会专门展开讲。1.2 本地部署解决了什么痛点对一个想学分布式数据库的人来说最大的门槛不是概念而是环境。以前要体验这类数据库要么付费买云上实例要么自己凑几台服务器搭集群成本高、流程长、改坏了还不方便重来。本地部署的意义就在于把门槛降到一台电脑就能搞定的程度。这次体验下来本地部署 PolarDB-X 真正解决的痛点有三个。第一零成本体验只要机器上有 Docker一条命令就能把整个 PolarDB-X 跑起来不需要申请任何云资源。第二随改随用本地环境完全自己掌控可以反复初始化、删除、重建适合做实验和测试。第三离线可用如果公司内网环境不允许连接外部的云数据库本地部署一套 PolarDB-X 做开发联调是非常实用的方案。而且现在很多团队都在探索本地部署大模型、本地部署 AI 服务这类离线方案数据不出内网已经成为一个普遍诉求。数据库作为所有应用的地基自然也值得纳入本地部署的范畴。你可以把 PolarDB-X 当作一个具备分布式能力的本地数据库在开发环境里提前验证它在高并发、大数据量场景下的表现。1.3 这篇文章适合谁如果你属于下面几类人这篇实操记录应该能帮你节省不少时间正在学习分布式数据库原理的开发者想找一个真实系统动手验证分库分表、全局索引等概念。做技术选型的技术负责人需要快速评估 PolarDB-X 是否适合自家业务本地部署是成本最低的验证方式。DBA 或运维同学希望在非生产环境搭建一套兼容 MySQL 的分布式数据库用于测试数据迁移、备份恢复等流程。纯粹对数据库技术好奇想在自己的电脑上跑一个“看起来很厉害”的分布式数据库的玩家。不管哪一类我建议你先准备一台内存不低于 8GB、磁盘剩余空间不低于 20GB 的电脑操作系统不限只要能装 Docker 就行。下面所有的步骤我都按最简单的方式给你拆开。2. 部署前必须搞懂的架构GMS、CN、DN、CDC2.1 四大核心组件的作用在敲命令之前我强烈建议你先花十分钟理解 PolarDB-X 的架构。知道自己启动的容器里到底跑了哪些进程后面遇到问题才能有排查方向。PolarDB-X 整体是计算与存储分离的架构核心组件有四个。第一个是 GMSGlobal Meta Service负责全局元数据管理包括表结构、分区信息、全局时间戳分配等。分布式事务依赖的时间戳就是 GMS 统一下发的它保证所有节点拿到的时钟是一致的这样跨节点的事务才能做到有序提交。第二个是 CNCompute Node也就是计算节点。它对客户端暴露 MySQL 协议端口接收 SQL 请求后进行解析、优化、生成执行计划再把任务下推到各个 DN 并行执行最后汇总结果返回给客户端。CN 本身是无状态的可以水平扩展多个本地单机部署只需要一个 CN。第三个是 DNData Node数据节点负责实际数据的存储和读写底层基于 InnoDB 存储引擎。在分布式模式下一张逻辑表的数据会按照分区规则散列到多个 DN 上每个 DN 只保存部分数据。第四个是 CDCChange Data Capture负责捕获数据变更并对外输出 binlog 格式的变更流常用于数据同步到其他系统。这四个组件各司其职组合在一起才能构建出一个完整的分布式数据库系统。在本地一键部署时官方镜像会把这四个组件整合进一个容器里对外呈现为一个整体你可以理解为“麻雀虽小五脏俱全”。2.2 一体化镜像与分布式集群的区别很多人第一次接触 PolarDB-X 本地部署会有一个疑问官方提供的一键启动容器和真正生产环境的集群有什么区别我这次理解下来区别主要在于部署形态和资源隔离。一键启动的方式是把 GMS、CN、DN、CDC 全部跑在一个容器里。这种形态适合开发测试、功能体验和初步学习因为所有网络通信都在容器内部完成部署命令极其简单。但它的局限性也很明显单点瓶颈容器所在机器挂了整个数据库就不可用资源共挤计算和存储共享一份系统资源难以独立扩容。生产环境一般建议使用 PolarDB-X Operator 在 Kubernetes 上部署或者用物理机/虚拟机的方式手动部署多 CN、多 DN 拓扑。比如一个常见的生产集群可以是 2 个 CN、3 个 DN、1 个 GMS、2 个 CDC 副本每个组件独立成 Pod 或独立进程具备高可用和弹性伸缩能力。对于本地部署这篇文章来说我们选择一体化镜像就够了。你要理解的是这个容器里其实包含了一整套完整组件只是被打包在一起你可以在容器内用ps命令看到多个 Java 进程它们就是不同组件的运行时。2.3 部署方案选型对比在你准备动手之前我帮你把几种本地部署方案做个对比方便你根据实际情况选方案适合场景难度资源占用高可用Docker 单容器快速体验、开发测试低低无Docker Compose 多容器模拟多节点拓扑中中弱本地 K8s Operator进阶实验、生产预演高高中多台物理机/虚拟机手动部署真实生产验证很高很高强我这次选择的是第一种方案原因很简单目标是把 PolarDB-X 跑起来用最少的步骤验证它的功能。如果你后续想深入研究高可用和扩缩容可以再挑战 K8s 方案但那是另一个量级的工作量。先把最简单的跑通再逐步加深这个学习路径我觉得是最高效的。3. 实操准备环境要求与环境检查3.1 硬件与软件要求先说硬件我对这次部署的结论是PolarDB-X 对硬件的要求没有想象中那么高但内存和磁盘必须给够。官方容器镜像启动后GMS、CN、DN、CDC 四个组件都会有自己独立的 JVM 进程合计内存占用在 4GB 左右。如果你的电脑只有 8GB 内存部署期间请把不必要的程序关掉否则很容易出现容器假死。磁盘方面PolarDB-X 的 Docker 镜像大约 2GB 到 3GB容器运行后数据文件会持续增长加上日志预留 20GB 会比较从容。另外容器启动时需要进行一系列初始化操作包括创建系统库、初始化 GMS、启动多个组件进程这个过程一般需要几分钟期间 CPU 会比较饱满所以别再同时跑大型编译任务否则等待时间会让你怀疑机器卡死了。软件方面核心依赖就是 Docker。我建议 Docker Engine 版本不低于 20.10Docker Compose 如果有就提前装好虽然本文用不到 Compose但后续做多容器实验会用到。操作系统完全随意Windows、macOS、Linux 都行Docker 桌面版或者 Linux 下的 Docker Engine 都可以。3.2 Docker 环境检查在拉取 PolarDB-X 镜像之前先用几个简单命令确认 Docker 环境正常。这一步很重要很多人后面部署失败就是因为本地 Docker 启动异常或者版本过旧。执行命令如下docker --version docker compose version docker info如果docker info能正常输出服务端信息说明 Docker 守护进程运行正常。如果报错提示无法连接Windows 用户检查一下 Docker Desktop 是否启动Linux 用户检查当前用户是否加入了 docker 用户组。顺手清理一下历史无用镜像避免磁盘空间不足docker system df docker system prune -f我这次清理之后腾出了不少空间因为之前本地堆积了几十个中间层镜像磁盘一度告急。确认环境没问题后就可以进入正式的部署环节了。4. 本地部署实操完整步骤记录4.1 拉取镜像并启动容器PolarDB-X 的官方镜像托管在 Docker Hub 上仓库名是polardb/polardb-x。我这次用的是2.3.0这个稳定版本你也可以直接使用latest标签拉取最新版。拉取命令如下docker pull polardb/polardb-x:2.3.0镜像体积约 2GB 多拉取时间取决于你的网络情况。下载完成后启动容器docker run -d --name polardb-x \ -p 8522:8522 \ -e TZAsia/Shanghai \ --restartalways \ polardb/polardb-x:2.3.0这里解释一下每个参数的作用。-d表示后台运行容器--name给容器起一个固定名字方便后续管理-p 8522:8522把容器内的 8522 端口映射到宿主机PolarDB-X 的 MySQL 兼容协议端口就是 8522不是默认的 3306这个千万别记错-e TZAsia/Shanghai设置容器时区--restartalways让 Docker 在重启后自动拉起容器避免本地开发机重启后数据库不通。启动容器后立刻查看启动日志docker logs -f polardb-x日志会输出大量初始化信息包括组件加载、元数据初始化等这个过程我实测大概需要两到三分钟。当看到类似PolarDB-X is ready或者Start successfully的提示时说明数据库实例已经就绪。中间如果长时间没有输出不要急多看一会儿第一次启动确实比较慢。4.2 连接你的第一个 PolarDB-X 实例实例启动就绪后接下来就是连接验证。PolarDB-X 默认的管理员账号是polardbx_root初始密码一般默认是123456不过为了稳妥还是建议先从容器日志里确认一下初始化信息找到类似 password 的关键字。在我的实际操作中连接方式有两种。第一种是在宿主机上用 MySQL 客户端直接连mysql -h127.0.0.1 -P8522 -upolardbx_root -p123456如果你电脑上没有 MySQL 客户端可以用第二种方式进入到容器内部执行docker exec -it polardb-x mysql -upolardbx_root -p123456注意容器内执行时不需要再指定端口和主机因为默认就是连接本地实例。连接成功后会看到 MySQL 风格的命令行提示符因为 PolarDB-X 兼容 MySQL 协议客户端交互体验和原生 MySQL 几乎一样。进入命令行后先执行两条最基础的 SQL 验证连接状态SELECT VERSION(); SHOW DATABASES;SELECT VERSION()会返回 PolarDB-X 的版本号SHOW DATABASES会列出系统内置的库。看到类似information_schema、__cn_sys_db__、__gms_sys_db__之类的库名就说明整个系统正常工作了。4.3 数据持久化与常用容器管理命令很多人在本地部署数据库时会忽略一个问题容器默认是无状态的删除容器之后数据就没了。如果你只是做一个快速体验这没什么问题。但如果你打算把这个容器当作长时间使用的本地开发库建议做数据持久化。PolarDB-X 官方的一体化镜像在持久化方面相对简单最稳妥的做法是给容器挂载一个 Docker volume 或者绑定宿主机的数据目录docker run -d --name polardb-x \ -p 8522:8522 \ -v polardbx_data:/data \ -e TZAsia/Shanghai \ polardb/polardb-x:2.3.0挂载数据卷后即使容器被删除数据卷中的数据也依然保留。重新创建容器时复用同一个数据卷数据就回来了。需要提醒的是不同版本对数据目录的要求可能不同最好以官方文档为准。如果只是短期学习不做持久化也一样跑但我个人建议一开始就把数据卷加上养成好习惯。常用运维命令也顺手列出来后面排查问题会频繁用到docker ps -a docker start polardb-x docker stop polardb-x docker logs --tail100 polardb-x docker stats polardb-xdocker stats用来查看容器实时资源占用非常有用后面排查内存问题时你会感谢这条命令。5. 快速体验分布式数据库能力5.1 创建 AUTO 模式数据库数据库连接通了接下来要做的事情是动手创造一张分布式表验证 PolarDB-X 的核心能力。PolarDB-X 创建数据库时支持指定模式本地部署最常用的是AUTO模式。这种模式下你不需要手动设计分库分表规则系统会自动根据主键或唯一键把数据拆分到多个分区上。执行下面的 SQL 创建一个 AUTO 模式的测试库CREATE DATABASE polarx_demo MODEauto; USE polarx_demo;创建完成之后你可以在该库下直接建普通表PolarDB-X 会自动把它变成分区表。这种体验非常像单机 MySQL但底层已经是分布式存储了。我个人觉得这是 PolarDB-X 设计得很聪明的地方它把分布式系统的复杂性封装在引擎内部对业务透明让开发者的心智负担大大降低。如果你的业务有明确的分区键需求比如订单表必须按照买家 ID 分片那么可以改用PARTITION模式创建数据库在这个模式下你需要手动指定分区策略。两种模式各有适用场景一个强调易用一个强调控制力我这次先用 AUTO 模式跑通流程。5.2 创建分区表与全局二级索引创建好数据库后我们来创建一张分布式订单表这是分布式数据库最经典的应用场景之一。SQL 如下CREATE TABLE t_order ( id BIGINT NOT NULL AUTO_INCREMENT, customer_id BIGINT NOT NULL, order_amount DECIMAL(10,2), status VARCHAR(32), create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id, customer_id) ) PARTITION BY HASH(customer_id) PARTITIONS 16;注意这条建表语句和普通 MySQL 建表有两个明显不同。第一主键是联合主键(id, customer_id)在 PolarDB-X 中分区键必须包含在主键中否则会报错原因很简单分区键决定了数据落在哪个节点如果主键不含分区键就无法保证全局唯一性。第二末尾多了PARTITION BY HASH(customer_id) PARTITIONS 16含义是按照customer_id做哈希取模把数据分散到 16 个分区。这个区域对查询WHERE customer_id 1非常友好数据库可以直接定位到具体分区不需要扫描全表。再来看全局二级索引的作用。上面的订单表按照customer_id分区如果业务里经常按订单状态或创建时间查询这些查询可能会涉及全部分区性能很难保证。解决方式是在这些字段上创建全局二级索引CREATE GLOBAL INDEX idx_status ON t_order(status);索引创建完成后当查询条件包含status字段时优化器可以自动选择走这个全局索引快速定位到符合条件的数据而不需要遍历所有分区。这个能力是单机数据库普通索引做不到的因为单机索引和数据在同一个存储引擎内而分布式环境下索引和数据可能分布在不同的节点上需要特殊的全局索引机制来维护。执行完建表和建索引的操作后可以插入几条测试数据验证一下INSERT INTO t_order (customer_id, order_amount, status) VALUES (1001, 199.90, PAID), (1002, 89.00, PENDING), (1001, 299.00, PAID), (1003, 59.90, SHIPPED);然后执行一次带条件的查询感受一下全局索引的效果SELECT * FROM t_order WHERE customer_id 1001; SELECT * FROM t_order WHERE status PAID;第一条查询会直接定位到customer_id对应的分区第二条查询则会借助idx_status全局索引完成数据定位。从应用侧看这两条 SQL 与 MySQL 写法完全一致但执行路径已经完全不同。5.3 用 SHOW 命令查看分布式元数据连接数据库之后很多人会好奇这张表到底被拆分成了多少份、落在哪些节点上。PolarDB-X 提供了一些特殊的 SHOW 命令可以查看这些分布式元数据。首先查看建表语句的完整信息SHOW CREATE TABLE t_order;执行结果会显示实际生效的分区键、分区数量、索引信息比原始建表语句多出很多内部细节。如果你想看表的分区分布情况可以执行SHOW PARTITIONS FROM t_order; SHOW INDEX FROM t_order;这些命令的输出非常直观分区名、分区表达式、所在节点信息都会列出来。通过它们你可以把抽象的“分布式”概念转化为具体的分区列表对理解 PolarDB-X 的数据分布非常有帮助。我第一次看到 16 个分区被均匀地列出来时才算真正理解了什么叫“一张表拆在多处”。再执行一个查询看看数据库对全局索引的识别情况SHOW GLOBAL INDEX FROM t_order;看到idx_status出现在全局索引列表中说明这个索引确实是跨节点的全局索引而不是普通本地索引。到这里PolarDB-X 最典型的两个分布式能力——分区分表和全局索引——已经在本地完整跑通了一遍。6. 常见问题与排查技巧实录6.1 端口冲突与容器启动失败本地部署最常见的坑之一就是端口被占用。8522 这个端口平时用得不多但如果你的机器上有其他中间件恰好占用容器就会启动失败。docker logs里会显示端口绑定失败相关的报错。解决办法很简单换一个宿主机映射端口docker run -d --name polardb-x \ -p 18522:8522 \ polardb/polardb-x:2.3.0这样就把容器内的 8522 映射到宿主机的 18522连接时执行mysql -h127.0.0.1 -P18522 -upolardbx_root -p123456即可。另外如果之前已经用同名容器启动过失败实例再次启动前需要先清理旧容器docker rm -f polardb-x6.2 连接不上与密码问题连接失败最典型的报错是ERROR 1045 (28000): Access denied for user polardbx_root...。多数情况是密码不对尤其是用自定义环境变量或者新版本镜像时初始密码可能不再是123456。遇到这种情况第一件事是去看初始化日志docker logs polardb-x | grep -i password日志里通常会打印初始化的管理员密码或临时密码。如果日志里也没有一个变通办法是重新创建一个新容器并在启动前通过环境变量指定密码。需要提醒的是PolarDB-X 镜像的初始密码机制不同版本略有差异最可靠的信息来源始终是官方文档和容器日志。另一个连接失败原因是 MySQL 客户端版本过旧。PolarDB-X 对 MySQL 5.7 和 8.0 的协议都做了兼容但如果你用的是非常老的客户端可能在认证方式上不兼容。建议升级到 MySQL 8.0 的官方客户端或者使用容器内自带的 mysql 命令进入省去本地客户端的麻烦。6.3 内存占用过高与性能优化PolarDB-X 一体机容器对内存的占用确实不小因为 GMS、CN、DN、CDC 四个组件各自都有独立的 JVM 进程。我实测过空闲状态下内存占用轻易超过 4GB。如果你的电脑内存不够大容器频繁 OOM 会让你非常头疼。优化的第一个思路是限制容器自身的内存使用在docker run时加上资源限制参数避免它把宿主机内存吃光docker run -d --name polardb-x \ -p 8522:8522 \ -m 6g \ polardb/polardb-x:2.3.0-m 6g表示容器最大使用 6GB 内存超限后内核会采取 OOM 策略。这个值可以根据你机器实际情况调整但我建议不要低于 4GB否则组件可能启动失败。第二个思路是关闭不必要的后台容器和服务给 PolarDB-X 腾出资源。第三个思路适用于深度玩家的场景如果只是验证 SQL 功能和分布式逻辑可以连接后用SET GLOBAL调整一些内存相关的参数但这需要你先清楚每个组件的内存配置入口难度偏高。排查内存问题最实用的工具还是docker stats它能实时显示每个容器的 CPU 和内存占用。发现内存飙升时再用docker logs查看对应时间段日志定位是哪个组件引起的。6.4 数据目录与容器重建的坑最后忍不住提醒一个我自己踩过的坑容器一旦删除默认情况下数据会全部丢失。如果你已经创建了测试表和测试数据想重新部署一个新版本镜像千万别直接docker rm否则前功尽弃。实际操作中建议先做逻辑备份docker exec polardb-x mysqldump -upolardbx_root -p123456 polarx_demo backup.sql这条命令会把polarx_demo库的所有表结构和数据导出到宿主机当前目录的backup.sql文件里。重建容器后再通过 mysql 命令导入回来mysql -h127.0.0.1 -P8522 -upolardbx_root -p123456 backup.sql对于本地学习环境用 mysqldump 逻辑备份已经足够。如果你追求更省心的方式就用前面提到的挂载数据卷方案从源头解决数据持久化问题。我的习惯是两条腿走路既有数据卷挂载也定期做逻辑备份这样无论容器层怎么变动数据都稳如泰山。最后再分享一个小技巧这篇文章写到这里PolarDB-X 本地部署的主流程已经全部跑通了。我自己实践下来最大的感受是分布式数据库的学习曲线并没有想象中那么陡峭关键是要有一个真实的环境去验证那些抽象概念。当你亲眼看到一张表被拆成 16 个分区亲手动 SQL 创建出全局二级索引之后很多算法和原理的书本知识就自然串起来了。给打算动手的同学两个建议第一不要跳过架构理解这一步至少花十分钟搞清楚 GMS、CN、DN 各自的作用这对后面排查问题太重要了第二大胆做实验把容器删了重建、换版本、调参数本地环境就是用来折腾的折腾得越多理解越深。我后续还打算研究一下 PolarDB-X 在 Kubernetes 上的部署方式等有结果了再继续分享。
返回列表