在我们的应用程序中,我们正在进行大量的插入/更新(从1k到100k),我注意到并没有保存所有记录.它可以在安全模式关闭的情况下节省90%-95%的记录.
使用safemode执行upsert会成功挂起所有记录但速度太慢.我记得在某处读到即使安全模式关闭,也应该没有理由更新/插入失败,除非服务器不可用.
我写了一个小应用程序来测试它,并包含下面的代码.它试图在Mongo中插入100,000个int,并且在运行后检查时,我在集合中看到大约90,000个记录.
(注意:我正在使用并行更新,因为我正在使用_id进行更新,而Mongo 2.0在使用_id时支持并行操作.当不使用Parallel.Foreach时,我仍然看到一些记录丢失虽然不是很好)
MongoServer server = MongoServer.Create(host);
MongoDatabase test = server.GetDatabase("testDB");
var list = Enumerable.Range(0, 100000).ToList();
using (server.RequestStart(test))
{
MongoCollection coll = test.GetCollection("testCollection");
Parallel.ForEach(list, i =>
{
var query = new QueryDocument("_id", i);
coll.Update(query, Update.Set("value",100),
UpdateFlags.Upsert, SafeMode.False);;
});
}
Run Code Online (Sandbox Code Playgroud)
所以我想我的问题是:快速进行大量更新的最佳方式是什么,成功率是100%?
我不能使用insert,因为我有许多进程写入Mongo并且无法确定某个文档是否存在,这就是我使用Upsert的原因.
当您使用SafeMode.False时,C#驱动程序只是将插入/更新消息写入套接字,而不是等待回复.当您将大量数据快速写入套接字时,它将在客户端进行缓冲,并且网络堆栈将尽可能快地将字节喷出网络.如果您正在使网络饱和,那么事情可以得到很大的支持.
我的猜测是,在网络堆栈有机会将所有剩余字节写入网络之前,您正在退出流程.这可以解释丢失的文件.
你最好的办法是最后给Count打电话,不是一次,而是一次,直到计数等于你认为应该是的数.此时你知道没有数据可以传输.
但是,如果任何插入因任何原因(例如,违反唯一索引)而失败,则计数将永远不会达到预期值.没有100%的方法可以在不使用SafeMode.True的情况下了解插入/更新是否有效.
请注意,大多数长期存在的服务器进程永远不会出现此问
| 归档时间: |
|
| 查看次数: |
1831 次 |
| 最近记录: |