Rails MongoDB驱动程序无法插入而没有错误

时间:2011-05-30 02:09:03

标签: ruby mongodb

我编写了一个简短的Ruby脚本来描述MongoDB,只是为了看看我添加记录时它的磁盘空间是如何增加的。我希望它创建100,000,000条记录,但是在7,000,000之后,插入开始无声地失败。有什么想法吗?这是代码:

#!/usr/bin/env ruby

require 'rubygems'
require 'mongo'

@conn = Mongo::Connection.new
@conn.drop_database('benchmark')
@db = @conn['benchmark']
@reqs = @db['requests']

last_count = 0
last_elapsed = 0
total_elapsed = 0

puts
puts "inserts\tsize\tt_elapsed\tt_per_insert"

print_at = [
    1,
    1000,
    # ...
    7_000_000,
    8_000_000,
    # ...
].inject({}) {|h,x| h[x] = 1; h}

1.upto 100_000_000 do |i|
  req = {'user_id' => i,
         'role_name' => 'user',
         'day' => [2011,5,30],
         'method' => 'get',
         'page' => 'http://www.example.com/users/5/edit',
         'referrer' => 'http://www.example.com/projects/57/notes'}
  t1 = Time.new
  @reqs.insert(req)
  t2 = Time.new
  total_elapsed += t2 - t1
  if print_at[i]
    elapsed_per = (total_elapsed - last_elapsed) / (i - last_count)
    puts "#{i}\t#{@reqs.stats['storageSize']}\t#{total_elapsed}\t#{elapsed_per}\t#{@reqs.count}"
    last_count = i
    last_elapsed = total_elapsed
  end
end

结果如下:

inserts size    t_elapsed   t_per_insert
1   13568   0.000333    0.000333    1
1000    284928  0.440234999999999   0.000440342342342342    1000
5000    4626688 2.399554    0.000489829750000001    5000
10000   4626688 4.04515699999996    0.00032912059999999 10000
50000   18520320    18.3045380000001    0.000356484525000004    50000
100000  35192576    36.1132420000052    0.000356174080000102    100000
250000  79207168    89.8520730000556    0.000358258873333669    250000
500000  142587904   179.141312000645    0.000357156956002356    500000
750000  184073216   262.518961001337    0.00033351059600277 750000
1000000 233855488   347.697380001333    0.000340713675999983    1000000
2000000 554531072   722.684815985293    0.00037498743598396 2000000
3000000 827051520   1122.17787597268    0.000399493059987388    3000000
4000000 1005428224  1468.68356799303    0.000346505692020353    4000000
5000000 1219480064.0    1803.55257001283    0.000334869002019792    5000000
6000000 1476342016.0    2152.29274403266    0.000348740174019833    6000000
7000000 1784576256.0    2497.58802604997    0.000345295282017315    7000000
8000000 1784576256.0    2877.84758905944    0.000380259563009462    7692111

你可以在最后一行看到,在进行8,000,000次保存后,数据库只有7,692,111个条目。

这是一个小环境信息:

$ ruby --version
ruby 1.8.7 (2009-06-12 patchlevel 174) [i486-linux]
$ uname -a
Linux shiny 2.6.31-19-generic #56-Ubuntu SMP Thu Jan 28 01:26:53 UTC 2010 i686 GNU/Linux
$ mongod --version
db version v1.8.1, pdfile version 4.5
Sun May 29 21:58:20 git version: a429cd4f535b2499cc4130b06ff7c26f41c00f04

请注意,运行此测试后我的磁盘仍然有22G空闲,所以我猜这不是问题所在。以下是MongoDB文件:

$ ls -lh /var/lib/mongodb
total 3.0G
-rw------- 1 mongodb nogroup  16M 2011-05-29 17:24 benchmark.0
-rw------- 1 mongodb nogroup  32M 2011-05-29 16:38 benchmark.1
-rw------- 1 mongodb nogroup  64M 2011-05-29 16:36 benchmark.2
-rw------- 1 mongodb nogroup 128M 2011-05-29 16:39 benchmark.3
-rw------- 1 mongodb nogroup 256M 2011-05-29 16:48 benchmark.4
-rw------- 1 mongodb nogroup 512M 2011-05-29 16:58 benchmark.5
-rw------- 1 mongodb nogroup 512M 2011-05-29 17:09 benchmark.6
-rw------- 1 mongodb nogroup 512M 2011-05-29 17:17 benchmark.7
-rw------- 1 mongodb nogroup 512M 2011-05-29 17:24 benchmark.8
-rw------- 1 mongodb nogroup 512M 2011-05-29 17:16 benchmark.9
-rw------- 1 mongodb nogroup  16M 2011-05-29 17:24 benchmark.ns
-rwxr-xr-x 1 mongodb nogroup    6 2011-05-28 15:46 mongod.lock
drwxr-xr-x 2 mongodb nogroup 4.0K 2011-05-29 16:34 _tmp

我想无论插入失败的具体原因如何,我都特别想知道为什么没有引发异常。我理解复制后用户可以在所有节点成功保存数据之前“成功”,但这不应该只是我的笔记本电脑上运行的vanilla实例的问题,对吧?

2 个答案:

答案 0 :(得分:3)

mongo有32位限制。它只允许存储2.5 GB的数据。这是最大尺寸。请查看此link了解详情。

答案 1 :(得分:1)

显然,即使您的数据库只是一台服务器,也不会引发错误。这篇文章似乎是最有用的:

http://www.thebuzzmedia.com/mongodb-single-server-data-durability-guide/

我仍然在弄清楚我的选择的细微差别,但它们有一些变化:

@reqs.insert(req, :safe => true)

使用该新代码,我收到此消息的异常:

10084: can't map file memory - mongo requires 64 bit build for larger datasets (Mongo::OperationFailure)

所以Ramesh是对的!

我必须说我同意那些认为这是一个相当令人震惊的违约的人。我很高兴我现在注意到它,而不是默默地丢弃一个月的分析数据。