我有一个用C ++编写的应用程序,有16个线程,可以从wireshark / tshark的输出中读取。 Wireshark / tshark分析了作为gsm_map信令捕获的pcap文件。
Mongodb是2.6.7
我的文档所需的结构是这样的:
注意“数据包”是一个数组,以后会变得很明显。
对于所有不了解TCAP的人来说,TCAP层是面向事务的,这意味着,所有数据包都包括:
因此,例如,您可能会看到一个包含3个数据包的事务,查看TCAP层将大致是这个
两个数据包,一个“开始”,一个“结束”。
{
"_id" : ObjectId("54ccd186b8ea19c89ee8f231"),
"deleted" : "0",
"packet" : {
"datetime" : ISODate("2015-01-31T12:58:11.939Z"),
"signallingType" : "M2PA",
"opc" : "326",
"dpc" : "6406",
"transState" : "begin",
"otid" : "M2PA0400435B",
"dtid" : "",
"sccpCalling" : "523332075100",
"sccpCalled" : "523331466304",
"operation" : "mo-forwardSM (46)",
...
}
}
/* 1 */
{
"_id" : ObjectId("54ccd1a1b8ea19c89ee8f7c5"),
"deleted" : "0",
"packet" : {
"datetime" : ISODate("2015-01-31T12:58:16.788Z"),
"signallingType" : "M2PA",
"opc" : "6407",
"dpc" : "326",
"transState" : "end",
"otid" : "",
"dtid" : "M2PA0400435B",
"sccpCalling" : "523331466304",
"sccpCalled" : "523332075100",
"operation" : "Not Found",
...
}
}
由于网络架构,我们在两(2)个点进行跟踪,并且这两个点之间的流量是平衡的。这意味着有时我们会在“开始”之前看到“继续”或“结束”。相反,我们可能会在“开始”或“结束”之前看到“继续”。简而言之,交易不订购。
此外,多个端点之间正在“交谈”,并且transactionID可能会重复,2个端点可能同时使用相同的tid和其他2个端点,尽管这不会一直发生,它发生。
由于后者,我还需要使用SCCP层的“呼叫”和“呼叫”全局标题(如电话号码)。
请记住,我不知道给定数据包的走向,所以这就是我正在做的事情:
作为一个例子,这是一个“结束”的upsert,它应该找到一个“开始”:
db.runCommand(
{
update: "packets",
updates:
[
{ q:
{ $and:
[
{
$or: [
{ "packet.otid":
{ $in: [ "M2PA042e3918" ] }
},
{ "packet.dtid":
{ $in: [ "M2PA042e3918" ] }
}
]
},
{
$or: [
{ "packet.sccpCalling":
{ $in: [ "523332075151", "523331466305" ] }
},
{ "packet.sccpCalled":
{ $in: [ "523332075151", "523331466305" ] }
}
]
}
]
},
{
$setOnInsert: {
"unique-id": "422984b6-6688-4782-9ba1-852a9fc6db3b", deleted: "0"
},
$push: {
packet: {
datetime: new Date(1422371239182),
opc: "327", dpc: "6407",
transState: "end",
otid: "", dtid: "M2PA042e3918", sccpCalling: "523332075151", ... }
}
},
upsert: true
}
],
writeConcern: { j: "1" }
}
)
现在,所有这些都有效,直到我投入生产。
似乎数据包正在快速发展,我看到很多:
“ClientCursor :: staticYield无法解锁B / c递归锁定”警告 我读到我们可以忽略这个警告,但我发现我的upserts不会更新文件!看起来有一个锁和mongodb会忘记更新。如果我将upsert更改为简单插入,则不会丢失数据包
我还读到这与没有使用索引有关,我有以下索引:
"3" : {
"v" : 1,
"key" : {
"packet.otid" : 1,
"packet.dtid" : 1,
"packet.sccpCalling" : 1,
"packet.sccpCalled" : 1
},
"name" : "packet.otid_1_packet.dtid_1_packet.sccpCalling_1_packet.sccpCalled_1",
"ns" : "tracer.packets"
总之:
1.-如果此指数不正确,有人可以帮我创建正确的索引吗? 2.-如果发现锁定,mongo不会更新文件是否正常?
谢谢和问候!
大卫
答案 0 :(得分:0)
为什么要将所有数据包存储在数组中?通常在这种情况下,最好将每个数据包单独作为文档;如果没有关于你的用例的更多信息(或者更多地了解你正在使用的所有这些首字母缩略词,很难说更多):D)。您的更新将成为插入,您不需要执行更新查询。相反,数据包上的一些其他元数据会将相关数据包连接在一起,因此您可以重建事务或任何您需要做的事情。
更直接地解决您的问题,我会使用数组字段tids
来存储[otid, dtid]
,使用数组字段sccps
来存储[sccpCalling, sccpCalled]
,这将使您的更新查询看起来像
{ "tids" : { "$in" : ["M2PA042e3918"] }, "sccps" : { "$in" : [ "523332075151", "523331466305" ] } }
并且可以使用索引{ "tids" : 1, "sccps" : 1 }
。