• [技术干货] 11月技术干货合集
    11月技术干货合集分享:1、 Linux使用waitpid回收多个子进程的方法小结 — 转载cid:link_02、 Linux获取子进程退出值和异常终止信号的完整指南 — 转载cid:link_1PostgreSQL 安装部署及配置使用教程 — 转载cid:link_34、 MongoDB分片模式集群部署方案详解 — 转载cid:link_4redis缓存神器之@Cacheable注解详解 — 转载cid:link_55、通过Redisson监听Redis集群的Key过期事件的实现指南 — 转载cid:link_66、Oracle数据库空间回收从诊断到优化实战指南详细教程 — 转载cid:link_77、MySQL EXPLAIN详细解析 — 转载cid:link_88、Linux使用wait函数回收子进程的操作指南 — 转载cid:link_99、Nginx 中的Rewrite 使用示例详解 — 转载cid:link_1010、 Linux系统日志持久化配置的完整指南 — 转载cid:link_1111、 PostgreSQL中pg_surgery的扩展使用 — 转载cid:link_1212、PostgreSQL扩展bloom的具体使用 — 转载cid:link_1313、PostgreSQL扩展UUID-OSSP的使用方法 — 转载cid:link_214、MySQL深度分页优化的常用策略 — 转载cid:link_1415、Linux使用du和sort命令查找最大文件和目录 — 转载https://bbs.huaweicloud.com/forum/thread-0250198135428299001-1-1.html
  • 分片集群运维时常见故障及排查方法?
    分片集群运维时常见故障及排查方法?
  • 分片集群如何扩容?数据如何迁移?
    分片集群如何扩容?数据如何迁移?
  • 分片集群如何保证高可用和数据安全?
    分片集群如何保证高可用和数据安全?
  • 如何选择分片键?有哪些注意事项?
    如何选择分片键?有哪些注意事项?
  • MongoDB分片集群的核心组件及其作用?
    MongoDB分片集群的核心组件及其作用?
  • 分片集群如何保证高可用和灾备?
    分片集群如何保证高可用和灾备?
  • 如何排查分片集群性能瓶颈?
    如何排查分片集群性能瓶颈?
  • 集群扩容/缩容的流程和注意事项?
    集群扩容/缩容的流程和注意事项?
  • [问题求助] 分片键选取不合理会带来哪些问题?如何优化?
    分片键选取不合理会带来哪些问题?如何优化?
  • [问题求助] MongoDB分片集群如何实现数据均衡?chunk迁移机制是什么?
    MongoDB分片集群如何实现数据均衡?chunk迁移机制是什么?
  • [技术干货] MongoDB分片模式集群部署方案详解 — 转载
    一、MongoDB分片模式简介**分片(Sharding)**是MongoDB实现数据水平扩展(Scale Out)的核心机制。通过将数据分布到多个服务器(分片节点),MongoDB可以支撑海量数据和高并发访问,避免单机性能瓶颈。二、分片集群核心架构MongoDB分片集群通常包含以下组件:mongos(路由服务)客户端访问入口,负责将请求路由到正确的分片。集群可以部署多个mongos实现高可用。分片服务器(Shard Server)存储实际数据,每个分片通常是一个副本集(Replica Set),保证高可用和数据安全。配置服务器(Config Server)存储分片元数据(分片键、数据分布等)。从MongoDB 3.4开始,必须为副本集(建议3个节点)。典型架构图:123456789101112+----------+      +------------+|  Client  | ---> |   mongos   | ---++----------+      +------------+    |                                      |                +----------+   +----------+   +----------+                | Shard 1  |   | Shard 2  |   | Shard N  |                | Replica  |   | Replica  |   | Replica  |                +----------+   +----------+   +----------+                          \      /      /                        +--------------------+                        |  Config Servers    |                        +--------------------+三、分片集群部署步骤1. 部署配置服务器(Config Server)建议3台机器,组成副本集。启动命令示例:1mongod --configsvr --replSet configReplSet --port 27019 --dbpath /data/configdb --bind_ip 0.0.0.0初始化副本集:123456789rs.initiate({  _id: "configReplSet",  configsvr: true,  members: [    { _id: 0, host: "config1:27019" },    { _id: 1, host: "config2:27019" },    { _id: 2, host: "config3:27019" }  ]})2. 部署分片服务器(Shard Server)每个分片建议为副本集(如shard1ReplSet、shard2ReplSet)。启动命令示例:1mongod --shardsvr --replSet shard1ReplSet --port 27018 --dbpath /data/shard1 --bind_ip 0.0.0.0初始化副本集:12345678rs.initiate({  _id: "shard1ReplSet",  members: [    { _id: 0, host: "shard1a:27018" },    { _id: 1, host: "shard1b:27018" },    { _id: 2, host: "shard1c:27018" }  ]})3. 部署mongos路由服务可以部署多台,提升高可用性和负载均衡。启动命令示例:1mongos --configdb configReplSet/config1:27019,config2:27019,config3:27019 --port 27017 --bind_ip 0.0.0.0四、集群初始化与分片配置连接mongos进行集群管理:1mongo --host mongos1:27017添加分片到集群:12sh.addShard("shard1ReplSet/shard1a:27018,shard1b:27018,shard1c:27018")sh.addShard("shard2ReplSet/shard2a:27018,shard2b:27018,shard2c:27018")选择数据库并启用分片:1sh.enableSharding("mydb")为集合设置分片键并启用分片:1sh.shardCollection("mydb.mycollection", {user_id: 1})分片键应选择高区分度、均匀分布的字段,避免热点。五、分片策略与数据分布**分片键(Shard Key)**决定数据如何分布。MongoDB支持范围分片(range-based)和哈希分片(hashed)。范围分片适合有顺序查询场景。哈希分片适合高并发、均匀分布场景。六、运维管理与监控高可用性:所有分片和配置服务器建议为副本集,防止单点故障。扩容与缩容:可随时添加新的分片,MongoDB自动迁移数据。监控工具:推荐使用MongoDB Ops Manager、Cloud Manager或Prometheus+Grafana。数据迁移与均衡:后台自动进行,确保分片间负载均衡。七、常见问题与排查分片键选择不当导致数据倾斜、部分分片压力过大。需分析数据分布,合理选键。配置服务器故障集群不可用或元数据丢失。建议多节点副本集+定期备份。分片集群扩容新分片加入后,数据自动迁移,需关注迁移期间性能影响。跨分片事务4.0+版本支持分片事务,但性能较单分片事务低,需关注业务设计。八、分片集群最佳实践分片键选取要合理,避免单点热点。所有关键服务(mongos、config、shard)都建议多节点部署并用副本集。定期备份配置服务器和分片数据。监控分片均衡状态,及时处理数据迁移异常。用SSL和认证机制保护集群安全。九、参考命令与工具sh.status() 查看分片集群状态db.collection.stats() 查看集合分片和存储信息sh.moveChunk() 手动迁移分片数据MongoDB Atlas(云服务)、Ops Manager(企业版)、开源监控工具十、分片原理与数据路由细节1. 数据分布与分片键每条数据根据**分片键(Shard Key)**决定存储到哪个分片。分片键值空间被切分为若干“chunk”,每个chunk属于某个分片。mongos路由服务会根据分片键,将请求直接路由到对应分片,提升查询效率。2. Chunk迁移与均衡MongoDB后台自动监控各分片数据量,发现某分片数据过多时,会自动迁移chunk到其他分片,实现负载均衡。迁移过程无须停机,但会消耗部分网络与IO资源,需关注业务高峰期。3. 查询路由优化查询语句中包含分片键时,mongos可精准路由到目标分片,效率最高。不包含分片键时,mongos会广播到所有分片,性能下降。十一、分片键设计原则与案例1. 设计原则高区分度:分片键值分布要均匀,避免数据热点。常用查询字段:最好选择业务常用的查询条件字段。不可变:分片键一旦设定,不能修改。避免递增/递减键:如时间戳、自增ID,易导致新数据集中在某分片,形成热点。2. 典型分片键案例用户系统:user_id(哈希分片更均匀)订单系统:order_id(哈希分片或组合键)日志系统:log_type + timestamp(组合分片键)3. 分片键类型范围分片:适合有区间查询需求的场景,如时间序列数据。哈希分片:适合高并发写入、分布均匀的场景。十二、分片集群高可用与灾备1. 分片副本集高可用每个分片建议至少3个副本节点,支持自动主从切换。副本集内主节点故障时,自动选举新主节点,无需人工干预。2. 配置服务器高可用配置服务器必须为副本集(3节点),防止元数据丢失。定期备份配置服务器数据,保障集群元数据安全。3. 路由服务高可用部署多个mongos实例,客户端可配置多个mongos地址实现故障转移和负载均衡。十三、分片集群扩容与缩容1. 扩容流程新增分片副本集,使用sh.addShard()命令加入集群。MongoDB自动将部分chunk迁移到新分片,实现数据均衡。扩容期间建议监控迁移进度和集群负载。2. 缩容流程先用sh.removeShard()命令移除目标分片。MongoDB会自动迁移该分片上的chunk到其他分片,迁移完成后才能正式移除。3. 动态扩缩容注意事项迁移期间会有额外性能消耗,建议在业务低峰时操作。避免分片节点资源紧张,影响数据迁移和副本集选举。十四、分片集群运维与监控1. 监控重点分片数据分布均衡情况(chunk分布、数据量)副本集健康状态(主从切换、延迟、丢失节点)配置服务器状态mongos路由负载与连接数数据迁移进度与异常2. 推荐工具MongoDB Ops Manager / Cloud Manager:官方企业级监控和自动化运维平台。Prometheus + Grafana:开源监控体系,结合MongoDB Exporter采集指标。sh.status()、db.collection.stats():命令行查看分片状态和数据分布。十五、常见故障场景与排查1. 配置服务器不可用集群无法路由和分片元数据丢失,需尽快恢复副本集或从备份恢复。2. 分片键选择错误导致数据倾斜某分片压力过大,需分析分片键分布,调整业务写入或重新设计分片键(涉及数据迁移)。3. chunk迁移异常或阻塞检查网络、磁盘IO、分片副本集健康,必要时手动迁移chunk。4. 跨分片事务性能低优化业务逻辑,尽量减少跨分片事务,或将相关数据聚合到同一分片。5. mongos负载过高增加mongos实例,优化客户端连接池配置。十六、生产环境实战建议分片键设计前务必做数据分布模拟,避免后期大规模迁移。集群所有关键组件(分片、副本集、配置服务器、mongos)都要高可用部署。定期备份配置服务器和业务数据,定期演练恢复流程。监控chunk分布和迁移进度,及时处理异常。配置认证和加密,保障数据安全。十七、分片集群的数据迁移与均衡机制1. Chunk迁移原理MongoDB自动监控每个分片的chunk数量和数据量。当某分片数据量显著高于其他分片时,balancer进程会自动将部分chunk迁移到负载较轻的分片。迁移过程为在线迁移,不会影响集群可用性,但可能影响性能。2. 手动迁移Chunk运维可通过sh.moveChunk()命令手动迁移chunk(仅在特殊场景,如自动均衡异常或热点分片迁移)。123sh.moveChunk("mydb.mycollection",     {user_id: 123456},     "shard2ReplSet")参数为集合、分片键值、目标分片。3. 迁移过程监控用sh.status()命令查看chunk分布与迁移状态。监控迁移速率、迁移失败重试次数、chunk大小变化。十八、分片集群运维监控实战1. 关键监控指标分片数据分布:chunk数量、数据量是否均衡。Balancer状态:是否在运行、是否有迁移异常。副本集健康:主节点选举、延迟、丢失节点。mongos负载:连接数、请求分布、路由延迟。配置服务器状态:副本集同步、磁盘空间。2. 监控工具推荐MongoDB Cloud Manager/Ops Manager:官方运维平台,支持分片集群专属监控。Prometheus + Grafana + MongoDB Exporter:开源监控体系,支持自定义仪表盘和报警。日志分析:关注mongos和mongod日志中的chunk迁移、分片异常、连接超时等信息。十九、分片集群的备份与恢复1. 备份策略分片副本集:对每个分片的主节点或任意节点进行备份(推荐使用mongodump、快照、企业版的备份工具)。配置服务器副本集:务必定期备份,元数据丢失会导致集群不可用。全量与增量备份结合:业务高峰期优先用增量备份,低峰期做全量备份。2. 恢复流程恢复配置服务器副本集,确保分片元数据完整。按需恢复分片副本集数据,支持单分片恢复或全量恢复。恢复后用sh.status()和db.collection.stats()检查数据完整性和分片分布。二十、分片集群的安全加固1. 认证与授权启用MongoDB认证机制(SCRAM、x.509证书等),禁止匿名访问。分片、副本集、mongos、配置服务器均需配置认证,防止横向攻击。2. 网络隔离仅开放必要端口,分片节点间建议使用专用网络或VPC。mongos对外暴露,分片和配置服务器仅内网互联。3. 加密与审计启用TLS/SSL加密,保障数据传输安全。企业版支持数据文件加密和操作审计,满足合规要求。二十一、混合部署与云原生方案1. 混合部署分片集群可跨多个数据中心或云服务部署,提升容灾能力。分片副本集可配置不同成员在不同机房,实现跨地域高可用。2. 云原生分片集群推荐使用MongoDB Atlas(官方云服务),一键部署分片集群,自动运维、自动扩容、内置监控和安全加固。结合Kubernetes Operator,支持自动扩缩容、自动备份、自动故障恢复。二十二、典型运维案例分析案例1:分片键设计不合理导致数据倾斜现象:某分片数据量远高于其他分片,业务性能下降。排查:用sh.status()分析chunk分布,发现分片键为递增ID或时间戳。解决:调整业务写入逻辑,采用哈希分片键或组合键,必要时重建集合并迁移数据。案例2:配置服务器故障导致集群不可用现象:mongos无法路由请求,集群元数据丢失。排查:副本集节点全部离线或数据损坏。解决:用备份恢复配置服务器副本集,重启mongos和分片节点,集群恢复正常。案例3:chunk迁移异常影响业务现象:业务高峰期chunk迁移导致分片节点负载过高,查询延迟增加。排查:查看balancer日志,发现迁移频繁且部分chunk迁移失败。解决:调整balancer运行时间窗口,避免高峰期迁移;优化分片键分布。二十三、分片集群常见误区与优化建议误区:分片键随便选,后期可修改分片键不可修改,需提前设计和模拟数据分布。误区:只部署单节点分片/配置服务器必须副本集高可用,单节点风险极高。误区:chunk迁移不影响业务迁移期间可能影响性能,应合理安排迁移窗口。优化建议:选用哈希分片键均衡写入压力。监控chunk分布,及时调整分片策略。定期演练备份与恢复,保障数据安全。结合云原生方案提升自动化运维能力。二十四、进一步学习与实战建议阅读MongoDB官方分片架构与运维文档。实践分片集群的部署、扩容、迁移、备份与恢复。结合Prometheus/Grafana搭建分片集群监控体系。研究MongoDB Atlas和Kubernetes Operator的分片集群自动化运维方案。结合实际业务,设计高可用、可扩展、安全的分片集群架构。
  • [技术干货] GridFSBucket是什么呢?
    GridFSBucket 是 MongoDB 官方 Java 驱动中操作 GridFS 文件存储系统 的核心类,主要用于直接与 GridFS 交互,实现大文件的上传、下载、删除等底层操作,是管理 MongoDB 中大文件的关键组件。1. 先明确:GridFS 是什么?在解释 GridFSBucket 前,需要先了解它依赖的 GridFS:GridFS 是 MongoDB 内置的一种 大文件存储规范(非数据库),专门用于存储超过 MongoDB 单个文档上限(默认 16MB)的文件,比如图片、视频、PDF 等。它的核心逻辑是:将大文件拆分成多个 256KB 的小分片(chunk) 存储在 fs.chunks 集合中,同时将文件的元数据(文件名、大小、类型等)存储在 fs.files 集合中,通过关联两个集合实现文件的完整管理。2. GridFSBucket 的核心作用GridFSBucket 是操作 GridFS 的“入口类”,封装了与 GridFS 交互的底层细节,核心作用有 4 点:(1)上传文件到 GridFS直接将文件(输入流、字节数组等)写入 GridFS,自动完成分片拆分和元数据存储,无需手动处理 fs.chunks 和 fs.files 集合。示例代码(上传文件并指定元数据):// 通过输入流上传文件,设置文件名、内容类型try (InputStream inputStream = new FileInputStream("test.jpg")) {    GridFSUploadOptions options = new GridFSUploadOptions()        .metadata(new Document("author", "test").append("type", "carousel")); // 自定义元数据    // 上传文件,返回文件在 GridFS 中的唯一标识(ObjectId)    ObjectId fileId = gridFSBucket.uploadFromStream("轮播图1.jpg", inputStream, options);} catch (IOException e) {    e.printStackTrace();}(2)从 GridFS 下载文件根据文件的唯一标识(ObjectId)或文件名,获取文件的输入流,进而实现文件下载(保存到本地、返回给前端等)。示例代码(根据 ObjectId 下载文件):// 目标文件的 ObjectIdObjectId fileId = new ObjectId("60d21b4667d0d8992e610c85");// 下载文件到输出流(如本地文件)try (OutputStream outputStream = new FileOutputStream("download.jpg")) {    gridFSBucket.downloadToStream(fileId, outputStream);} catch (IOException e) {    e.printStackTrace();}(3)删除 GridFS 中的文件根据 ObjectId 或文件名删除 GridFS 中的文件,会自动同时删除 fs.files 中的元数据和 fs.chunks 中的所有分片,避免数据残留。示例代码:// 根据 ObjectId 删除文件ObjectId fileId = new ObjectId("60d21b4667d0d8992e610c85");gridFSBucket.delete(fileId);// 也可根据文件名删除(若有重名文件,会删除所有匹配的文件)// gridFSBucket.delete(new BsonDocument("filename", new BsonString("轮播图1.jpg")));(4)管理文件元数据查询或修改文件的元数据(如文件名、内容类型、自定义属性等),元数据存储在 fs.files 集合中,可通过 GridFSBucket 关联查询。示例代码(查询文件元数据):// 根据 ObjectId 查询文件元数据(GridFSFile 包含文件名、大小、类型等信息)GridFSFile gridFSFile = gridFSBucket.find(new BsonDocument("_id", new BsonObjectId(fileId))).first();if (gridFSFile != null) {    String filename = gridFSFile.getFilename(); // 获取文件名    long fileSize = gridFSFile.getLength();     // 获取文件大小    Document metadata = gridFSFile.getMetadata(); // 获取自定义元数据}3. GridFSBucket 与 GridFSTemplate 的区别在 Spring 项目中,你可能还接触过 GridFSTemplate,它和 GridFSBucket 的核心区别是 封装层级不同:对比维度    GridFSBucket    GridFSTemplate所属框架    MongoDB 官方 Java 驱动    Spring Data MongoDB(基于官方驱动封装)定位    底层操作类,更贴近 MongoDB 原生 API    高层模板类,符合 Spring 风格使用场景    需精细控制文件操作(如自定义分片大小)    快速集成 Spring 项目,简化代码依赖注入    需手动创建(需传入 MongoDatabase)    可直接通过 @Autowired 注入简单说:GridFSBucket 是“原生工具”,GridFSTemplate 是 Spring 对它的“包装增强”,二者最终都作用于 GridFS,但 GridFSTemplate 更适配 Spring 项目的开发习惯。4. 如何创建 GridFSBucket?GridFSBucket 需要基于 MongoDB 的数据库实例(MongoDatabase)创建,示例代码:// 1. 获取 MongoDB 客户端(MongoClient)MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017");// 2. 获取目标数据库(如 "cms_db")MongoDatabase database = mongoClient.getDatabase("cms_db");// 3. 创建 GridFSBucket(参数2:存储桶名称,默认 "fs",可自定义区分不同文件类型)GridFSBucket gridFSBucket = GridFSBuckets.create(database, "carousel_files");在 Spring 项目中,也可通过配置类将 GridFSBucket 注册为 Bean,方便全局注入使用(就像之前解决 GridFSBucket 缺失时的配置)。总结:GridFSBucket 是操作 MongoDB GridFS 的核心入口,负责大文件的上传、下载、删除和元数据管理,是 MongoDB 大文件存储场景中不可或缺的组件。
  • [技术干货] springboot连接mongodb的多种写法
    uri: mongodb://jack:123456@localhost://27017/MongoDB 配置存在语法错误(uri 中多了一个 //),正确的配置格式有多种写法,可根据需要选择:1. 标准 URI 完整写法(推荐)明确指定数据库名和认证信息,修复后的正确格式:spring: data: mongodb: # 格式:mongodb://用户名:密码@主机:端口/数据库名?认证参数 uri: mongodb://jack:123456@localhost:27017/yh_cms?authSource=adminauthSource=admin:指定认证数据库(默认是要连接的数据库,若账号在 admin 库创建必须加此参数)2. 拆分参数写法(更清晰)将 URI 拆分为多个独立参数,适合复杂配置:spring: data: mongodb: host: localhost # 主机地址 port: 27017 # 端口(默认27017可省略) database: yh_cms # 数据库名 username: jack # 用户名 password: 123456 # 密码 authentication-database: admin # 认证数据库(可选,默认同database)3. 带集群和额外参数的写法(多节点场景)若连接 MongoDB 集群或需要指定读写偏好:spring: data: mongodb: uri: mongodb://jack:123456@host1:27017,host2:27017/yh_cms?authSource=admin&readPreference=primaryPreferred多节点用逗号分隔readPreference=primaryPreferred:优先从主节点读取注意事项原配置中 uri: mongodb://jack:123456@localhost://27017 错误在于 localhost://27017,正确应为 localhost:27017(单冒号)若 MongoDB 未启用认证,可省略用户名密码:uri: mongodb://localhost:27017/yh_cms生产环境建议添加 maxPoolSize 等连接池参数:&maxPoolSize=50根据你的场景选择合适的写法即可,拆分参数写法更易维护,URI 写法更简洁。
  • [技术干货] MongoDB入门教程:从零开始掌握现代文档数据库
    MongoDB入门教程:从零开始掌握现代文档数据库作为最流行的NoSQL数据库之一,MongoDB凭借其灵活的文档模型、水平扩展能力和丰富的查询功能,已成为全栈开发中不可或缺的组件。本文将通过实战案例,带您快速掌握MongoDB的核心概念与开发技巧。一、环境搭建:3种主流部署方式1. 本地开发环境(Ubuntu示例)# 添加MongoDB官方PPA wget -qO -| sudo apt-key add - echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list sudo apt update # 安装社区版MongoDB sudo apt install mongodb-community-server # 启动服务并验证 sudo systemctl start mongod mongo --eval "db.runCommand({ connectionStatus: 1 })" # 返回ok:1即成功 2. Docker容器化部署(推荐生产环境)# 单节点部署 docker run --name my-mongo -p 27017:27017 \ -e MONGO_INITDB_ROOT_USERNAME=admin \ -e MONGO_INITDB_ROOT_PASSWORD=secret \ -v /data/mongo:/data/db \ -d mongo:6.0 # 使用MongoDB Compass连接(GUI工具) # 地址: mongodb://admin:secret@localhost:27017 3. Atlas云服务(全球分布式集群)注册[MongoDB Atlas]账号创建免费M0集群(支持512MB存储)获取连接字符串:mongodb+srv://<username>:<password>@cluster0.example.mongodb.net/?retryWrites=true&w=majority二、核心概念对比表(关系型 vs MongoDB)关系型数据库MongoDB对应概念说明DatabaseDatabase数据库实例TableCollection文档集合(无固定模式)RowDocumentJSON/BSON格式数据ColumnField动态字段Primary Key_id (ObjectId)默认12字节唯一标识符Join$lookup/嵌入式文档关联查询方式IndexIndex支持单字段、复合、多键索引三、CRUD操作实战1. 数据库与集合操作// 切换/创建数据库(自动创建) use ecommerce // 创建集合(隐式创建) db.createCollection("products") // 查看所有集合 show collections // 删除集合 db.products.drop() 2. 文档操作(增删改查)// 插入文档 db.products.insertOne({ name: "MacBook Pro 16\"", price: 2499.99, specs: { cpu: "M2 Pro", memory: "32GB", storage: "1TB SSD" }, tags: ["laptop", "apple", "pro"], createdAt: new Date() }) // 批量插入 db.products.insertMany([ { name: "iPhone 14 Pro", price: 999.99 }, { name: "AirPods Pro", price: 249.99 } ]) // 查询文档 db.products.find({ price: { $gt: 500 } }) // 价格大于500 db.products.findOne({ "specs.memory": "32GB" }) // 嵌套查询 // 更新文档 db.products.updateOne( { name: "MacBook Pro 16\"" }, { $set: { price: 2399.99 }, $inc: { stock: 10 } } // 多操作符组合 ) // 删除文档 db.products.deleteOne({ name: "AirPods Pro" }) 3. 高级查询技巧// 分页查询 db.products.find().skip(10).limit(5) // 跳过10条,取5条 // 排序 db.products.find().sort({ price: -1, name: 1 }) // 价格降序,名称升序 // 聚合管道(数据分析) db.orders.aggregate([ { $match: { status: "completed" } }, // 筛选条件 { $group: { _id: "$customerId", total: { $sum: "$amount" }, count: { $sum: 1 } } }, { $sort: { total: -1 } }, { $limit: 5 } ]) 四、数据建模实战案例1. 电商系统建模// 用户集合 db.users.insertOne({ _id: ObjectId("507f1f77bcf86cd799439011"), username: "john_doe", email: "john@example.com", addresses: [ { type: "shipping", street: "123 Main St", city: "New York" }, { type: "billing", street: "123 Main St", city: "New York" } ], paymentMethods: [ { type: "credit_card", cardNumber: "**** **** **** 1234", expiry: "12/25" } ] }) // 订单集合(引用用户ID) db.orders.insertOne({ userId: ObjectId("507f1f77bcf86cd799439011"), items: [ { productId: ObjectId("507f1f77bcf86cd799439012"), quantity: 2 }, { productId: ObjectId("507f1f77bcf86cd799439013"), quantity: 1 } ], status: "shipped", shippingAddress: { street: "123 Main St", city: "New York" } }) 2. 模式设计原则嵌入式 vs 引用式:嵌入式:适合1:1或1:少量关系(如用户地址)引用式:适合1:多或频繁独立查询的关系(如订单与产品)反规范化策略:// 预聚合评论评分(减少查询次数) db.products.updateOne( { _id: productId }, { $inc: { "reviewStats.total": 1, "reviewStats.score": newRating }, $set: { "reviewStats.avg": (db.products.findOne({_id: productId}).reviewStats.total * db.products.findOne({_id: productId}).reviewStats.avg + newRating) / (db.products.findOne({_id: productId}).reviewStats.total + 1) } } ) 五、性能优化指南1. 索引策略// 创建单字段索引 db.products.createIndex({ name: 1 }) // 1升序,-1降序 // 创建复合索引 db.orders.createIndex({ userId: 1, status: 1 }) // 创建TTL索引(自动过期) db.sessions.createIndex({ lastAccess: 1 }, { expireAfterSeconds: 3600 }) // 查看索引 db.products.getIndexes() // 索引分析 explain("executionStats") // 查询执行计划 2. 查询优化技巧避免全集合扫描:确保查询使用索引使用投影减少数据传输:db.products.find({}, { name: 1, price: 1, _id: 0 }) 批量操作替代循环查询:// 不推荐(N+1查询问题) orders.forEach(order => { const product = db.products.findOne({_id: order.productId}); // ... }); // 推荐(使用$in批量查询) const productIds = orders.map(o => o.productId); const products = db.products.find({_id: {$in: productIds}}).toArray(); 3. 分片集群配置# mongod.conf 分片节点配置 sharding: clusterRole: shardsvr replication: replSetName: "rs0" net: bindIp: 0.0.0.0 port: 27017 # 初始化副本集 rs.initiate({ _id: "rs0", members: [ { _id: 0, host: "mongo1:27017" }, { _id: 1, host: "mongo2:27017" }, { _id: 2, host: "mongo3:27017", arbiterOnly: true } ] }) # 配置分片键(在mongos上执行) sh.enableSharding("ecommerce") sh.shardCollection("ecommerce.orders", { customerId: 1 })六、安全与监控1. 安全配置清单// 启用认证 security: authorization: enabled // 创建管理员用户 use admin db.createUser({ user: "siteAdmin", pwd: "securePassword", roles: ["root"] }) // 创建应用用户(最小权限原则) use ecommerce db.createUser({ user: "appUser", pwd: "appPassword", roles: [ { role: "readWrite", db: "ecommerce" }, { role: "read", db: "reporting" } ] }) 2. 监控关键指标慢查询日志:operationProfiling: mode: slowOp slowOpThresholdMs: 100 Prometheus监控配置:# 使用mongodb_exporter docker run -d --name mongo-exporter \ -p 9216:9216 \ percona/mongodb_exporter:0.31 \ --mongodb.uri=mongodb://admin:secret@mongo:27017关键监控项:connections.current:当前连接数opcounters.query:每秒查询数indexCounters.btree.misses:索引未命中次数wt.cache.bytes.read.into:WiredTiger缓存读取量七、常见问题解决方案1. 连接池配置(Node.js示例)const { MongoClient } = require('mongodb'); const uri = "mongodb+srv://appUser:appPassword@cluster0.example.mongodb.net"; const client = new MongoClient(uri, { connectTimeoutMS: 5000, socketTimeoutMS: 45000, maxPoolSize: 50, // 最大连接数 minPoolSize: 10, // 最小连接数 waitQueueTimeoutMS: 10000 // 等待队列超时 }); async function run() { try { await client.connect(); const database = client.db("ecommerce"); const products = database.collection("products"); // 执行查询... } finally { await client.close(); } } run().catch(console.error); 2. 事务处理(跨文档原子操作)const session = client.startSession(); try { session.startTransaction({ readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } }); const accounts = client.db("bank").collection("accounts"); await accounts.updateOne( { _id: fromAccount }, { $inc: { balance: -amount } }, { session } ); await accounts.updateOne( { _id: toAccount }, { $inc: { balance: amount } }, { session } ); await session.commitTransaction(); } catch (error) { await session.abortTransaction(); throw error; } finally { session.endSession(); } 结语MongoDB的灵活性使其成为现代应用开发的理想选择,但同时也要求开发者具备更强的数据建模能力。建议从以下方向深入学习:变更流(Change Stream):实现实时数据同步Timeseries集合:物联网/监控场景优化Atlas Search:全文检索功能MongoDB Charts:内置可视化工具掌握MongoDB不仅是掌握一个数据库,更是获得了一种以文档为中心的数据思维。立即开始您的MongoDB实战之旅,构建可扩展的现代应用!