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

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

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

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

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

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

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

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

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

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

PS если используете MS SQL, читайте про READPAST
...
Рейтинг: 0 / 0
04.07.2006, 16:55
    #33830820
DocAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Такой случай...
softwarerПодозреваю, с точки зрения производительности (которая, вроде как, очень важна) стоит убрать некую программу и делать все на сервере БД. Для случайно выбранной задачи это обеспечит такой прирост быстродействия, что не будет нужно ни тредов, ни чего либо еще. А иначе следующей задачей поставите кластер, чтобы распихать треды по разным машинам.
Ну, не всегда время обработки ограничивается только ресурсами системы... Впрочем, раз тредстартер это не упомянул, у него не такой случай.)
...
Рейтинг: 0 / 0
10.07.2006, 19:48
    #33843547
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Такой случай...
Уточните вопрос, пожалуйста.
- Вам нужна очередь с однократной выборкой каждой поставленной в нее строки?
- Или есть другие критерии, которые определяют, какие строки выбираются для какого потока?
-Важно ли, чтобы строки выбирались на обработку в том порядке, в котором пришли.
- Сколько строк за один раз выбирает поток?
- Какова интенсивность добавления строк в таблицу?
И вообще, какую задачу пытаетесь решить?
...
Рейтинг: 0 / 0
10.07.2006, 20:38
    #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
10.07.2006, 23:58
    #33843716
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Такой случай...
В Oracle есть. Если мне не изменяет память, в одной из бесед упоминали про такую возможность и для MSSQL.
...
Рейтинг: 0 / 0
10.07.2006, 23:59
    #33843718
DocAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Такой случай...
А можно пример?
...
Рейтинг: 0 / 0
11.07.2006, 00:03
    #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
11.07.2006, 00:05
    #33843723
DocAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Такой случай...
Спасибо
...
Рейтинг: 0 / 0
11.07.2006, 00:07
    #33843724
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Такой случай...
Но, пожалуй, стоит отметить, что таскать с сервера по одной записи конкурирующими запросами - представляется мне одним из наименее эффективных возможных занятий.
...
Рейтинг: 0 / 0
11.07.2006, 00:16
    #33843729
DocAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Такой случай...
Ну, зависит от... Если сама обработка достаточно продолжительная, относительно обработки запроса СУБД -- почему бы и нет? Зато наверняка, особенно, если обработка идёт не многопоточным процессом, а несколькими процессами. Все процессы при этом абсолютно одинаковы, обработка распараллеливается на произольное количество обработчиков, если по каким-то причинам один из обработчиков помер в процессе, залоченная им запись освобождается по таймауту, и обрабатывается любым другим, не образуя гребёнку пропущеных записей и не требуя особой обработки подобной ситуации.
...
Рейтинг: 0 / 0
11.07.2006, 00:26
    #33843731
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Такой случай...
DocAlНу, зависит от... Если сама обработка достаточно продолжительная, относительно обработки запроса СУБД -- почему бы и нет?
Во-первых, я не особо в это верю - в этом случае автора вряд ли так уж интересовала бы эффективность именно работы с БД.

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

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

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

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

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

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

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

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

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

DocAlто есть, при распределении записей по остатку от деления нацело, то в нём никто не подхватит.
С какой это стати? Тот же процесс и подхватит.
...
Рейтинг: 0 / 0
11.07.2006, 20:17
    #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]