本文记录在部署 MongoDB 复制集时遇到的一些小坑和解决方法。
docker 环境下 ip 设置错误导致无法访问 在第一次部署 MongoDB 时,为了方便而选择了使用 docker 容器进行部署。部署过程中完全依照官方的教程 ,但是最终部署的集群却无法在 docker 网络外以副本集模式访问。在调试过程中发现在 docker 网络内部可以进行访问,因此猜测可能是 DNS 或者监听的问题。
最终定位到问题在于初始化时选择的 host 错误。官方教程在初始化时,使用的命令如下:
1 2 3 4 5 6 7 8 9 10 rs.initiate ( { _id : "rs0" , members : [ { _id : 0 , host : "mongodb0.example.net:27017" }, { _id : 1 , host : "mongodb1.example.net:27017" }, { _id : 2 , host : "mongodb2.example.net:27017" } ] })
官方的教程在部署过程中直接使用了 container name 作为 MongoDB 实例的 HostName,由于所有的副本集是部署在同一个 docker 网络中,所以可以通过 docker DNS 功能来实现服务发现。而在 docker 网络外部,无法使用 docker DNS 服务,因此不能够正确地访问集群。
经过修改后,将集群初始化命令修改为以下形式,可以正常访问:
1 2 3 4 5 6 7 8 9 10 11 rs.initiate ( { _id : "rs0" , members : [ { _id : 0 , host : "宿主机ip:port" }, { _id : 1 , host : "宿主机ip:port" }, { _id : 2 , host : "宿主机ip:port" } ] })
宿主机 ip 变更,集群失效 上述部署方式,虽然解决了容器外部访问的问题,但是在一次网关配置的修改后,集群所在的宿主机 ip 发生了变化,导致之前部署的 ip 无法访问,需要修改集群的配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 rs.reconfig ( { _id : "rs0" , members : [ { _id : 0 , host : "mongodb0.example.net:27017" }, { _id : 1 , host : "mongodb1.example.net:27017" }, { _id : 2 , host : "mongodb2.example.net:27017" } ] }) rs.reconfig ( { _id : "rs0" , members : [ { _id : 0 , host : "mongodb0.example.net:27017" }, { _id : 1 , host : "mongodb1.example.net:27017" }, { _id : 2 , host : "mongodb2.example.net:27017" } ] },{force :true })
最好的部署方式还是在网关处部署一个 DNS 服务,用于集群的域名管理。
网络吞吐量过大,查询不稳定 由于在部署中利用了 MongoDB Gridfs 功能作为基础架构作为深度学习的标记、训练、测试的数据集来源,在我们的使用场景中,经常会需要从 MongoDB 集群中批量访问 500 张以上 15M 左右的图像。在最初的本地测试中,我测试了批量从 MongoDB 中读取 1000 张图像,所以运行速度一直非常稳定,保持在一张图像 150ms 左右的速度,这对我们来说是比较满意的性能。
但是将 MongoDB 集群投入到使用中,我们发现对图像的获取速度非常不稳定,有时获取一张图像只需要 200ms 左右,有时获取一张图像却需要 3~4 s。大部分情况下获取一张图像需要 1s 左右,而且 MongoDB 性能的波动非常严重,不符合我们最初的测试效果。
最初猜测是由于 MongoDB 中数据存储不合理,导致数据集查询较慢。但查询 MongoDB 的慢查询日志后,发现所有的查询操作均不是慢查询操作。通过 top 命令查询 MongoDB 部署的主机进行监控,发现在查询过程中,CPU 的占用率一直在 20%左右。正在一筹莫展时,突然发现主机的网卡占用率非常高,猜测是网络的问题。
利用 wireshark 抓包后,发现在查询过程中有大量 TCP 重传,可能是由于网络阻塞比较严重。经过排查后,发现是实验室的网关性能过差。
最终,更换了实验室网关,并且将需要批量查询图像的主机通过网线直接与 MongoDB 部署主机相连,最终批量查询的时间稳定在 200ms 左右。