mongoimport连续导入多个CSV时,失去连接造成部分数据丢失?


  • 註冊用戶

    我最近在测试mongodb的性能,当我循环用mongoimport向一个collection导入数据时(循环了300次,每次导入的数据大概有44M大小,数据格式很简单,每一条document由8个int组成),发现最后的数据有丢失。

    查看mongoimport的输出,会有错误   Failed: Closed explicitly  或者   Failed: error connecting to db server: no reachable servers 报出。查看mongo的log日志,发现有错误  [conn311] AssertionException handling request, closing client connection: 6 socket exception [SEND_ERROR] for 127.0.0.1:34142 报出。

    看起来是连接的问题,但是我都是在本地进行的单机测试,会有网络问题?

    有人能帮我解决这个问题吗

    ------------------------------------------------------------------------------------

    补充:另外发现一个现象是,当collection的数据量已经比较大的时候,mongoimport会有卡住的情况,就是连续几次都没有进度:


    如图,所以,我还不清楚造成这种阻塞的原因是什么,但是是否可能是这种阻塞导致的连接问题呢?比如超时?

    ————————————————————————————————————————————————————————————————

    可能有几点需要补充一下:

    1、错误发生的时候通常是在循环已经进行了几十次之后,也就是说前面的导入过程都是十分正常的。

    2、在数据导入的过程中,mongo占用的内存是会不断增大的,但是会有一个上限,即增加到某一个值后就基本不变了,错误发生是出现在这之后的,所以是否可能跟系统的内存资源相关?



  • 猜测:连线满了。如果可以启动连接池的方式连线最好。


  • 註冊用戶

    我每次也都打印了db.serverStatus().connections的信息,连接数只有1呀。


  • 註冊用戶

    從錯誤訊息來看.被關掉的連線數有6個

    所以是不是連線沒使用到了但是沒有關閉連線

    每次都開新連線最後造成了.實際連線數只有1.但是有多個連線在waiting最後結果就是連線滿了


  • 註冊用戶

    @neo 难道mongoimport在导入结束后不会自动关闭连接吗?


  • 註冊用戶

    @AJW

    我也不肯定,理論上應該是會的.

    從你的錯誤訊息來看.似乎沒有關閉連線.

    沒有看到你import的程式碼只能從錯誤訊息去猜測,看起來是這樣

    你在每次打印server status之後就強迫關閉連線.每次loop開始時再重啟連線試試看.

    我試了一下.如果程式裡面沒有去關閉連線,連線似乎會被保留一段時間.

    如下圖,我程式已經執行完畢了但連線還在.

    可以檢查一下你import的做法或者等高手解答了


  • 註冊用戶

    @neo 我看了一下,当导入结束后,我的连接都是出于TIME_WAIT状态,这个似乎是TCP连接关闭后的一个正常状态,在等待一段时间后,这些连接就会消失。


    我尝试将mongo配置文件中的maxIncomingConnections改到20,然后同样import了很多次,这些TIME_WAIT连接的存在并没有影响到导入的进行。

    我把我的代码也贴出来,难道是我哪里写错了?

    #Shell Script
    1 #!bin/bash
      2 base_dir=/home/wja/log
      3 du -sh /home/wja/mongo-data > ${base_dir}/datasize.log
      4 :>${base_dir}/runtime.log
      5 :>${base_dir}/dbcount.log
      6 :>${base_dir}/memory.log
      7 
      8 for((i = 0;i < 100;i++))
      9 do
     10         for((j = 0;j<3;j++))
     11         do
     12                 start_time=`date +%s`
     13                 mongoimport --host localhost:27018 -d wja -c test2 --type csv --headerline --file mongoimport_1000000.csv --numInsertionWorkers 4
     14                 end_time=`date +%s`
     15                 echo $[ $i * 3 + $j + 1 ]th time: use $[ $end_time-$start_time ] s >> ${base_dir}/runtime.log
     16                 du -sh /home/wja/mongo-data >> ${base_dir}/datasize.log
     17 #               ps -aux | grep logpath | grep mongod >> ${base_dir}/memory.log
     18 #               netstat -ant | grep 27018 | grep TIME_WAIT >> netstat.log 
     19                 sleep 5
     20                 mongo localhost:27018 --quiet --eval "db=db.getSiblingDB('wja');var n = db.test2.count();var cur = db.serverStatus().connections.current;var mem = db.serverStatus().mem;print(n,cur,mem.resident,mem.mapped,mem.virtual);" >> ${base_dir}/dbcount.log
     21         done    
     22         sleep 10
     23 done
    

  • 註冊用戶

    @AJW 

    如果都是TIME_WAIT而不是ESTABLISHED的話應該就是正常情況

    從程式碼以及你跑的結果來看都很正常。

    至少我看不出來哪邊有問題。

    另外16行.我不確定是你po上來的時候打錯,還是哪應該是正確的

    /home/wja 似乎應該是/hom/ajw

    但應該不影響整個結果

    我也很好奇問題倒底是什麼了


  • Lv 1

    可以查查看系統ulimit的系統資源及連線數是多少


  • 註冊用戶

    @Amber ulimit -n open files是1024。

    所以,又一个奇怪的问题的出现了,明明我同时存在的连接数(包括TIME_WAIT状态下的)已经超过1024了,可是为什么还是能够再建立连接导入数据呢。。。?


  • Lv 1

    @AJW  你先將ulimit -n改大看看,另外ulimit -u是多少呢?


  • 註冊用戶

    @Amber 61992


  • Lv 1

    @AJW 導入連線應該是會排隊,db.serverStatus().connections才會都是1

    如果將程式改成休眠久一點再繼續下一次的mongoimport呢?

    看看是否因為連續寫造成阻塞


  • Lv 1

    @AJW  剛發現程式第二個for迴圈好像有點問題,是否貼錯

    這樣應該不會進到這個迴圈

    for((j = 3;j<1;j++))

  • 註冊用戶

    @Amber

    可以尝试一下

    另外,这么多数据是不是分片会更好一些呢?我还在学习mongo的阶段,所以对这些还不是太了解,现在只是在单机测试。


  • 註冊用戶

    @Amber

    哦,谢谢提醒,应该是我不小心写错



  • @AJW

    把导入的文件内容格式秀出来看一下。



  • @AJW 说:

    mongoimport --host localhost:27018 -d ajw -c test2 --type csv --headerline --file mongoimport_1000000.csv -j 4

     这句的 -j  4  是栏位?如果是,把 --file 改成  --files 试试。


  • 註冊用戶

    @asd

    mongoimport --help 可以看到选项

    -j, --numInsertionWorkers= number of insert operations to run concurrently (defaults to 1)

    我的理解就是会分成4个同时的插入操作来进行,因为我在执行的时候看到,每次会建立4个连接。

    我的数据很简单,就是8个整数,都是我随机生成的。

    类似这样

    a,b,c,d,e,f,g,h   //第一行是每一栏位的名称
    6761,2702,8259,19196,9507,23266,26075,13922
    7326,21114,29716,21027,31034,26999,10542,13969
    30992,3232,32675,17863,17720,4296,18492,27213
    ……


  • @AJW 说:

    -j, --numInsertionWorkers

     --numInsertionWorkers 没问题,但是,-j 是什么意思?j 是变量,内循环的变量。


登录后回复
 

与 萌阔论坛 的连接断开,我们正在尝试重连,请耐心等待