powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Такой случай...
21 сообщений из 21, страница 1 из 1
Такой случай...
    #33827788
BigMac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброе время суток,

сегодня наткнулся на следующую проблему. Должна быть написана некая программа (C#), внутри которой будут работать паралельно множество threads (~ от 10 до 100). Каждый thread должен обращаться в БД и забирать свою "порцию" строк из довольно большой таблицы (около 1 миллиона записей) для обработки.
Тут возникают сразу несколько вопросов:
- конкурентноспособность, т.е. как избежать того, что бы 2 thread-а брали одни и те же строчки
- чем лучше сделать (курсором?)
- очень важна производительность

Буду очень признателен за любые идеи
...
Рейтинг: 0 / 0
Такой случай...
    #33827810
shuklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В качестве одной из идей
Сделать еще один трэд, который и будет ходить к БД, и никто кроме него, он будет отгребать порции данных и раздавать работу другим трэдам. Если обработка данных занимает больше времени чем их загрузка - вполне адекватное решение.
...
Рейтинг: 0 / 0
Такой случай...
    #33827863
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подозреваю, с точки зрения производительности (которая, вроде как, очень важна) стоит убрать некую программу и делать все на сервере БД. Для случайно выбранной задачи это обеспечит такой прирост быстродействия, что не будет нужно ни тредов, ни чего либо еще. А иначе следующей задачей поставите кластер, чтобы распихать треды по разным машинам.

Делать на сервере, наверное, можно и на C#, если он чем-то лучше.

Ну а распараллеливать строки для обработки - зависит от. Самый простой способ - при наличии N потоков каждый из них делает

Код: plaintext
select * from table where mod (id, N) = K

Впрочем, это далеко не самый эффективный вариант.
...
Рейтинг: 0 / 0
Такой случай...
    #33827866
BigMac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
довольно хорошая идея, спасибо.
А какой способ (из FAQ http://www.sql.ru/faq/faq_topic.aspx?fid=126) посоветуете что бы возвращать строчки ОТ..ДО? (опять же, важна производительность на очень большой таблице)
...
Рейтинг: 0 / 0
Такой случай...
    #33828038
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BigMacвнутри которой будут работать паралельно множество threads (~ от 10 до 100).
========== не обсуждается? Зачем потоки, т.к. голова процессора и голова пользователя ОДНА

Каждый thread должен обращаться в БД и забирать свою "порцию" строк из довольно большой таблицы (около 1 миллиона записей) для обработки.
========= много решений, от: разбить таблицу на несколько/грязное_чтение/на_более_быстрый_диск/..........Тут возникают сразу несколько вопросов:
- конкурентноспособность, т.е. как избежать того, что бы 2 thread-а брали одни и те же строчки
=========== а чем плохо? При грязном чтении никто не конкурирует кроме головки на контроллёре диска HDD

- чем лучше сделать (курсором?)
============= всегда плохо перед статикой-SELECT

- очень важна производительность
======= определить узкое место (потоки/устр-во_вывода/обработка/......)
...
Рейтинг: 0 / 0
Такой случай...
    #33830786
Фотография Критик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще согласен с softwarer

PS если используете MS SQL, читайте про READPAST
...
Рейтинг: 0 / 0
Такой случай...
    #33830820
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerПодозреваю, с точки зрения производительности (которая, вроде как, очень важна) стоит убрать некую программу и делать все на сервере БД. Для случайно выбранной задачи это обеспечит такой прирост быстродействия, что не будет нужно ни тредов, ни чего либо еще. А иначе следующей задачей поставите кластер, чтобы распихать треды по разным машинам.
Ну, не всегда время обработки ограничивается только ресурсами системы... Впрочем, раз тредстартер это не упомянул, у него не такой случай.)
...
Рейтинг: 0 / 0
Такой случай...
    #33843547
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
Уточните вопрос, пожалуйста.
- Вам нужна очередь с однократной выборкой каждой поставленной в нее строки?
- Или есть другие критерии, которые определяют, какие строки выбираются для какого потока?
-Важно ли, чтобы строки выбирались на обработку в том порядке, в котором пришли.
- Сколько строк за один раз выбирает поток?
- Какова интенсивность добавления строк в таблицу?
И вообще, какую задачу пытаетесь решить?
...
Рейтинг: 0 / 0
Такой случай...
    #33843595
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот кстати, подобную задачу можно было бы довольно красиво решить, если бы в условии выборки можно было бы задать что-то вроде WHERE ... IS NOT LOCKED. Достаточно было бы из каждого потока делать запросы вроде SELECT ... WHERE ... IS NOT LOCKED LIMIT 1 FOR UPDATE (или, если хотите SELECT TOP 1 ... WHERE ... IS NOT LOCKED FOR UPDATE), конечно, при наличии row level locking. Однако я не знаю, есть ли возможность в какой-либо СУБД задать такое условие... Кто-нибудь в курсе о такой возможности?)
...
Рейтинг: 0 / 0
Такой случай...
    #33843716
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В Oracle есть. Если мне не изменяет память, в одной из бесед упоминали про такую возможность и для MSSQL.
...
Рейтинг: 0 / 0
Такой случай...
    #33843718
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А можно пример?
...
Рейтинг: 0 / 0
Такой случай...
    #33843721
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Позволю себе процитировать не лучшее, но первое попавшееся под руку.

How to Acquire a Lock without Handling Exceptions

Overview

Normally we use FOR UPDATE NOWAIT to acquire a lock on rows. This statement either locks all the selected rows or the control is returned without acquiring any lock (i.e. even on rows which are available for locking) after throwing an exception.

For Update SKIP LOCKED

But there is an feature in Oracle Database, the clause FOR UPDATE SKIP LOCKED, which can be used to lock rows that are available for locking and skip the rows that have been locked by other sessions. This statement returns the control back without throwing an exception, even if all the rows are locked by another session.

To illustrate, we open two sessions. In the first session, we lock the row with deptno as 10 using FOR UPDATE NOWAIT.

Код: plaintext
1.
2.
3.
4.
5.
6.
    SELECT * FROM dept
     WHERE deptno =  10 
    FOR UPDATE NOWAIT;

    DEPTNO     DNAME          LOC
    ---------- -------------- -------------
     10          ACCOUNTING     NEW YORK

In the second session, we try to lock two rows (deptno 10 and 20) from the table dept using FOR UPDATE NOWAIT. An exception is thrown after executing the following statement because one of the row (i.e. deptno 10) out of the selected list is already locked by session 1.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
    SELECT * FROM dept
     WHERE deptno IN ( 10 , 20 )
    FOR UPDATE NOWAIT;

    SELECT * FROM dept WHERE deptno IN ( 10 , 20 )
    FOR UPDATE NOWAIT
    ERROR at line  1 :
    ORA- 00054 : resource busy and acquire with NOWAIT specified

Now we again try to lock two rows (deptno(s) 10 and 20) from the table dept but using the clause FOR UPDATE SKIP LOCKED instead of FOR UPDATE NOWAIT. As you can see the following statement has

1. returned the control without throwing an exception
2. acquired lock on the row (i.e. deptno 20) which is available for locking
3. skipped the row (i.e. deptno 10) that has been locked already by session 1

Код: plaintext
1.
2.
3.
4.
5.
6.
    SELECT * FROM dept
     WHERE deptno IN ( 10 , 20 )
    FOR UPDATE SKIP LOCKED;

    DEPTNO     DNAME          LOC
    ---------- -------------- -------------
     20          RESEARCH       DALLAS
...
Рейтинг: 0 / 0
Такой случай...
    #33843723
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо
...
Рейтинг: 0 / 0
Такой случай...
    #33843724
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но, пожалуй, стоит отметить, что таскать с сервера по одной записи конкурирующими запросами - представляется мне одним из наименее эффективных возможных занятий.
...
Рейтинг: 0 / 0
Такой случай...
    #33843729
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, зависит от... Если сама обработка достаточно продолжительная, относительно обработки запроса СУБД -- почему бы и нет? Зато наверняка, особенно, если обработка идёт не многопоточным процессом, а несколькими процессами. Все процессы при этом абсолютно одинаковы, обработка распараллеливается на произольное количество обработчиков, если по каким-то причинам один из обработчиков помер в процессе, залоченная им запись освобождается по таймауту, и обрабатывается любым другим, не образуя гребёнку пропущеных записей и не требуя особой обработки подобной ситуации.
...
Рейтинг: 0 / 0
Такой случай...
    #33843731
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DocAlНу, зависит от... Если сама обработка достаточно продолжительная, относительно обработки запроса СУБД -- почему бы и нет?
Во-первых, я не особо в это верю - в этом случае автора вряд ли так уж интересовала бы эффективность именно работы с БД.

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

DocAlЗато наверняка, особенно, если обработка идёт не многопоточным процессом, а несколькими процессами.
Хм. C# и fork() - малость из разных партитур :)

DocAlесли по каким-то причинам один из обработчиков помер в процессе,
Хм. А может программировать так, чтобы этого не случалось?

DocAlи обрабатывается любым другим, не образуя гребёнку пропущеных записей и не требуя особой обработки подобной ситуации.
И без этого будет все то же самое. Естественный результат обработки - простановка флага "обработано"; запись без этого флага подхватится любым процессом, который вновь потянется за следующей порцией данных.

В то же время такой процесс естественно подразумевает и коммиты по каждому чиху; для Oracle такой режим не слишком удачен в смысле эффективности, да и, подозреваю, для любого другого сервера тоже (коммит означает одно из двух - либо необходимость гарантированно сбросить на диск все данные транзакции, то есть журнал, либо возможность потерять данные закоммиченной транзакции, что совершенно недопустимо).
...
Рейтинг: 0 / 0
Такой случай...
    #33843737
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer
DocAlесли по каким-то причинам один из обработчиков помер в процессе,
Хм. А может программировать так, чтобы этого не случалось?

М... Если имеется в виду, "так, чтобы обработчики не помирали", это не всегда зависит от разработчика, если же "чтобы помирание как-то обрабатывалось", создавать также некого пастуха, то не всегда это и надо.
softwarer
DocAlи обрабатывается любым другим, не образуя гребёнку пропущеных записей и не требуя особой обработки подобной ситуации.
И без этого будет все то же самое. Естественный результат обработки - простановка флага "обработано"; запись без этого флага подхватится любым процессом, который вновь потянется за следующей порцией данных.

В то же время такой процесс естественно подразумевает и коммиты по каждому чиху; для Oracle такой режим не слишком удачен в смысле эффективности, да и, подозреваю, для любого другого сервера тоже (коммит означает одно из двух - либо необходимость гарантированно сбросить на диск все данные транзакции, то есть журнал, либо возможность потерять данные закоммиченной транзакции, что совершенно недопустимо).
Ммм... А оракл не позволяет выставлять стратегию сохранения логов транзакции для отдельной сессии?
...
Рейтинг: 0 / 0
Такой случай...
    #33843741
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, забыл добавить, в предложенном вами в этой ветке методе, то есть, при распределении записей по остатку от деления нацело, то в нём никто не подхватит. Хотя, конечно, как вы и указали, это не единственный возможный вариант.
...
Рейтинг: 0 / 0
Такой случай...
    #33843877
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DocAlМ... Если имеется в виду, "так, чтобы обработчики не помирали", это не всегда зависит от разработчика,
Хм. Если полагать, что "не использовать левых библиотек" итп зависит от разработчика, то скорее таки всегда.

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

DocAlМмм... А оракл не позволяет выставлять стратегию сохранения логов транзакции для отдельной сессии?
Позволяет. Насколько я понимаю, это один из шагов в сторону облегчения работы криво написанных приложений, наподобие того же параметра cursor_sharing. Но это не значит, что этот режим стоит использовать.
...
Рейтинг: 0 / 0
Такой случай...
    #33843880
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DocAlДа, забыл добавить, в предложенном вами в этой ветке методе,
Хм. Я бы предпочел какое-нибудь другое слово, например "упомянутом". "Предложенном" - подразумевает положительное отношение к этому методу, в то время как я решительно не готов считать его удачным.

DocAlто есть, при распределении записей по остатку от деления нацело, то в нём никто не подхватит.
С какой это стати? Тот же процесс и подхватит.
...
Рейтинг: 0 / 0
Такой случай...
    #33846246
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer DocAlМ... Если имеется в виду, "так, чтобы обработчики не помирали", это не всегда зависит от разработчика,
Хм. Если полагать, что "не использовать левых библиотек" итп зависит от разработчика, то скорее таки всегда.

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

DocAlМмм... А оракл не позволяет выставлять стратегию сохранения логов транзакции для отдельной сессии?
Позволяет. Насколько я понимаю, это один из шагов в сторону облегчения работы криво написанных приложений, наподобие того же параметра cursor_sharing. Но это не значит, что этот режим стоит использовать.
Ну, мы с вами просто работаем в разных областях, со своей спецификой, у вас, видимо, все данные для обработки уже имеются на сервере, хранятся в упорядоченном виде в СУБД, и конечно тут скорость обработки зависит практически исключительно от системых ресурсов, выделенных на это, а надёжность этой обработки полностью в руках разработчика. Но так бывает не всегда. С другой же стороны, мне не очень понятно, почему, если категорически недопустимо потерять результат обработки каждой записи, не дёргать-таки сервер коммитом, после этой самой обработки, а если это не столь принципиально -- то не заставлять сервер сбрасывать на диск лог транзакций "от каждого чиха". Да, можно, конечно, просто дёргать его не каждый чих, а каждый десятый, или там, каждый сотый чих, но это ведь симптоматическое лечение, всегда есть шанс потерять результаты обработки 9 (99) записей, да и почему бы серверу самому не разобраться, когда ему дёргаться?
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Такой случай...
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]