Лучший способ обработать проблемы параллелизма

Чистый Bash, никакие внешние процессы кроме 'mv':

for file in foo*; do
  newnumber='00000'${file#foo}      # get number, pack with zeros
  newnumber=${newnumber:(-5)}       # the last five characters
  mv $file foo$newnumber            # rename
done
12
задан 4 revs 26 November 2009 в 16:33
поделиться

10 ответов

I agree that I probably wouldn't hit the database for this. I suppose I would use APC cache (or some other in-memory cache) to maintain this information. What you are describing is clearly optimistic locking at the detailed record level. The higher the level in the database structure the less you need to deal with. It sounds like you want to check with multiple tables within a structure.

I would maintain a cache (in APC) of the IDs and the timestamps of the last updated time keyed by the table name. So for example I might have an array of table names where each entry is keyed by ID and the actual value is the last updated timestamp. There are probably many ways to set this up with arrays or other structures but you get the idea. I would probably add a timeout to the cache so that entries in the cache are removed after a certain period of time - i.e., I wouldn't want the cache to grow and assume that 1 day old entries aren't useful anymore).

With this architecture you would need to do the following (in addition to setting up APC):

  • on any update to any (applicable) table, update the APC cache entry with the new timestamp.

  • within ajax just go as far "back" as php (to obtain the APC cache to check the entry) rather than all of the way "back" to the database.

3
ответ дан 2 December 2019 в 23:07
поделиться

Я думаю, вы можете использовать условие в операторе UPDATE, например WHERE ID =? AND LAST_UPDATE = ?.

Идея состоит в том, что вы сможете выполнить обновление только тогда, когда будете последним, кто прочитает эту строку. Если кто-то что-то совершил, вы потерпите неудачу, и, как только вы узнаете, что потерпели неудачу, вы можете запросить изменения.

2
ответ дан 2 December 2019 в 23:07
поделиться

Вам понадобится какой-либо тип поля отметки версии для каждой записи. Что это, не имеет значения, если вы можете гарантировать, что любое изменение записи приведет к тому, что штамп версии будет отличаться. Лучше всего затем проверить и убедиться, что загруженная запись ' Метка версии совпадает с меткой версии в БД, когда пользователь нажимает кнопку «Сохранить», и если она отличается от нее, обрабатывать ее.

Как вы ее обрабатываете, зависит от вас. По крайней мере, вы хотели бы предложить перезагрузку из БД, чтобы пользователь мог убедиться, что он все еще хочет сохранить. Один из возможных вариантов - попытаться объединить их изменения в новую запись БД, а затем попросить их убедиться, что объединение работает правильно.

Если вы хотите периодически опрашивать любую БД, способную обрабатывать вашу систему, она должна иметь возможность принимать загрузка опроса. 10 пользователей, опрашивающих каждые 5 секунд, составляют 2 транзакции в секунду. Это тривиальная нагрузка, и она не должна вызывать никаких проблем. Чтобы средняя нагрузка оставалась близкой к фактической, просто немного измените время опроса (вместо того, чтобы делать это точно каждые 5 секунд, делайте это, например, каждые 4-6 секунд).

и если это будет по-другому, сделай это.

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

Если вы хотите периодически опрашивать любую БД, способную обрабатывать вашу систему, она должна иметь возможность принимать загрузка опроса. 10 пользователей, опрашивающих каждые 5 секунд, составляют 2 транзакции в секунду. Это банальная нагрузка, и это не должно быть проблемой. Чтобы средняя нагрузка была близка к фактической, просто немного измените время опроса (вместо того, чтобы делать это точно каждые 5 секунд, делайте это, например, каждые 4-6 секунд).

и если это будет по-другому, сделай это.

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

Если вы хотите периодически опрашивать любую БД, способную обрабатывать вашу систему, она должна иметь возможность принимать загрузка опроса. 10 пользователей, опрашивающих каждые 5 секунд, составляют 2 транзакции в секунду. Это тривиальная нагрузка, и она не должна вызывать никаких проблем. Чтобы средняя нагрузка была близка к фактической, просто немного измените время опроса (вместо того, чтобы делать это точно каждые 5 секунд, делайте это, например, каждые 4-6 секунд).

d хочу предложить перезагрузку из БД, чтобы пользователь мог убедиться, что он все еще хочет сохранить. Один из возможных вариантов - попытаться объединить их изменения в новую запись БД, а затем попросить их убедиться, что объединение работает правильно.

Если вы хотите периодически опрашивать любую БД, способную обрабатывать вашу систему, она должна иметь возможность принимать загрузка опроса. 10 пользователей, опрашивающих каждые 5 секунд, составляют 2 транзакции в секунду. Это тривиальная нагрузка, и она не должна вызывать никаких проблем. Чтобы средняя нагрузка была близка к фактической, просто немного измените время опроса (вместо того, чтобы делать это точно каждые 5 секунд, делайте это, например, каждые 4-6 секунд).

d хочу предложить перезагрузку из БД, чтобы пользователь мог убедиться, что он все еще хочет сохранить. Один из возможных вариантов - попытаться объединить их изменения в новую запись БД, а затем попросить их убедиться, что объединение работает правильно.

Если вы хотите периодически опрашивать любую БД, способную обрабатывать вашу систему, она должна иметь возможность принимать загрузка опроса. 10 пользователей, опрашивающих каждые 5 секунд, составляют 2 транзакции в секунду. Это банальная нагрузка, и это не должно быть проблемой. Чтобы средняя нагрузка была близка к фактической, просто немного измените время опроса (вместо того, чтобы делать это точно каждые 5 секунд, делайте это, например, каждые 4-6 секунд).

Один из возможных вариантов - попытаться объединить их изменения в новую запись БД, а затем попросить их убедиться, что объединение работает правильно.

Если вы хотите периодически опрашивать любую БД, способную обрабатывать вашу систему, она должна иметь возможность принимать загрузка опроса. 10 пользователей, опрашивающих каждые 5 секунд, составляют 2 транзакции в секунду. Это банальная нагрузка, и это не должно быть проблемой. Чтобы средняя нагрузка оставалась близкой к фактической, просто немного измените время опроса (вместо того, чтобы делать это точно каждые 5 секунд, делайте это, например, каждые 4-6 секунд).

Один из возможных вариантов - попытаться объединить их изменения в новую запись БД, а затем попросить их убедиться, что объединение работает правильно.

Если вы хотите периодически опрашивать любую БД, способную обрабатывать вашу систему, она должна иметь возможность принимать загрузка опроса. 10 пользователей, опрашивающих каждые 5 секунд, составляют 2 транзакции в секунду. Это банальная нагрузка, и это не должно быть проблемой. Чтобы средняя нагрузка оставалась близкой к фактической, просто немного измените время опроса (вместо того, чтобы делать это точно каждые 5 секунд, делайте это, например, каждые 4-6 секунд).

1
ответ дан 2 December 2019 в 23:07
поделиться

Ваш подход к запросам базы данных - лучший. Если вы делаете это каждые 5 секунд и у вас одновременно работает 15 пользователей, то вы просматриваете ~ 3 запроса в секунду. Это тоже должен быть очень маленький запрос, возвращающий только одну строку данных. Если ваша база данных не может обрабатывать 3 транзакции в секунду, вам может потребоваться лучшая база данных, потому что 3 запроса в секунду - это ничего.

Отметьте записи в таблице, чтобы вы могли быстро увидеть, изменилось ли что-нибудь, без необходимости различать каждое поле.

0
ответ дан 2 December 2019 в 23:07
поделиться

Во-первых, обновите только те поля, которые были изменены при записи в базу данных, это снизит нагрузку на базу данных.

Во-вторых, запросите временную метку последнего обновления, если у вас более старая отметка времени, а затем текущая версия в базе данных, затем выдает предупреждение клиенту.

В-третьих, как-то передать эту информацию клиенту, используя какое-то постоянное соединение с сервером, позволяющее одновременное двустороннее соединение.

0
ответ дан 2 December 2019 в 23:07
поделиться

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

0
ответ дан 2 December 2019 в 23:07
поделиться

Это немного не по теме, но вы можете использовать пакет PEAR (или пакет PECL, я забыл какой) xdiff , чтобы отправить полезное руководство пользователя, когда вы получите столкновение.

0
ответ дан 2 December 2019 в 23:07
поделиться

Опрос редко бывает хорошим решением.
Вы можете выполнить проверку временной метки только тогда, когда пользователь (с открытым документом) делает что-то активное с документом, например, прокручивает, перемещает мышь по нему или начинает редактировать. Затем пользователь получает предупреждение, если документ был изменен.

.....
Я знаю, что это не то, о чем вы просили, но ... почему не синглтон для редактирования?
Синглтон может быть столбцом идентификатора пользователя в таблице документа.
Если пользователь хочет редактировать документ, документ блокируется для редактирования другими пользователями.

Или есть отдельные поля редактирования для отдельных полей / групп информации.

Только один пользователь может редактировать документ одновременно. Если другой пользователь открыл документ и хочет отредактировать единственную временную метку, проверка покажет, что документ был изменен и перезагружен.

В синглтоне нет опроса и только одна проверка временной метки, когда пользователь "касается" и / или хочет отредактировать документ.

Но, возможно, одноэлементный механизм не подходит для вашей системы.

С уважением
Зигерстед

0
ответ дан 2 December 2019 в 23:07
поделиться

Ответ Донни (опрос), вероятно, ваш лучший вариант - простой и работает. Он будет охватывать почти все случаи (маловероятно, что простой поиск PK снизит производительность, даже на очень популярном сайте).

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

Однако не используйте столбец с меткой времени «last_updated». Редактирование в течение одной секунды не является чем-то необычным. Вы можете избежать неприятностей, если добавите дополнительную информацию (сервер, который выполнил обновление, удаленный адрес, порт и т. Д.), Чтобы гарантировать, что если два запроса поступят в одну и ту же секунду, к тому же серверу, вы можете заметить разницу. Однако если вам нужна такая точность, вы также можете использовать уникальное поле ревизии (оно не обязательно должно быть увеличивающимся целым числом, просто уникальным в пределах срока жизни этой записи).

Кто-то упомянул постоянные соединения - это уменьшило бы стоимость настройки опросных запросов (естественно, каждое соединение потребляет ресурсы в базе данных и на хост-машине). Вы должны держать одно соединение (или как можно меньше) открытым все время (или как можно дольше) и использовать его (в сочетании с кэшированием и мемоизацией, если необходимо).

Наконец, есть операторы SQL, которые позволяют вы должны добавить условие на UPDATE или INSERT. Мой SQl действительно ржавеет, но я думаю, что это что-то вроде ОБНОВЛЕНИЕ ... ГДЕ ... . Чтобы соответствовать этому уровню защиты, вам нужно будет выполнить собственную блокировку строк перед отправкой обновления (и всей возможной обработкой ошибок и очисткой). Вряд ли вам это понадобится; Я упоминаю это только для полноты.

Редактировать:

Ваше решение звучит нормально (временные метки кеша, запросы прокси-опроса к другому серверу). Единственное изменение, которое я внесу, - это обновлять кешированные метки времени при каждом сохранении. Это позволит сохранить кэш более свежим. Я бы также проверил временную метку непосредственно из базы данных при сохранении, чтобы предотвратить проникновение сохранения из-за устаревших данных кеша.

Если вы используете APC для кеширования, то второй HTTP-сервер не имеет смысла - вам придется для запуска на той же машине (APC использует разделяемую память). Эта же физическая машина будет выполнять работу, но с дополнительными накладными расходами второго HTTP-сервера. Если вы хотите разгрузить запросы опроса на второй сервер (lighttpd, в вашем случае), тогда было бы лучше настроить lightttpd перед Apache на второй физической машине и использовать общий кэширующий сервер (memcache), чтобы Сервер lighttpd может читать кешированные метки времени, а Apache может обновлять кешированные метки времени. Если большинство запросов являются запросами опроса, то причина для помещения lighttpd перед Apache заключается в том, чтобы избежать использования более тяжелого процесса Apache.

Вам, вероятно, вообще не нужен второй сервер. Apache должен уметь обрабатывать дополнительные запросы. Если нет, то я бы пересмотрел вашу конфигурацию (в частности, директивы, которые контролируют, сколько рабочих процессов вы запускаете и сколько запросов им разрешено обрабатывать, прежде чем они будут убиты).

тогда было бы лучше установить lightttpd перед Apache на второй физической машине и использовать общий кэширующий сервер (memcache), чтобы сервер lighttpd мог читать кешированные временные метки, а Apache мог обновлять кешированные временные метки. Если большинство запросов являются запросами опроса, то причина для помещения lighttpd перед Apache заключается в том, чтобы избежать использования более тяжелого процесса Apache.

Вам, вероятно, вообще не нужен второй сервер. Apache должен уметь обрабатывать дополнительные запросы. Если нет, то я бы пересмотрел вашу конфигурацию (в частности, директивы, которые контролируют, сколько рабочих процессов вы запускаете и сколько запросов им разрешено обрабатывать, прежде чем они будут убиты).

тогда было бы лучше установить lightttpd перед Apache на второй физической машине и использовать общий кэширующий сервер (memcache), чтобы сервер lighttpd мог читать кешированные временные метки, а Apache мог обновлять кешированные временные метки. Если большинство запросов являются запросами опроса, то причина для помещения lighttpd перед Apache состоит в том, чтобы избежать использования более тяжелого процесса Apache.

Вам, вероятно, вообще не нужен второй сервер. Apache должен уметь обрабатывать дополнительные запросы. Если нет, то я бы еще раз просмотрел вашу конфигурацию (в частности, директивы, которые контролируют, сколько рабочих процессов вы запускаете и сколько запросов им разрешено обрабатывать до того, как они будут уничтожены).

Если большинство запросов являются запросами опроса, то причина для помещения lighttpd перед Apache заключается в том, чтобы избежать использования более тяжелого процесса Apache.

Вам, вероятно, вообще не нужен второй сервер. Apache должен уметь обрабатывать дополнительные запросы. Если нет, то я бы еще раз просмотрел вашу конфигурацию (в частности, директивы, которые контролируют, сколько рабочих процессов вы запускаете и сколько запросов им разрешено обрабатывать до того, как они будут уничтожены).

Если большинство запросов являются запросами опроса, то причина для помещения lighttpd перед Apache заключается в том, чтобы избежать использования более тяжелого процесса Apache.

Вам, вероятно, вообще не нужен второй сервер. Apache должен уметь обрабатывать дополнительные запросы. Если нет, то я бы еще раз просмотрел вашу конфигурацию (в частности, директивы, которые контролируют, сколько рабочих процессов вы запускаете и сколько запросов им разрешено обрабатывать до того, как они будут уничтожены).

1
ответ дан 2 December 2019 в 23:07
поделиться

Ааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааа * * 1261] У меня есть $ x (на самом деле $ x = 200, но он растет, надеюсь, скоро достигнет 1000) точных копий этой базы данных, и для каждого из них до 20 (в среднем 10) пользователей на 9 часов в день.

Если один из этих пользователей просматривает запись, любую запись, я должен посоветовать ему, если кто-то редактирует ту же запись.

Предположим, Фу смотрит документ 0001, сядет, чтобы выпить кофе, открыть Бар и отредактировать то же самое. документ, когда Фу вернется, он должен увидеть «Предупреждение, этот документ редактировал кто-то другой! щелкните здесь, чтобы обновить страницу. '.

Мне нужен банкомат, возможно, я расширю эту ситуацию, добавив способ просмотра изменений и отката, но дело не в этом.

Некоторые из вас предлагали проверять временную метку «последнего обновления» только тогда, когда foo пытается сохранить документ; Это тоже может быть решением, но мне нужно что-то в реальном времени (задержка 10 секунд).

Длительный опрос, плохой способ, но кажется единственным.

Итак, что я сделал:

  1. Установлен Lighttp на моем компьютере (и php5 как fastcgi);
  2. Загружен прокси-модуль apache2 (вы получите ошибку all или 403);
  3. Изменен порт lighttpd с 80 (который используется apache2) на 81;
  4. Настроен apache2 для проксирования запроса с mydomain.com/polling/* на polling.mydomain.com (обслуживается с помощью Lighttp).
  5. Теперь у меня есть еще один вспомогательный http-сервис, который я буду использовать как для опроса, так и для загрузки. статический контент (изображения и т. д.), чтобы уменьшить нагрузку на apache2.
  6. Becos i не хочет уничтожать базу данных для проверки метки времени, i '
    1. APC: довольно простой в установке и управлении, очень легкий и быстрый, это был бы мой первый выбор ... если бы только кеш был доступен для совместного использования между двумя процессами cgi (мне нужно сохранить в кеше значение из процесса php apache2, и прочтите его из процесса php lighttpd)
    2. Memcached: примерно в 4-5 раз медленнее, чем APC, но работает как единый процесс, который можно задействовать везде в моей среде. Я пойду с этим, атм. (даже если он медленнее, я буду использовать его относительно просто.)

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

Я полагаю, что эта среда будет работать и в других ситуациях с длительным опросом (чат?)

Спасибо всем, кто дал мне знать!

0
ответ дан 2 December 2019 в 23:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: