资讯详情

资讯详情

CentOS 6 上安装 MongoDB 4.0 的完整指南与踩坑实录

1. 为什么还有人要在 CentOS 6.X 上装 MongoDB 4.0先把话说在前头CentOS 6 早就停止维护了MongoDB 4.0 也已经是老版本。但现实情况是不少企业内部的老业务系统还跑在 CentOS 6.9 或 6.10 上机房里的物理机、虚拟机、甚至某些专用设备配套的管理系统短期内根本没法迁移。这时候如果业务方提出来要存一些文档型数据用 MongoDB 吧你就得硬着头皮在 CentOS 6 上把 MongoDB 4.0 装起来。这个组合有几个天然的矛盾点必须先讲清楚否则后面踩坑会踩到怀疑人生glibc 版本问题MongoDB 4.0 官方编译时依赖的 glibc 版本比 CentOS 6 自带的 2.12 要高。CentOS 6 的 glibc 是 2.12而 MongoDB 4.0 的官方二进制包是在较新的系统上编译的直接跑大概率会报GLIBC_2.14 not found之类的错误。OpenSSL 版本问题CentOS 6 自带 OpenSSL 1.0.1eMongoDB 4.0 的某些构建版本需要 1.0.1e 以上或 1.1.x具体取决于你拿到的包。systemd 缺失CentOS 6 用的是 SysV initservice/chkconfig没有 systemd。而 MongoDB 官方从 3.x 后期开始提供的服务管理脚本很多是面向 systemd 的直接照搬会失败。libcurl 与依赖链MongoDB 4.0 的 shellmongo和 server 都依赖 libcurlCentOS 6 自带的 libcurl 版本偏老可能需要额外处理。所以这篇文章的核心不是复制粘贴几条命令而是把在 CentOS 6 这种老平台上跑起一个相对新的 MongoDB 4.0这件事讲透包括版本选型、依赖处理、服务脚本改造、以及 CentOS 7 上的差异对照。如果你手上是 CentOS 7大部分步骤可以直接用我会在关键位置标注差异。适合谁看手里有 CentOS 6 老机器、需要快速搭一个 MongoDB 做验证或小规模生产、又不想折腾编译源码的运维和开发同学。如果你追求的是最新特性或者大规模集群那这篇文章的场景可能不适合你建议直接上容器化方案。2. 安装前的版本选型与依赖盘点2.1 到底该选哪个 MongoDB 4.0.x 小版本MongoDB 4.0 系列从 4.0.0 一直更新到 4.0.28 左右。在 CentOS 6 上我的建议是优先选 4.0 系列里较晚的小版本比如 4.0.27 或 4.0.28。原因很直接早期 4.0.x 在旧内核和旧 glibc 上的兼容性 bug 更多后期小版本修了不少崩溃和内存相关问题。但这里有个反直觉的点不是越新越好。如果你拿到的二进制包是在 glibc 2.17 环境编译的那在 CentOS 6 上照样跑不起来。所以选版本之前先确认你手上的包是在什么环境下构建的。最稳妥的做法是找那些明确标注支持 RHEL/CentOS 6 的构建或者干脆用源码编译后面会讲。一个实用的判断方法解压二进制包后用ldd看依赖ldd /usr/local/mongodb/bin/mongod | grep -i not found如果输出里出现libc.so.6 /lib64/libc.so.6但伴随版本符号错误那就是 glibc 不匹配。如果只是缺某个.so文件那补装对应的库就行。2.2 CentOS 6 上必须先补齐的系统依赖在动手装 MongoDB 之前先把系统层面的依赖理一遍。CentOS 6 的最小化安装缺的东西不少下面这些建议一次性装齐yum install -y epel-release yum install -y libcurl openssl openssl-devel libaio \ net-snmp cyrus-sasl cyrus-sasl-devel \ gcc gcc-c make wget tar逐个说下为什么libcurlmongo shell 和 mongod 的某些网络功能依赖它缺了会报error while loading shared libraries: libcurl.so.4。opensslMongoDB 4.0 支持 TLS即使你暂时不用加密连接二进制本身也链接了 OpenSSL。libaio异步 IO 库MongoDB 的存储引擎 WiredTiger 会用到。cyrus-sasl如果启用认证SCRAM-SHA-1/256底层会用到 SASL 相关库。gcc/make如果你走源码编译路线这两个是必须的。注意CentOS 6 的 yum 源很多已经失效或迁移如果yum install报 404需要先把/etc/yum.repos.d/下的 repo 地址换成 vault 归档地址否则连基础依赖都装不上。这一步是很多人在老机器上翻车的第一个坑。2.3 glibc 版本冲突的两种处理思路这是 CentOS 6 装 MongoDB 4.0 最核心的难点。CentOS 6 的 glibc 是 2.12而 MongoDB 4.0 官方包通常需要 2.14 或更高。处理思路有两条思路一升级 glibc不推荐。网上有些教程教你手动编译 glibc 2.14 或 2.17 覆盖系统自带的。我强烈不建议在 CentOS 6 上这么干因为 glibc 是系统最底层的库一旦升级出问题ls、cp这些基础命令都可能挂掉整台机器直接废掉。除非这是台可以随时重装的测试机否则别碰。思路二源码编译 MongoDB推荐。在 CentOS 6 本机编译编译出来的二进制自然链接本机的 glibc 2.12兼容性最好。代价是编译时间长老机器上可能一两个小时而且需要装 Python、scons 等构建工具。MongoDB 4.0 用的是 Python 2.7 加 scons 构建系统CentOS 6 自带 Python 2.6需要额外装 Python 2.7。思路三找第三方兼容构建。有些社区或内部团队会提供针对老系统编译好的包如果你能拿到直接用最省事。但要注意来源可信度生产环境别随便用不明来源的二进制。我个人在测试环境用过思路二生产环境如果实在没法迁移会优先推动业务方换机器或上容器。毕竟在 EOL 系统上跑数据库本身就是个风险点。3. 二进制包安装的完整操作链路3.1 下载与解压的正确姿势假设你已经拿到了一个能在 CentOS 6 上跑的 MongoDB 4.0 二进制包tgz 格式。标准流程如下cd /usr/local wget https://example.com/mongodb-linux-x86_64-4.0.28.tgz tar -zxvf mongodb-linux-x86_64-4.0.28.tgz mv mongodb-linux-x86_64-4.0.28 mongodb解压后目录结构大致是/usr/local/mongodb/ ├── bin/ │ ├── mongod │ ├── mongo │ ├── mongos │ └── ... └── LICENSE-Community.txt把 bin 目录加到 PATH 里方便后续操作echo export PATH/usr/local/mongodb/bin:$PATH /etc/profile source /etc/profile验证一下能不能跑mongod --version如果这一步就报 glibc 错误说明你拿到的包和系统不兼容回到上一节选型部分重新处理。如果正常输出版本号那恭喜最难的坎过去了。3.2 目录规划与数据盘挂载生产环境千万别把数据目录放在系统盘。MongoDB 的 WiredTiger 引擎对磁盘 IO 比较敏感建议单独挂一块数据盘。假设数据盘挂载在/datamkdir -p /data/mongodb/data mkdir -p /data/mongodb/log mkdir -p /data/mongodb/conf目录职责划分清楚目录用途备注/data/mongodb/data数据文件必须独立磁盘容量按业务预估/data/mongodb/log日志文件建议单独分区避免日志写满影响数据/data/mongodb/conf配置文件存放 mongod.conf/data/mongodb/keyfile认证密钥文件启用副本集认证时用权限方面如果不用 root 跑 MongoDB强烈建议不用 root需要先建专用用户groupadd mongodb useradd -g mongodb -s /sbin/nologin mongodb chown -R mongodb:mongodb /data/mongodb提示CentOS 6 上useradd的-s /sbin/nologin是标准做法禁止 MongoDB 进程用户登录系统减少安全面。3.3 配置文件 mongod.conf 的关键参数MongoDB 4.0 支持 YAML 格式的配置文件比命令行参数清晰得多。一个适合 CentOS 6 小规模部署的配置示例systemLog: destination: file path: /data/mongodb/log/mongod.log logAppend: true storage: dbPath: /data/mongodb/data journal: enabled: true wiredTiger: engineConfig: cacheSizeGB: 2 net: port: 27017 bindIp: 127.0.0.1 processManagement: fork: true pidFilePath: /data/mongodb/mongod.pid operationProfiling: slowOpThresholdMs: 100几个参数值得展开说cacheSizeGBWiredTiger 的缓存大小。经验值是物理内存的 50% 左右但如果你这台机器还跑别的服务要留够余量。比如 8G 内存的机器给 2-3G 比较稳妥。设太大容易触发 OOM设太小则频繁刷盘影响性能。bindIp默认只监听本地。如果业务在其他机器上需要改成0.0.0.0或具体网卡 IP。但改之前想清楚安全策略别裸奔在公网上。journal4.0 默认开启别关。关了虽然写入快一点但断电后数据可能损坏得不偿失。slowOpThresholdMs慢查询阈值100ms 是个常用起点方便后续排查性能问题。3.4 启动与首次连接验证配置文件写好后启动命令很简单mongod -f /data/mongodb/conf/mongod.conffork: true会让它后台运行。检查是否起来ps -ef | grep mongod tail -f /data/mongodb/log/mongod.log日志里看到waiting for connections on port 27017就说明启动成功了。然后用 mongo shell 连上去mongo --host 127.0.0.1 --port 27017进去之后跑几个基础命令验证db.version() db.stats() show dbs如果db.version()返回 4.0.x那整个安装链路就通了。4. CentOS 6 服务脚本改造与开机自启4.1 为什么不能直接用官方 systemd 脚本MongoDB 官方文档里给的服务管理方式基本是 systemd 的systemctl start mongod。但 CentOS 6 根本没有 systemd你敲systemctl会提示 command not found。所以必须自己写一个 SysV init 脚本放到/etc/init.d/下然后用service和chkconfig管理。这是 CentOS 6 和 CentOS 7 在部署上最大的差异点。如果你在 CentOS 7 上直接用官方 systemd unit 文件即可不用看这一节。4.2 手写一个可用的 init 脚本下面这个脚本是我在实际环境中用过的精简但功能完整#!/bin/bash # chkconfig: 2345 80 10 # description: MongoDB 4.0 init script MONGOD/usr/local/mongodb/bin/mongod CONF/data/mongodb/conf/mongod.conf PIDFILE/data/mongodb/mongod.pid USERmongodb start() { if [ -f $PIDFILE ]; then echo MongoDB already running return 1 fi su - $USER -c $MONGOD -f $CONF echo MongoDB started } stop() { if [ ! -f $PIDFILE ]; then echo MongoDB not running return 1 fi PID$(cat $PIDFILE) kill $PID while kill -0 $PID 2/dev/null; do sleep 1 done echo MongoDB stopped } case $1 in start) start ;; stop) stop ;; restart) stop; sleep 2; start ;; status) if [ -f $PIDFILE ]; then echo MongoDB is running, PID$(cat $PIDFILE) else echo MongoDB is stopped fi ;; *) echo Usage: $0 {start|stop|restart|status} exit 1 ;; esac几个关键点解释chkconfig 那两行注释不能少# chkconfig: 2345 80 10定义了在哪些运行级别启动、启动优先级 80、关闭优先级 10。没有这行chkconfig --add会失败。用 su 切换用户因为前面建了 mongodb 专用用户启动时切过去保证数据文件属主正确。stop 用 kill 而非 kill -9先发 SIGTERM 让 MongoDB 优雅关闭等进程真正退出。直接 kill -9 可能导致数据文件损坏。给脚本加执行权限并注册chmod x /etc/init.d/mongod chkconfig --add mongod chkconfig mongod on之后就能用service mongod start/stop/restart/status管理了。4.3 开机自启验证与常见失败原因注册完之后别急着信实际验证一遍service mongod stop chkconfig --list mongod reboot重启后登录service mongod status看是否自动起来了。常见的自启失败原因有几个PID 文件路径不对脚本里写的 PIDFILE 必须和 mongod.conf 里的pidFilePath一致否则 stop 和 status 都会失效。权限问题mongodb 用户对 data、log 目录没有写权限启动会失败。用chown -R再确认一遍。环境变量缺失init 脚本执行时的环境和你登录 shell 不一样PATH 可能不含 mongodb/bin。所以脚本里最好用绝对路径调用 mongod。依赖服务未就绪如果数据盘是网络存储开机时挂载可能晚于 MongoDB 启动导致 dbPath 不存在。这种情况需要在脚本里加等待逻辑或者调整 chkconfig 优先级。5. 认证、副本集与 CentOS 7 的差异对照5.1 开启认证的正确顺序MongoDB 默认是不开认证的任何人连上就能操作这在生产环境绝对不行。但开启认证有个顺序陷阱必须先创建管理员用户再开启认证否则开了认证之后你连创建用户的权限都没有。正确流程// 1. 先以无认证模式启动连上去 use admin db.createUser({ user: admin, pwd: YourStrongPassword, roles: [{ role: root, db: admin }] }) // 2. 再创建业务库的用户 use myapp db.createUser({ user: appuser, pwd: AppPassword, roles: [{ role: readWrite, db: myapp }] })然后在 mongod.conf 里加上security: authorization: enabled重启 MongoDB之后连接就需要认证了mongo -u admin -p --authenticationDatabase admin注意密码里别用特殊字符导致 shell 解析出问题如果非要用记得加引号或用交互式输入。5.2 单节点副本集的必要性很多人觉得副本集至少要三个节点单机没必要。但 MongoDB 4.0 的某些功能比如事务、Change Stream要求必须是副本集模式哪怕只有一个节点。所以即使是单机部署也建议配成单节点副本集。配置方法是在 mongod.conf 里加replication: replSetName: rs0重启后连上去初始化rs.initiate()等几秒rs.status()看到自己是 PRIMARY 就成功了。这样后续如果业务需要事务直接就能用不用再改架构。5.3 CentOS 7 上的操作差异清单如果你手上是 CentOS 7大部分内容通用但以下几点不同项目CentOS 6CentOS 7服务管理SysV init service/chkconfigsystemd systemctlglibc 版本2.12需特殊处理2.17官方包直接可用防火墙iptablesfirewalld官方二进制包需找兼容构建或源码编译直接下载官方包即可服务脚本手写 init 脚本用官方 mongod.serviceCentOS 7 上装 MongoDB 4.0 基本就是下载官方包、解压、写配置、systemctl 启动顺畅得多。所以如果你的机器能升级到 CentOS 7强烈建议升级能省掉本文一半的折腾。防火墙方面CentOS 6 用 iptables 放行端口iptables -I INPUT -p tcp --dport 27017 -j ACCEPT service iptables saveCentOS 7 则是firewall-cmd --permanent --add-port27017/tcp firewall-cmd --reload6. 老平台上的性能调优与踩坑实录6.1 内核参数与文件句柄调整CentOS 6 默认的文件句柄数和内核参数对 MongoDB 来说偏保守需要调整。编辑/etc/security/limits.confmongodb soft nofile 64000 mongodb hard nofile 64000 mongodb soft nproc 64000 mongodb hard nproc 64000内核参数方面/etc/sysctl.conf加vm.swappiness 1 vm.dirty_ratio 15 vm.dirty_background_ratio 5 net.core.somaxconn 4096vm.swappiness 1是让系统尽量别把 MongoDB 的内存换到 swap数据库最怕 swap。dirty_ratio调低是为了让脏页更早刷盘避免一次性大量写入导致 IO 卡顿。改完执行sysctl -p生效。6.2 我踩过的三个真实坑坑一日志文件把磁盘写满。有次测试环境跑了几天突然 MongoDB 挂了一看日志目录所在分区 100% 满。原因是没配日志轮转mongod.log 一直涨。解决办法是用 logrotate或者至少在 mongod.conf 里配合logAppend加外部轮转脚本。CentOS 6 自带 logrotate加个配置/data/mongodb/log/mongod.log { daily rotate 7 compress missingok notifempty copytruncate }copytruncate很关键因为 MongoDB 不会自己重新打开日志文件用 copytruncate 可以避免重启。坑二glibc 报错但信息误导。有次拿到的包报version GLIBC_2.14 not found我一开始以为是缺库装了一堆东西没用。后来才明白是编译环境版本高于运行环境只能换包或源码编译。这个错误的迷惑性在于它看起来像缺文件实际是版本不够。坑三副本集初始化卡住。单节点rs.initiate()之后一直不是 PRIMARY查日志发现是主机名解析问题。CentOS 6 的/etc/hosts里没配本机主机名MongoDB 解析不了自己的地址。加上127.0.0.1 主机名就好了。这个坑在老机器上特别常见因为很多机器主机名是随手设的hosts 文件没同步。6.3 监控与日常维护建议老平台上的 MongoDB监控尤其重要因为系统本身就不稳定。几个必看的指标连接数db.serverStatus().connections接近上限就要警惕。慢查询开了 profiling 后db.system.profile.find().sort({ts:-1}).limit(10)看最近的慢操作。WiredTiger 缓存使用率db.serverStatus().wiredTiger.cache如果 bytes currently in the cache 接近 cacheSizeGB说明缓存吃紧。复制延迟副本集模式下rs.printSlaveReplicationInfo()。备份方面小规模用mongodump就够mongodump --host 127.0.0.1 --port 27017 -u admin -p --authenticationDatabase admin -o /data/backup/$(date %Y%m%d)但要注意mongodump在数据量大时对性能有影响建议在业务低峰期做或者用文件系统快照的方式。我个人在 CentOS 6 上跑 MongoDB 的体会是能跑但每一步都要比新系统多留个心眼。依赖、权限、服务脚本、内核参数任何一环没处理好都可能出问题。如果这台机器承载的是核心业务我会强烈建议推动迁移如果只是过渡或测试那按本文的流程走一遍基本能稳定运行。最后再提醒一句老系统的安全补丁早就停了MongoDB 端口千万别暴露在不可信网络里bindIp 和防火墙规则一定要配好。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →