【发布时间】:2020-04-25 21:22:17
【问题描述】:
我正在为 MongoDB 的“更新”模拟 multiple concurrent request。
事情是这样的,我在mongoDB中插入了一个数据amount=1000,每次触发api时,它都会更新amount += 50的数量并保存回数据库。基本上它是对单个文档的find and update 操作。
err := globalDB.C("bank").Find(bson.M{"account": account}).One(&entry)
if err != nil {
panic(err)
}
wait := Random(1, 100)
time.Sleep(time.Duration(wait) * time.Millisecond)
//step 3: add current balance and update back to database
entry.Amount = entry.Amount + 50.000
err = globalDB.C("bank").UpdateId(entry.ID, &entry)
Here 是项目的源代码。
我正在使用 Vegeta 模拟请求:
如果我设置-rate=10(意思是每秒触发10次api,所以1000 + 50 * 10 = 1500),数据是正确的
echo "GET http://localhost:8000" | \
vegeta attack -rate=10 -connections=1 -duration=1s | \
tee results.bin | \
vegeta report
但是使用-rate=100(这意味着每秒触发 api 100 次,因此 1000 + 50 * 100 = 6000)会产生非常混乱的结果。
echo "GET http://localhost:8000" | \
vegeta attack -rate=100 -connections=1 -duration=1s | \
tee results.bin | \
vegeta report
简而言之,我想知道的是:我以为MongoDB正在使用optimistic concurrency control,这意味着如果有write conflict,它应该再次重试,所以延迟会上升,但数据应该保证是正确的。
为什么结果看起来在 MongoDB 中完全不能保证数据的正确性?
我知道你们中的一些人可能会注意到 41 和 42 行的睡眠,但即使我将其注释掉,当我使用 -rate=500 进行测试时,结果仍然不正确。
任何线索为什么会发生这种情况?
【问题讨论】:
-
哪些操作没有产生预期的结果?将那些从源中提取到问题正文中。
标签: mongodb optimistic-concurrency