问题: 我们的写入速度很慢,写入时间差异很大。从1分钟到近4分钟。这是为了插入大量的值(准确地说是704 974)
背景: 我们从txt文件中读取值,将其链接到某个标记(数据对象),然后将值添加到值集合中。每个数据点都链接到标签和时间。每个值bson都有两个主键:ID和tag-date。 Bson的值如下所示:
public int InsertValues(string aDatabaseName, List<cValueDocument> aValues, out List<int> aErrorValueIndexes,
bool aOverride = false)
{
Parallel.ForEach(aValues, aValue => aValue.ConvertToDoubleIfCan());
int lResult = 0;
Stack<int> lErrorIndexesToDelete = new Stack<int>(aValues.Count - 1);
aErrorValueIndexes = new List<int>(aValues.Count);
aDatabaseName = aDatabaseName.ToLower();
var lValueCollection =
MongoDatabasesDict[aDatabaseName].GetCollection<cValueDocument>(tMongoCollectionNames.Value.ToString());
var lTagCollection =
MongoDatabasesDict[aDatabaseName].GetCollection<cTagDocument>(tMongoCollectionNames.Tag.ToString());
List<cValueDocument> lValuesOrderedByTime = aValues.OrderBy(aDocument => aDocument.Timestamp).ToList();
// Check if there are Values that belong to other Tags.
if (lValuesOrderedByTime.Any(aValue => aValue.TagID != lValuesOrderedByTime[0].TagID))
{
return -4;
}
cTagDocument lTagDocument = lTagCollection.AsQueryable().First(aTag => aTag._id == lValuesOrderedByTime[0].TagID);
// Find any Values that are not at least the minimum Interval between each other.
for (int i = 1; i < lValuesOrderedByTime.Count; i++)
{
// Determine if the two consecutive timestamps are not at least an Interval from each other.
if (lTagDocument.IntervalMask.CompareDateTimesWithinInterval(lValuesOrderedByTime[i - 1].Timestamp, lValuesOrderedByTime[i].Timestamp) == -1)
{
aErrorValueIndexes.Add(aValues.FindIndex(aElement => aElement == lValuesOrderedByTime[i]));
lErrorIndexesToDelete.Push(i);
lResult = -2;
}
}
// Determine if erroneous values must be removed before insertion.
if (lResult == -2)
{
// Remove each value with an index in lErrorIndexesToDelete;
while (lErrorIndexesToDelete.Count > 0)
{
lValuesOrderedByTime.RemoveAt(lErrorIndexesToDelete.Pop());
}
}
if (aOverride)
{//removed for testing purposes}
try
{
try
{
InsertManyOptions lOptions = new InsertManyOptions();
lOptions.IsOrdered = false;
lValueCollection.InsertMany(lValuesOrderedByTime, lOptions);
}
catch (MongoBulkWriteException lException)
{
if (lException.WriteErrors?.First().Code == 11000)
{
aErrorValueIndexes = Enumerable.Range(0, aValues.Count).ToList();
lResult = -3;
}
else
{
throw;
}
}
return lResult;
}
catch (Exception lException)
{
BigDBLog.LogEvent("Error, an exception was thrown in InsertValues. ", tEventEscalation.Error,
false,
lException);
return -5;
}
}
mongoDb设置为3复制集,我们用writeconcern写入true(我们遇到一个复制集落后并且拒绝自动赶上的麻烦)Mongo在MESOS / Linux部署上运行,而c#代码通过网络从Windows机器连接。
Mongo版本:3.4.5
C#驱动程序:2.4.4
我还将最小和最大线程池线程数增加了50.我利用线程尝试提高写入速度,它有点起作用。
代码 将数据插入mongo的实际代码是:
{{1}}
我删除了一些值检查以缩短功能。 基本上该函数将aValues推送到mongo
调试/跟踪 这是对我来说很奇怪的地方。我使用相同的文件来测试它。我在每次测试之前删除了DB中的值。
执行速度从1分钟到4分钟不到1分钟。 我使用jetbrains dotTrace对程序进行了跟踪。它指向MongoDB.Driver.Core.Misc.StreamExtensionMethods.ReadBytes作为热点。如果您遵循代码,则称为MongoDB.Driver.MongoCollectionBase`1.InsertMany。这很奇怪,因为我正在编写数据库而不是从中读取数据。 CPU使用spike(在文件转换期间更多),但保持低(1-2%)。
我查看了wiredTiger.concurrentTransactions票证。他们没有用完。
问题