2014-01-08 3 views
0

Я использую mongodb, и мне нужно обновить свои документы, скажем, всего 1000. Мой документ имеет базовую структуру, как:Mongodb Проблема с производительностью

{ 
People:[1,2,3,4], 
Place:"Auckland" 
Event:"Music Show" 
} 

У меня есть 10 000 потоков, работающих одновременно в другой виртуальной машине. Каждый поток ищет эти документы (1000), посмотрите, соответствуют ли эти 1000 документов запросу и нажимают число в массиве People. Предположим, что если поток 100 нашел, что 500 из этих 1000 документов имеют отношение к делу, то он подталкивает число 100 в массиве People из всех 500 документов. Для этого

Я использую для каждого потока (10000) команд

update.append("$push",new BasicDBObject("People",serial_number)); 
updateMulti(query,update); 

Я наблюдаю плохую производительность этих обновлений в месте (мульти-запрос). Это проблема из-за блокировки записи? Каждый поток (10000) обновляет документ, относящийся к запросу? - так кажется, есть много «ожидания» Есть ли более эффективный способ выполнения этих «push» операций? Действительно ли «UpdateMulti» подходит для этого?

Th AnK за большой ответ - редактирование и добавление больше информации

Некоторого дизайн:

Да ваше чтение нашей проблемы является правильным. У нас есть 10000 потоков, каждый из которых представляет один «актер», обновляющий до 1000 объектов (на основе соответствующего запроса) за один раз с помощью $ push.

Инвертирование модели приводит нас к нескольким сломанным пользователям (с точки зрения нашего домена), что приводит нас к объединению «состояний» первичной сущности (которая теперь будет распространена во многих коллекциях) - ex: каждое из этих действий изменение состояния для этого объекта - E имеет состояния (e1, e2, e3, e4, e5). Таким образом, e1-e5 представляется как совокупный массив, который обновляется 10 000 потоков/процессов, которые представляют действия внешних приложений.

Нам нужно близко к агрегации в реальном времени, поскольку другой набор «актеров» рассматривает эти «состояния» от e1 до e5, а затем соответствующим образом реагирует через другой канал на «элементы в массиве».

Что должно быть «идеальной» стратегией дизайна в таком случае - ускорить запись. Будет ли ошпаривать помощь - есть ли эвристика «величины» для этого - при какой блокировке% мы должны осколки и т. Д.

+0

Необходимо некоторое уточнение - известны ли государства заранее? Другими словами, сколько штатов существует - 5? И если да, то почему они должны быть массивом? Можете ли вы привести пример документа «в процессе» и тип запроса, который использует другой набор участников? –

+0

C {a1 = "",//// атрибуты a2 = "", a3 = "" C_s1 = [a1, a2, a3, a4, ....] // состояние s1 объекта C C_s2 = [a5, a4, a11, a1, ...] C_s3 = [a1, a2, a3, a4, ....] C_s4 = [a1, a2, a3, a4, ....] C_s5 = [a1, a2, a3 , a4, ....]} 5 состояний уже закодированы как типы массивов - так что любой запрос, чтобы сделать multi-update wiil, должен быть с точки зрения «ai», поэтому для данного экземпляра ai - возможно, потребуется обновить несколько C соответственно в разных состояниях - т.е. s1 в C1, s2 в C3 и т. д. каждые несколько минут. другой актер смотрит только на ай в своих разных государствах и взаимодействует с ними, чтобы вести их через государственную машину @ Ася Камский –

ответ

1

Это проблема из-за конструкции схемы.

Это крайне неэффективно для $push нескольких значений для нескольких документов, особенно из нескольких потоков. Это не так, что проблема блокировки записи - это то, что ваш дизайн стал проблемой. Кроме того, вы постоянно расширяете документы, что означает, что обновления не «на месте», и ваша коллекция быстро становится фрагментированной.

Кажется, что ваша схема «перевернута». У вас есть 10 000 потоков, которые хотят добавить числа, представляющие людей (я предполагаю, что очень много людей) к небольшому числу документов (1000), которые будут расти огромными. Мне кажется, что если вы хотите что-то внедрить во что-то еще, вы можете рассмотреть коллекции, представляющие людей, а затем встраивать события, в которые эти люди находятся, по крайней мере, тогда вы ограничиваете размер массива для каждого человека до 1000 максимум , а обновления будут распространяться на гораздо большее количество документов, что значительно сократит количество конфликтов.

Другой вариант - просто зарегистрировать событие/лицо в посещаемости, а затем выполнить агрегирование по необработанным данным позже, но, не зная точно, каковы ваши требования к этому приложению, трудно понять, какой способ даст наилучшие результаты - то, как вы выбрали, определенно тот, который вряд ли даст вам хорошую производительность.

+0

Th ank вам за отличный ответ - Отредактировано и добавлено еще немного информации в вопрос –

+0

C { a1 = "",//// атрибуты a2 = "", a3 = "" C_s1 = [a1, a2, a3, a4, ....] // состояние s1 объекта C C_s2 = [a5, a4, a11, a1, ...] C_s3 = [a1, a2, a3, a4, ....] C_s4 = [a1, a2, a3, a4, ....] C_s5 = [a1, a2, a3, a4, ....] 5 государств уже являются e ncoded как типы массивов - , поэтому любой запрос на выполнение мультиобмена wiil должен быть с точки зрения «ai» , поэтому для данного экземпляра ai может потребоваться обновить несколько C соответственно в разных состояниях - т.е. s1 в C1, s2 в C3 и т. Д. Каждые несколько минут. другой актер смотрит только на ай в своих различных состояниях и взаимодействует с ними, чтобы вести их через государственную машину –

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