内存数据库与基于磁盘的NoSQL数据库的关键性能优势是什么?

时间:2018-02-13 00:53:04

标签: database mongodb performance redis in-memory-database

阅读设计数据密集型应用程序书,我遇到了这样的说法:

  

与直觉相反,内存数据库的性能优势并不是因为它们不需要从磁盘读取。如果你有足够的内存,即使是基于磁盘的存储引擎也可能永远不需要从磁盘读取,因为操作系统无论如何都会将最近使用过的磁盘块缓存在内存中。相反,它们可以更快,因为它们可以避免以可写入磁盘的形式编码内存数据结构的开销。 OLTP Through the Looking Glass, and What We Found There

所以我的问题是:

  1. 鉴于基于磁盘的NoSQL(Mongo DB)被提供与内存数据库(Redis)相同的RAM,它们的性能是否相同?
  2. 如果基于磁盘的数据库使用写回缓存策略并使用具有相同RAM量的异步写入持久存储,该怎么办?这会使它的性能类似于内存数据库吗?
  3. 即使序列化具有如此高的代价(如上面引用中所述),基于磁盘的NoSQL也会与内存数据库的性能相匹配,因为读取繁重的系统会为两个数据库提供相同数量的缓存。
  4. 我对NoSQL世界很陌生,所以如果我错过了什么,请指导我正确的方向 PS:我读过Difference between In memory databases and disk memory database 但它没有解决我的具体问题。

2 个答案:

答案 0 :(得分:1)

我很快测试了你的(1)。这可能太天真了,但它应该给出第一个答案,而这更像是对自己进行测试的鼓励。

插入100,000个键/值对:

Redis的

Redis setting
time: 4.391808
Redis getting: second run
time: 4.129066

MongoDB的

Mongo setting
time: 30.313092
Mongo getting: second run
time: 33.969624

但是:REDIS和MongoDB是非常不同的系统,并不清楚比较两者是否有用。除非您遇到性能问题,否则不要优化性能。

注释

MongoDB以mongod --storageEngine wiredTiger --syncdelay 0 --journalCommitInterval 500 --dbpath /usr/local/var/mongodb启动,机器有32GB RAM(足以将所有数据保存在内存中)。

这是我使用的ruby脚本:

redis = Redis.current
redis.flushall
mongodb = Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'test')
collection = mongodb[:mycollection]
collection.delete_many({})
collection.indexes.create_one(name: 1)

setids = (0..100000).to_a.map {|i| {name: "#plop_#{i}", val: i} }.shuffle
getids = (0..100000).to_a.map {|i| {name: "#plop_#{i}"} }.shuffle

puts "Redis setting"

time do
    x = 0
    setids.each do |i|
        x += i[:val]
        redis.set(i[:name], i[:val])
    end
    fail unless x == (0..100000).sum
end

["first", "second"].each do |run|
    puts "Redis getting: #{run} run"

    time do
        x = 0
        getids.each do |i|
            x += r.get(i[:name]).to_i
        end
        fail unless x == (0..100000).sum
    end
end

puts "Redis setting (hashes)"
redis.flushall
time do
    x = 0
    setids.each do |i|
        x += i[:val]
        redis.hset(i[:name],:val, i[:val])
    end
    fail unless x == (0..100000).sum
end


["first", "second"].each do |run|
    puts "Redis getting (hashes): #{run} run"
    time do
        x = 0
        getids.each do |i|
            x += redis.hget(i[:name], :val).to_i
        end
        fail unless x == (0..100000).sum
    end
end

puts "Mongo setting"
time do
    x = 0
    setids.each do |i|
        x += i[:val]
        collection.insert_one(i)
    end
    fail unless x == (0..100000).sum
end

["first", "second"].each do |run|
    puts "Mongo getting: #{run} run"

    time do
        x = 0
        getids.each do |i|
            x += collection.find(i).first[:val]
        end
        fail unless x == (0..100000).sum
    end
end

def time
    start = Time.now
    yield
    puts "time: #{Time.now - start}"
end

答案 1 :(得分:1)

完全披露:我代表eXtremeDB的供应商,eXtremeDB是第一个内存数据库系统之一(2001年首次发布)。

  1. 鉴于基于磁盘的NoSQL(Mongo DB)的数量相同 RAM作为内存数据库(Redis),他们将执行关于 相同?
  2. 没有。他们是非常不同的DBMS,Matt的答案证明了这一点。

    1. 如果基于磁盘的数据库使用回写缓存策略怎么办? 异步写入具有相同数量的持久存储 内存。这会使它的性能类似于内存中 数据库?
    2. 再一次,没有。无论是否异步,它仍然是一个系统活动,它将从CPU本身系统中窃取CPU周期。 (我在这里做了一个假设,内存数据库的合理性是性能,因此数据库活动非常激烈。)此外,基于磁盘的内存DBMS处理事务的方式和# 39;原子性是不同的。对于纯内存DBMS,它可以更简单,并且可以针对提交事务的正常情况进行优化。在最好的情况下,我们可以就地更新数据并将之前的映像复制到回滚缓冲区。如果事务提交,我们只是丢弃回滚缓冲区。因此,提交速度非常快,但中止需要更多时间。当您需要在并发访问设置(MVCC)中强制执行READ-COMMITTED时,事情变得更加复杂。

      1. 即使序列化具有如此高的惩罚(如上所述)     以上引用)将基于磁盘的NoSQL匹配性能     内存数据库,用于具有相同数量的读取重系统     缓存给两个数据库。
      2. 没有。任何基于磁盘的DBMS都不会(不能)知道它的数据是完全缓存的。它将始终通过确定所请求页面是否在缓存中的逻辑。这不是免费的(它使用CPU周期)。真正的内存中DBMS没有这样的查找逻辑,并且消除了这种处理。此外,基于磁盘的DBMS使用大页面大小(通常是磁盘阻塞因子的倍数,因此4K,8K,16K等),可以容纳许多记录/行/对象/文档/ ...查找是否有页面无论是否在缓存中,仍然需要在页面上找到特定对象。当然,这并不适用于每个DBMS - 实现细节差别很大。无论如何,内存数据库并不关心磁盘阻塞因素,并且不想浪费在页面上查找对象的周期。我们使用较小的页面大小来消除或大幅减少对象的页内搜索。

        此外,基于磁盘的数据库与内存中DBMS实现索引的方式是(或应该)非常不同。没有详细说明(参见下面的白皮书),最终结果是,与内存数据库相比,b-trees对于具有相同行数的基于磁盘的数据库更深。或者,内存数据库可以一起使用不同类型的索引(t树或散列)。但是,让我们坚持使用b-tree。更深层树的效果是步行树以找到搜索值所需的平均和最差情况级别数更高。最后,一旦找到b树节点(等于数据库页面),就使用二进制搜索来查找页面上的搜索值(插槽)。在4K(或16K,或......)的页面上进行二进制搜索所需的迭代次数比对几百个字节的页面要多得多。同样,这一切都归结为更多的CPU周期。

        还有其他考虑因素。请随时阅读我们的白皮书(免费使用,无需注册)" Will The Real IMDS Please Stand Up?"

        和" In-Memory Database Systems: Myths and Facts"。