我正在研究一个使用RavenDB的原型,供我公司评估。我们将有许多线程每隔几秒插入数千行,并且许多线程同时读取。我已经完成了我的第一个简单的插入测试,在进一步开发之前,我想确保我使用推荐的方法来获得RavenDB插入的最佳性能。
我相信有一个批量插入选项。我还没有调查过,因为我不确定这是否必要。我正在使用.NET API,我的代码目前看起来像这样:
Debug.WriteLine("Number of Marker objects: {0}", markerList.Count);
StopwatchLogger.ExecuteAndLogPerformance(() =>
{
IDocumentSession ravenSession = GetRavenSession();
markerList.ForEach(marker => ravenSession.Store(marker));
ravenSession.SaveChanges();
}, "Save Marker data in RavenDB");
StopwatchLogger只是在周围放一个秒表时调用动作:
internal static void ExecuteAndLogPerformance(Action action, string descriptionOfAction)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
action();
stopwatch.Stop();
Debug.WriteLine("{0} -- Processing time: {1} ms", descriptionOfAction, stopwatch.ElapsedMilliseconds);
}
以下是几次运行的输出。注意,我正在写一个RavenDB的本地实例(build 701)。我知道网络上的性能会更差,但我首先在本地进行测试。
一次运行:
标记对象数:671
在RavenDB中保存标记数据 - 处理时间:1308 ms
另一次运行:
标记对象数:670
在RavenDB中保存标记数据 - 处理时间:1266 ms
另一次运行:
标记对象数:667
在RavenDB中保存标记数据 - 处理时间:625 ms
另一次运行:
标记对象数:639
在RavenDB中保存标记数据 - 处理时间:639 ms
哈。 639毫秒内有639个物体。有什么可能性?无论如何,这是每毫秒一次插入,每秒1000次。
标记对象/文档没有太多内容。以下是已保存的示例:
{
"ID": 14740009,
"SubID": "120403041588",
"ReadTime": "2012-04-03T13:51:45.0000000",
"CdsLotOpside": "163325",
"CdsLotBackside": "163325",
"CdteLotOpside": "167762",
"CdteLotBackside": "167762",
"EquipmentID": "VA_B"
}
这是预期的表现吗?
是否有更好的方式(最佳做法)插入以获得速度?
是否有我可以定位的插入基准?
答案 0 :(得分:6)
首先,我希望确保您在一个批次中保存的项目数量不会太大。没有硬限制,但是如果交易规模太大,它会损害性能并最终崩溃。使用1024个项目的值是安全的,但这实际上取决于文档的大小。
每秒1000个文档远远低于使用单个RavenDB实例可以实现的数量。你应该并行插入,你可以使用配置选项进行某种调整。例如,您可以增加以Raven / Esent /开头的设置定义的值。将日志和索引放到不同的硬盘驱动器上也是一个好主意(比如在sql server中)。根据您的具体情况,您可能还希望在执行插入时暂时禁用索引。
但是,在大多数情况下,您不想关心这一点。如果您需要真正的高插入性能,您可以使用多个分片实例,理论上每秒可以获得无限数量的插入(只需添加更多实例)。