文章目录MongoDB原生协议兼容这个事我得展开说说然后聊到迁移具体怎么搞性能这块我得说实话SQL操作文档数据这个能力被严重低估了多集群架构这个事也值得聊聊关于融合数据库架构的一些碎碎念和文献思考回到那次迁移本身兼容是对前人努力的尊重是确保业务平稳过渡的基石然而这仅仅是故事的起点说真的我一开始根本没打算写这篇东西。上个月帮一个老朋友搞MongoDB迁移折腾了大半个月过程中把KES的MongoDB兼容版翻来覆去用了好几遍踩了不少坑也想明白了不少事。MongoDB原生协议兼容这个事我得展开说说当时我也不太信这个零代码修改的说法因为之前见过太多号称兼容实际上各种不兼容的案例。但翻完KES MongoDB兼容版的产品文档和一些社区帖子之后发现它确实是走了一条比较硬核的路——不是在应用层做适配而是在数据库协议层直接兼容。啥意思呢你的Java应用原来用MongoDB Java Driver连接MongoDB现在只要把连接地址从MongoDB服务器改成KES服务器端口设成27017KES监听这个端口来接收MongoDB协议请求其他啥都不用动。Driver发出的所有insertOne、find、update这些命令KES都能识别和处理。// 原来连MongoDBMongoClientclientMongoClients.create(mongodb://user:passmongo-host:27017/mydb);// 迁移到KES只改地址MongoClientclientMongoClients.create(mongodb://system:123456kes-host:27017/mydb);// 后续所有操作完全不变MongoCollectionDocumentcollectionclient.getDatabase(mydb).getCollection(users);// 插入文档collection.insertOne(newDocument(name,张三).append(age,28).append(tags,Arrays.asList(vip,active)));// 查询FindIterableDocumentresultscollection.find(Filters.eq(age,28));看到没就是改个连接字符串的事。Spring Data MongoDB、PyMongo这些主流框架也都能直接用因为KES兼容的是MongoDB Wire Protocol而不是简单做了个API翻译层。我当时跟朋友说你可以先用 mongosh 连上去试试感觉就跟连了个真的MongoDB一样// 用mongosh连接KES的MongoDB兼容端口mongoshmongodb://system:123456127.0.0.1:27017/mydb?directConnectiontrueauthMechanismSCRAM-SHA-256// 创建集合db.createCollection(orders)// 插入文档db.orders.insertOne({order_id:ORD20260801001,customer:{name:李四,phone:138xxxx0001},items:[{sku:SKU001,qty:2,price:99.9},{sku:SKU002,qty:1,price:199.0}],status:pending,created_at:newDate()})// 查询db.orders.find({customer.name:李四})// 聚合查询统计每个客户的订单数db.orders.aggregate([{$group:{_id:$customer.name,orderCount:{$sum:1}}},{$sort:{orderCount:-1}}])朋友试了之后说卧槽真的能用说实话我也挺惊讶的。因为KES对MongoDB常用命令的支持率非常高查询和写入类命令100%覆盖更新操作符100%覆盖聚合管道操作符98.82%。只有一些不太常用的管理类命令比如角色管理那块没完全兼容但KES本身有自己的一套权限管理机制可以通过KES的管理工具来做。然后聊到迁移具体怎么搞零代码修改是应用层的事但数据库本身的迁移还是得做点工作的。我把KES文档里提到的步骤捋了一遍大致是这么个流程。首先是初始化KES实例得指定兼容模式# 初始化KES指定兼容模式# -m 参数指定兼容模式具体模式值参考官方部署手册# -U 指定超级用户initdb-Usystem-D/data/kes_data这里插一句KES支持多种兼容模式不同模式下语法习惯和默认行为有差异。MongoDB兼容功能是在内核层面实现的通过加载插件来启用。然后改配置文件 kingbase.conf开启MongoDB协议兼容# kingbase.conf 中添加或修改以下参数 # 开启协议兼容 enable_protocol_compat on # MongoDB兼容监听端口默认就用27017 extension_protocol_port 27017 # BSON格式使用EJSON documentdb_core.bsonUseEJson on # 在shared_preload_libraries中追加以下三个模块 shared_preload_libraries kdb_cron, kdb_documentdb_core, kdb_documentdb这几个参数逐个说下。enable_protocol_compat是总开关打开后KES才能处理非SQL协议连接。extension_protocol_port指定MongoDB协议监听端口设27017是为了跟原生MongoDB一致迁移时连接串只改IP就行。bsonUseEJson控制BSON序列化方式建议开启。shared_preload_libraries里那两个模块是KES实现MongoDB兼容的核心组件必须在启动时加载。配置改完之后重启数据库然后登录进去创建插件# 用ksql连接数据库ksql-Usystem-p54321mydb-- 创建MongoDB兼容插件cascade会自动安装依赖组件CREATEEXTENSION documentdbCASCADE;-- 给system用户设置密码MongoDB客户端连接时需要ALTERUSERsystemWITHPASSWORD123456;执行完这一步KES就处于MongoDB兼容模式了。此时你可以用任何MongoDB客户端工具来连接它mongosh、MongoDB Compass、Navicat都行选择MongoDB数据源直接连。朋友问数据怎么搬。KES有配套的KDTS做存量数据迁移图形化工具配好源端MongoDB和目标端KES连接信息就行。数据量大或对停机时间有要求的话还有KFS做实时增量同步边搬边追增量最后切换只需要很短停机窗口。# KDTS命令行示例具体参数根据版本调整# 全量迁移kdts--modefull\--sourcemongodb://source-host:27017\--targetkingbase://kes-host:27017\--databasemydb# 增量同步不停机迁移用kfs--modeincremental\--sourcemongodb://source-host:27017\--targetkingbase://kes-host:27017\--databasemydb不过KDTS和KFS具体用法还是得看官方部署手册我这里只给个概念。性能这块我得说实话我知道很多人关心迁移完性能会怎样。老实说KES在纯文档操作的性能上跟原生MongoDB比是有差距的。从产品文档里给的测试数据来看1万条数据规模下INSERT操作KES是144毫秒MongoDB是100毫秒10万条数据时KES的UPDATE是543毫秒MongoDB是328毫秒。到了百万级数据差距更明显一些UPDATE操作KES 6413毫秒MongoDB 3083毫秒。数据量1万条 操作 MongoDB KES INSERT 100ms 144ms UPDATE 35ms 52ms SELECT(全表) 24ms 38ms SELECT(标量) 4ms 6ms 数据量100万条 操作 MongoDB KES INSERT 2275ms 3498ms UPDATE 3083ms 6413ms SELECT(全表) 2087ms 3320ms SELECT(标量) 174ms 270ms差距是客观存在的。但这里面有个核心问题——你是拿KES跟MongoDB单独比文档操作性能可KES的真正价值在于融合。三套系统的总成本——硬件、授权费、运维人力、数据同步开销——跟一套KES比哪个高我朋友算过一笔账光运维人力一年省两个人就够覆盖性能差距带来的硬件投入了。再说安全这块MongoDB默认认证弱、传输加密要手动配、没有透明数据加密、审计得靠第三方插件。信创和等保2.0背景下这些是硬伤。KES有细粒度RBAC、国密SM2/SM3双向认证、SSL/TLS、TDE透明数据加密、内建审计这套纵深防御体系是MongoDB给不了的。还有一点KES的文档操作性能虽然慢一些但完全够用。标量查询百万级数据270毫秒对绝大多数业务可接受。而且KES还有SQL接口操作文档数据有些复杂分析用SQL写比MongoDB聚合管道方便太多。SQL操作文档数据这个能力被严重低估了说到SQL操作文档数据我觉得这个功能被很多人忽略了。KES除了支持MongoDB原生协议访问文档数据之外还支持直接用SQL来查。这意味着什么意味着你可以在一个SQL语句里同时操作关系型数据和文档数据。举个例子你有个用户表关系型和一个订单集合文档型原来分属MySQL和MongoDB两个库想要关联查询得写ETL先同步数据再跑分析。现在都在KES一个库里了-- users是关系表orders是文档集合对应的表-- 用SQL直接做关联查询SELECTu.username,u.phone,o.order_infoFROMusers uJOINorders oONu.user_ido.order_info-user_id::intWHEREo.order_info-statuspendingANDu.register_time2026-01-01;-- 也可以直接用SQL插入文档数据INSERTINTOorders(order_info)VALUES({order_id: ORD001, customer: 张三, amount: 299.0});-- JSONB字段上的查询操作SELECTorder_info-customerAScustomer_name,(order_info-amount)::numericASamountFROMordersWHEREorder_info {status: completed}ORDERBYamountDESCLIMIT10;// 同样的查询用MongoDB语法也能做db.orders.find({status:completed}).sort({amount:-1}).limit(10)你看同一份数据你可以用MongoDB驱动访问也可以用SQL访问取决于你的场景需要。开发新功能的时候用SQL多方便啊JDBC直接连上就能写不用学MongoDB的查询语法。老代码不动继续用MongoDB驱动跑。这种灵活性是真的香。你团队里那些只会写SQL的后端以前碰MongoDB的数据就抓瞎现在一条SQL就能搞定跨数据模型的关联查询。多集群架构这个事也值得聊聊KES的融合架构里还有一个概念叫集中分布一体化说白了就是它支持多种部署模式——单机、主备、分布式集群可以根据你的可用性需求和成本预算来选。朋友原来MongoDB用Replica Set三节点MySQL主从一备Redis三主三从cluster。三套高可用方案、三套故障切换逻辑出故障时排障顺序都能搞晕人。KES的多集群架构思路是同一套数据库先单机做开发测试再切主备上生产业务量上来扩到分布式集群。底层的数据模型和SQL语法都不变只是部署形态变了。单机模式开发测试用 ↓ 主备模式小规模生产满足基本高可用 ↓ 分布式集群大规模生产水平扩展高可用而且KES分布式集群用MPP架构数据分片存在不同节点上查询时各节点并行处理。后面要做跨业务数据分析不需要额外搭数据仓库直接在KES上跑就行。朋友听完这些之后说了一句话让我印象很深他说早知道有这种融合方案我当初就不该搞那么多套数据库了。说实话我也是这种感觉很多时候技术选型上的分别部署不是有意为之而是业务发展过程中一步步加出来的等问题积累了才发现收不了场。关于融合数据库架构的一些碎碎念和文献思考聊到这块我想多说几句。数据库融合架构这个概念其实不是KES首创的但不同厂商走的技术路线差异很大理解这些差异对你做技术选型挺重要的。你去看早期做多模数据库的尝试大概2015年前后吧当时业界讨论的热点是NewSQL能不能取代NoSQL。一批人认为关系型数据库通过扩展JSON类型就能覆盖文档数据库的场景另一批人觉得NoSQL的灵活schema和水平扩展能力是关系型数据库无法替代的。这个争论持续了好几年最后的结果是两边都没完全取代对方反而催生了一种新的思路——在关系型内核上原生支持多种数据模型。不过我也得说句公道话KES的多模融合方案目前也不是完全没有短板。比如在超大规模向量检索场景下十亿级以上向量专业向量数据库的检索性能还是更有优势的。再比如文档模型那边一些MongoDB的高级特性像查询计划缓存、角色管理命令这些还没完全兼容。这些gap是否影响你的业务得自己评估。我个人觉得融合数据库架构这条路方向是对的。与其追求单一场景的极致性能然后忍受多系统的运维痛苦不如在够用的性能水平上把技术栈收敛了。尤其对于信创背景下的国产化替代来说你本来就要换数据库了与其一个MongoDB换成另一个MongoDB、一个MySQL换成另一个MySQL不如一步到位选个能融合的把长期的技术债一起清了。回到那次迁移本身最后说说我朋友那边的结果吧。经过大半个月的折腾最终方案是核心交易数据保持在KES的关系型存储里MongoDB里的用户画像和商品动态数据迁移到了KES的文档存储Redis缓存暂时保留但后续也计划迁移到KESKES本身也有缓存能力。GIS相关的业务直接用了KES内置的KGIS组件。迁移之后最直观的感受是数据一致性问题彻底解决了。因为所有数据都在一个库里跨表事务由ACID保证再也不用依赖ETL和补偿逻辑了。运维那边反馈说监控面板从一个铺满四个屏幕的大屏变成了一块屏看监控的时候终于不用来回转头了这是原话我笑了半天。应用代码那边MongoDB相关的代码几乎没改就是连接字符串换了一下。倒是有些原来用ETL做跨库分析的任务现在直接改成了SQL关联查询代码量少了一大截。朋友说光把ETL相关的代码删掉就删了两千多行删的时候特别爽。当然了过程中也有踩坑的地方。比如MongoDB的一些聚合管道操作符KES虽然支持但行为细节有差异$lookup在处理大数据量的时候内存占用比原生MongoDB高一些需要调整work_mem参数。还有mongosh连接的时候认证机制要指定SCRAM-SHA-256不指定的话有些版本会默认用SCRAM-SHA-1导致认证失败。