2015-01-31 4 views
1

У меня есть приложение, написанное на C++ с 16 потоками, которое читается на выходе wirehark/tshark. Wireshark/tshark анализирует файлы pcap, которые передают сигналы gsm_map.mongodb upsert не обновляется, если заблокирован

MongoDB является 2.6.7

Структура мне нужно для моих документов, как это:

Примечание «пакет» является массивом, то станет понятно, почему позже.

Для всех, кто не знает TCAP, то ПМТ слой ориентированных на транзакции, это означает, что все пакеты включают в себя: Государственный

  • Сделка: начать/продолжить/конец
  • Origin идентификатор транзакции (otid)
  • назначения идентификатора транзакции (dtid)

Так, например, вы можете увидеть транзакции, состоящие из 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) очков, а трафик сбалансирован между этими двумя точками. Это означает, что иногда мы видим «продолжение» или «конец» до «начала». И наоборот, мы можем увидеть «продолжить» до «начала» или «завершения». Короче говоря, транзакции - , а не.

Кроме того, несколько конечных точек «разговаривают» между собой, а идентификаторы транзакций могут дублироваться, 2 конечных точки могут одновременно использовать один и тот же tid и другие 2 конечные точки, хотя это не происходит все время, это делает.

Из-за более позднего времени мне также необходимо использовать «зов» и «названные» глобальные заголовки SCCP (например, номера телефонов).

Имейте в виду, что я не знаю, каким образом происходит данный пакет, так это то, что я делаю:

  • Всякий раз, когда я получаю новый пакет я должен найти, существует ли уже сделка в mongodb, я использую upsert, чтобы сделать это.
    • Я делаю это с помощью функции поиска текущего пакета в otid или dtid в любом otid или dtid существующих пакетов
    • Если он: надавите новый пакет в существующий документ.
    • Если это не так: создайте новый документ с пакетом.

В качестве примера, это 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 Может не Unlock B/C рекурсивной Lock» предупреждения я прочитал, что мы можем игнорировать это предупреждение, но Я обнаружил, что мои 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.- Нормально ли, что монго не будет обновлять документ, если он обнаружит блокировку?

Спасибо и приветствую!

Дэвид

ответ

0

Почему вы хранить все пакеты в массиве? Обычно в такой ситуации лучше сделать каждый пакет документом самостоятельно; трудно сказать больше без дополнительной информации о вашем случае использования (или, может быть, больше знаний обо всех этих акронимах, которые вы используете: D). Ваши обновления станут вставками, и вам не нужно будет делать запрос на обновление. Вместо этого некоторые другие метаданные в пакете объединяли связанные пакеты вместе, чтобы вы могли восстановить транзакцию или что-то еще, что вам нужно сделать.

Более непосредственно обращаясь ваш вопрос, я хотел бы использовать поле массива tids для хранения [otid, dtid] и поле массива sccps для хранения [sccpCalling, sccpCalled], что позволит сделать ваш обновления внешний вид запроса, как

{ "tids" : { "$in" : ["M2PA042e3918"] }, "sccps" : { "$in" : [ "523332075151", "523331466305" ] } } 

и поддающийся к индексу { "tids" : 1, "sccps" : 1 } ,

+0

Я попробую предложение массива о тидах. Что касается того факта, что я хочу создать транзакцию «на лету»: мне нужно сделать то, что мне нужно сделать, мы говорим о миллионах пакетов в час, если я жду, чтобы связать их (создать транзакцию позже). Я думаю, что это потребует дополнительных загрузить на сервер. Кроме того, мой другой вопрос: нормально ли для mongodb НЕ обновлять/вставлять документ, когда он обнаруживает (длинную?) Блокировку? –

+0

Нет, это не нормально. Что возвращают заявления без обновления? Таймауты? Какие-то ошибки? Можете ли вы опубликовать полное сообщение об ошибке? – wdberkeley

+0

Ничего, ни «updateExisting: true», если (обновлено), либо ObjectId (который является новым вставленным объектом) ... Я вижу в журнале «Client Cursor :: yield» не может разблокировать b/c рекурсивная блокировка ", когда пакет не вставлен/обновлен. –

Смежные вопросы