MongoExport后的负载均衡问题查询及解决:can't accept new chunks because there are still 2 deletes from previous migration

问题

  前一阵有一个数据导出需求,按照各种数据库的使用方法,使用MongoExport方法导出数据,将数据导出到本地文件系统,在导出之后遇到此问题。

  此问题和mongoexport的原理有关,我们知道数据是hashed或者ranged存放在不同shardsvr上的,那么既然export需要导出到某一个节点的物理文件系统中,那么势必要进行一次数据传输。在mongodb中,这次数据传输是通过migrate实现的,即把所有其他shardsvr上的数据汇总到本地shardsvr中,再进行export。也就是说文件的分布结构从分布式转化为了单机模式,然后export完再慢慢balance回去。这会造成一些问题例如:

  1、migrate之后所有数据都在同一个节点,如果数据大会有文件系统空间问题,例如我们的mongodb存储是放在3块SSD组成的raid5上的,空间较小但是有着较佳的性能。而export目标地址则是8块7200r的SAS硬盘组成的raid50中,本来空间足够,但是数据全都导入到shardsvr上SSD的空间可能不足了。

  2、migrate会占用所有带宽,这个不用讲,坏处大家都懂。

  3、export之后会通过balancer负载均衡回去,balancer传输数据较慢,这次600G数据用了2天时间,在balancer负载均衡完之前spark都不太好用,因为数据不均匀。

  4、中间会有其他原因干扰balancer导致数据不能传输。

  简而言之就是需要进行2轮数据传输,并且还有一次export,即使使用spark把数据扔到单机节点上对单节点的网络压力都没这么大。

先放结论:

  1、mongoexport在sharding集群中并不好用,所以不建议使用mongoexport,如果非要使用建议先用spark导入到一个单机系统再使用。或者直接连接shardsvr上进行export,但是大集群shardsvr比较多所以得通过脚本进行,密码明文存在脚本里有点不符合安全性要求。

  2、nocusortimeout还是别用了,这玩意有点坑,有时程序异常终止或者其他原因会导致client已经不存在了,然而cursor还在,cursor在集群就没法moveChunk或者balance。。

问题解决过程

  a) mongoexport 共运行28小时;

  b) 运行完发现所有数据都被migrate到了export节点上,即数据分布由分布式变为了集中式;

  c) 调研mongoDB负载均衡策略发现理应进行自动负载均衡,查询balancer的enabel和running状态发现为(true、true);

  d) 使用moveChunk操作发现有两个cursor一直被占用;

  e) 调研cursor操作发现现在listCursor已不再被支持,无法查看所有cursor情况,也就无法通过killCursors接口进行kill;

  f) 尝试重启mongos和Mongod发现重启后cursor依旧存在并且会重新开始数据传输?共额外传输了1.5TB数据;

  g) 重启所有服务,负载均衡开始;

  h) 结论:(1)集群中不能使用mongo export;(2)不应使用noCursorTimeOut。如果使用要确定cursor被手动关闭。(3)再出现这类问题依旧没有好的解决办法,还是只能重启。

 

posted @ 2017-12-25 14:48  月影舞华  阅读(788)  评论(0编辑  收藏  举报