31.07.2009, 23:24 | #1 |
Магистр
Регистрация: 04.12.2007
Сообщений: 3,681
Вес репутации: 421
|
Одновременное множественное обращение к строке- помогите решить (MySql4.1)
Камрады! Кто шарит- подмогните.
Есть базка. Вней таблички, в табличках, естессн, строки. Строки надо брать софтинкой, обрабатывать и по результату обработки ставить в этой строке тот или иной флаг (апдейтить, короче); Строка имеет признак того, что она обработанная или необработанная- флажочег, опятьже.. Софтинка берет необработанные и после действа помечает их как обработанные.. Обработка это- процесс ресурсоёмкий, посему экземпляров обработчика (запущенных софтинок) должно быть много. Например 5. Или 100. Табличка большая- на мильён строк (тоесть это в идеале, если не в идеале- то если не получится работать с большой, буду както чистить, чтоп была маленькая). Кроме обработчиков, которые обращаются к табличке, есть еще источники, которые в эту табличку строки заносят (создают новые); Вопрос: как реализовать с максимально возможным сохранением производительности алгоритм взятия строки на обработку отдельным экземпляром обработчика, чтобы не было конфликтов с другими экземплярами. Лочить таблицу очень не хочется. Это не путь самурая. Хочется как нить хитровыпендрицца Всю голову сломал, ничё путного не придумал. Поможите, люди добрые!
__________________
|
01.08.2009, 01:18 | #3 | |
Магистр
Регистрация: 04.12.2007
Сообщений: 3,681
Вес репутации: 421
|
Цитата:
Насчет кратности- количество строк постоянно меняется. Оно увеличивается или уменьшается. Причем не обязательно с краев таблички. Поэтому хочется придумать алгоритм "залочивания" строки за обработчиком.
__________________
|
|
01.08.2009, 01:34 | #5 | |
Магистр
Регистрация: 04.12.2007
Сообщений: 3,681
Вес репутации: 421
|
Цитата:
Но: 1. Обработчики разноскоростные с одной стороны и обработка одной строки идет не стандартное количество времени (строки разные)- получится что ктото будет простаивать; 2. Хочется иметь возможность легкого добавления нового обработчика, не завязывая его на регистрацию гдето "на главном компутере"- тоесть поставил новый обработчик, указал ему в конфиге адрес и пароль к базке- и он пошел колбасить.. Или взял, остановил, обработчик и выкинул его. И нигде не нужно их прописывать.. Как считаете? Так можно сделать? Или это слишком жырно?
__________________
|
|
01.08.2009, 01:44 | #6 |
Bannеd
Регистрация: 17.09.2008
Сообщений: 6,446
Вес репутации: 373
|
Йода, таблица MyISAM? создайте аналог InnoDB, там встроена построчная блокировка.
или даже в MyISAM можно лишний столбец - флажок (три позиции! 0 незаблокировано, 1 чтение (не записывать), 2 запись (доступ закрыт)) блокировки строки сделать. |
01.08.2009, 09:56 | #7 | |
Магистр
Регистрация: 04.12.2007
Сообщений: 3,681
Вес репутации: 421
|
Последний Герой, про инно-дб, да. Надо пошукать, что у них там с транзакциями..
А вот насчет Цитата:
__________________
|
|
01.08.2009, 13:53 | #8 | |
Bannеd
Регистрация: 17.09.2008
Сообщений: 6,446
Вес репутации: 373
|
BEGIN
SELECT ... FROM ... WHERE ... [FOR UPDATE | LOCK IN SHARE MODE] [COMMIT|ROLLBACK] FOR UPDATE - блокирует строку на мертво LOCK IN SHARE MODE - разрешает другим процессам только читать строку COMMIT - завершить транзакцию с сохранением данных ROLLBACK - завершить транзакцию с удалением данных (откат) Цитата:
1) добавляете столбец числовой и обнуляете его значение для ВСЕХ строк 2) как только какой то поток хочет обратиться к строкам, он записывает в столбец свой айди, с условием, что столбец равен нулю (примерно так UPDATE SET столбец=айди WHERE столбец=0) 3) далее он считывает столбец, если блокировку удалось установить, то в столбце написан его айди (иначе там либо 0 либой айди другого процесса) 4) если блокировки нет, то возвращаемся к шагу 2 5) если блокировка есть, то можно считать, что строки заблокированы и выполнять с ней любые махинации 6) снимаем блокировку, записывая в столбец 0 |
|
01.08.2009, 14:14 | #9 |
Мне повезёт!
Регистрация: 05.05.2007
Сообщений: 1,076
Вес репутации: 281
|
Делить таблицу на равные куски плохо т.к. на миллионе параллельных потоков, даже если все операции одинаково ресурсоемки, всегда найдутся процессы, которые сделают их в 3 раза быстрей чем самый медленный. Это обусловлено внешними факторами, неравномерностью распределения процессорного времени и т.д.
Поэтому к концу работы у вас получится что 2 потока "догрызают" последние 10 000 записей, в то время как остальные 98 уже стоят. Т.е. производительность к концу работы будет заметно снижаться. Простой и эффективный способ есть такой: 1) В таблицу вводим доп поле `handler`. 2) Каждому процессу присваиваем уникальный идентификатор (например, порядковый номер) 3) Делаем Код:
UPDATE `table` SET `handler`=<идентификатор текущего процесса> WHERE `handler` is NULL AND `is_processed` = 0 LIMIT 1 4) Выбираем эту строчку через Код:
SELECT .... WHERE `handler`=<идентификатор текущего процесса> 5) по завершению ставим записи is_processed = 1 Для оптимизации можно резервировать по 10-30 записей за раз, тогда будет меньше накладных расходов на обращение к БД. Для легкого добавления обработчика сделайте это поле, например, строковым и пишите туда не число, а типа `mycomputer-1` и т.д. В общем, неймспейсы Совершенно пофигу как и в каком порядка они будут называться. Не забудьте только индекс на это поле поставить.
__________________
If it's not great, it's not the end. |
01.08.2009, 14:19 | #10 |
Bannеd
Регистрация: 17.09.2008
Сообщений: 6,446
Вес репутации: 373
|
Alexey, у вас частный случай моего предложения, только в вашем случае к строке может обращаться всего 1 поток и только 1 раз. ТСу же нужны построчные блокировки для нескольких обращений, как это реализовано в иннодб.
|
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Помогите решить проблему . | Jenya | Курилка | 7 | 04.01.2009 11:27 |
Помогите решить проблему с MSN | Chervechok | Курилка | 2 | 12.12.2008 02:26 |
Помогите решить проблему! | yan21 | Яндекс | 3 | 20.11.2008 13:08 |
помогите решить проблему | ncx | Курилка | 24 | 04.08.2008 20:01 |
Помогите решить проблемы | ara | Вопросы по работе системы | 5 | 30.04.2007 22:45 |
Часовой пояс GMT +3, время: 16:13.