Ускорение процесса восстановления последовательности в 1С 8 УПП с использованием параллельных вычислений   

   

Описание задачи

Есть ИТ система на базе MS SQL и 1С:УПП 8. В этой системе необходимо за большой интервал времени восстанавливать последовательность путем перепроведения большого количества документов. Как правило, это делается для расчета корректной себестоимости, искажения которой происходят по вине изменений документов задним числом.

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

Большинство специалистов скажут что нельзя. Часть специалистов скажет, что можно если проапгрейдить сервер (сразу отмечу, что данный вариант поможет несущественно, на 10-15%). Кто-то предложит сильно переписать код модуля проведения документов, что потенциально может сказаться на бизнес логике со всеми вытекающими отсюда последствиями.

На самом деле можно! Причем ускорить можно не на жалкие 10-15%, а в 3-5 раз. В некоторых случая можно добиться ускорения в 10 раз.

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

За счет чего можно ускорить данный расчет? – за счет параллельных вычислений!

Для начала рассмотрим концепцию без углубления в детали

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

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

Предположим мы выдали каждой сессии в виде задачи по одному документу. Если сессий 16, то высока вероятность, что из 16 документов половина будет независима друг от друга. Фактически 8 документов смогут проводится полностью параллельно. Как только сессия завершает проведение документа ей выдается новый документ. Предварительно он проверяется на то, что его данные не пересекаются с документами уже стоящими в очереди. Приведу простейший пример. Есть последовательность хронологически расположенная по возрастанию:


  • Приходная накладная №1 (Товар1,Товар2,Товар3)

  • Расходная накладная №1 (Товар11,Товар12,Товар13)

  • Расходная накладная №2 (Товар21,Товар2,Товар23)

  • Расходная накладная №3 (Товар31,Товар32,Товар33)

  • Расходная накладная №4 (Товар41,Товар42,Товар43)

  • Расходная накладная №5 (Товар51,Товар32,Товар53)

В этом примере можно документы разделить на следующие потоки:

Поток №1

Приходная накладная №1 (Товар1,Товар2,Товар3)

Расходная накладная №2 (Товар21,Товар2,Товар23) (пересечение по Товар2)

Поток №2

Расходная накладная №1 (Товар11,Товар12,Товар13)

Поток №3

Расходная накладная №3 (Товар31,Товар32,Товар33)

Расходная накладная №5 (Товар51,Товар32,Товар53) (пересечение по Товар32)

Поток № 4

Расходная накладная №4 (Товар41,Товар42,Товар43)

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

Итак, первый вывод: нам нужен планировщик задач, который будет брать документы небольшими порциями и раздавать их освободившимся сессиям. Но только одной этой меры не достаточно. Нам также важна хронология. Документ А стоящий в последовательности ранее Документа Б никогда не должен привестись позже. А ведь это вполне может произойти, например, если Документ А значительно больше и время его проведения соответственно больше. Для решения этой задачи необходимо реализовать координатор блокировок. Каждый документ перед началом проведения будет накладывать блокировки, соответствующие множеству табличной части товара. Если документ передаваемый координатором задач пересекается по блокировкам с уже проводящимися или ожидающими в очереди, то он будет становиться в очередь. Если же не пересекается то он будет выдаваться свободной сессии и начнет незамедлительно проводиться. Таким образом будет соблюдаться хронология проведения для взаимозависящих документов. Независимые друг от друга документы будут проводиться полностью параллельно.
Отсюда следует второй немаловажный вывод: уровень параллельности определяется спецификой данных. Однако эту тему мы разберем отдельно, позже.

В итоге концепция выглядит следующей

Создается определенный пул соединений 1С. Реализуется координатор задач. Каждой сессии изначально выдается свой документ. Координатор блокировок проверяет документы на предмет зависимости между собой. Выстраивается очередь. Все независимые документы проводятся параллельно. Как только сессия проводит очередной документ – срабатывает событие. По этому событию координатор задач выдает новый документ. Этот документ проходит проверку координатором блокировок, после чего становится, либо в очередь определенной сессии 1С, либо проводится параллельно в свободной сессии.

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

Выглядит это следующим образом:

На рисунке 1 показано, как трейдеры выстраиваются в одну общую очередь, и затем они встают в очередь к терминалам (рис.2). Очереди формируются в зависимости от запрашиваемого ресурса.

Трейдер с запросом к ресурсу "Яблоко" встал в очередь CPU_1. Образовалась очередь к терминалу. В эту очередь встал трейдер с запросами к "Апельсину" и "Яблоку". Если трейдер имеет интерес хотя бы к одному схожему ресурсу, он не может занять свободный терминал. К терминалу CPU_2 образовалась очередь к "Грушам". CPU_3 - "Апельсины", и CPU_4 - "Бананы".

Рисунок 3 иллюстрирует ситуацию, когда первые участники очереди - трейдеры, закончили свою работу на терминале, и после них встают следующие по очереди. Со временем появляется новый трейдер. Сначала он проверяет очереди на наличие такого же запроса к терминалу и если не находит (как в нашем случае), то занимает свободный терминал (рис. 3а).

К терминалам CPU_1, CPU_2 и CPU_4 стоят трейдеры, к первому с запросом на ресурс "Яблоко", ко второму на "Грушу", к четвёртому на "Бананы". Новый, входящий трейдер, интересуется ресурсом по конфетам. Не найдя трейдеров с похожим запросом, он встаёт к свободному терминалу CPU_3.


Рисунок 4 показывает ситуацию, описанную выше, с одним небольшим изменением. Новый трейдер имеет интерес к двум ресурсам, одним из которых интересуется трейдер из очереди к терминалу. Трейдер проверяет все очереди и не смотря на наличие свободного терминала встаёт за другим трейдером, так как он запрашивает тот же ресурс (рис. 4а). CPU_1 обрабатывает очередь с "Яблоками", CPU_2 обрабатывает очередь с "Грушами", CPU_3 свободный терминал, а CPU_4 обрабатывает очередь с "Бананами".

Новый трейдер имеет интерес к ресурсу "Конфеты" и "Яблоко". После проверки встаёт в очередь CPU_1, так как там трейдер с запросом к тому же ресурсу.

Рисунок 5 показывает ситуацию похожую на две предыдущих. Новый трейдер проверяет все очереди на наличие схожих запросов к ресурсу, находит, и встаёт в очередь. СPU_1 занят очередью на ресурс "Яблоко", а первый её участник так же работает с ресурсом – "Виноград". Входящий трейдер интересуется "Виноградом", поетому после проверки он встаёт в очередь к CPU_1.

На рис. 5а мы видим, как первый в очереди трейдер заканчивает работу с ресурсом и сообщает это всем остальным участникам очереди. Оставшиеся два трейдера не имеют общих запросов, поэтому, последний трейдер выходит из очереди, проверяет, есть ли трейдеры с общим интересом к терминалу, и не найдя таковых встаёт за свободный терминал (рис. 5б).

На терминале CPU_1 заканчивает работу с "Яблоком" и "Виноградом" первый трейдер. Он освобождает терминал и сообщает участникам очереди. Последний трейдер очереди CPU_1 выходит, так как нужный ему ресурс освободился, и перед ним нет трейдера в очереди к терминалу, имеющему интерес к "Винограду". Он встаёт за свободный терминал CPU_3.

Более подробное описание примера приведено ниже

Аналогично с этим примером работает подсистема технологии "Гибких блокировок", предназначенная для ускорения процесса восстановления последовательности. Итак, теперь распишу эту технологию более подробно.

Создается отдельный пул соединений 1С. Координатор задач выбирает из общей последовательности очередной документ. Далее координатор блокировок накладывает блокировки и проверяет нет ли пересечений по блокировкам с проводящимися или стоящими в очереди документами. Если блокировки не пересекаются, то документ выдается свободной сессии на проведение. Если блокировки пересекаются то тогда документ ставиться в очередь за связанным с ним документом. Если документ зависит от нескольких документов – ставится в очередь за последним по времени.

Теперь о нюансах

Сначала рассмотрим блокировочный механизм. Для данной технологии нельзя применять ни координатор блокировок от 1С 8, ни координатор блокировок от MSSQL. Это происходит потому, что необходимо проверять все множество товаров на вхождение хотя бы одного элемента, не просто для последнего в очереди. Необходимо смотреть пересечение по всему множеству товаров документов, стоящих в очереди. Приведу на примере блокировок MSSQL. Есть следующие документы:

  • Расходная накладная №1 (Товар1,Товар2,Товар3,Товар4)

  • Расходная накладная №2 (Товар4,Товар5,Товар6,Товар7)

  • Расходная накладная №3 (Товар7)


Допустим, блокировки накладываются слева направо. В этом примере Расходная накладная №2 станет в очередь за Расходной накладной №1, по пересечению на Товар4. При этом, она не наложит ни одной блокировки, потому как сразу повиснет на позиции Товар4. Расходная накладная №3 может успеть провестись ранее Расходная накладная №2, что конечно будет не верно, ведь у них есть пересечение по Товар7. А провестись она может ранее, потому как по размеру она меньше и на Товар7 не была наложена блокировка.

Координатор от 1С тоже не подходит потому, как в момент ожидания на блокировке не накладываются блокировки намерением от ожидающей сессии. Ну и потому, что очередь работает по LIFO. Поэтому в технологии "Гибких блокировок" для этой задачи применяется свой отдельный координатор блокировок.

Есть и другие нюансы

Очевидно, что необходимо обрабатывать событие завершения проведения документа в сессии. Только обрабатывать его можно по разному. Допустим, просто брать из последовательности новый документ и обрабатывать по ранее описанному алгоритму. Или же можно перестраивать очередь ожидания. Ведь документ, который был проведен, мог влиять на стоящие в очереди документы.

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

Есть 4-е сессии 1С на 4-е процессора. Предположим, в какой-то момент времени координатор задач распределил документы следующим образом.

Сессия 1

Расходная накладная 1(Товар1, Товар2,Товар3)

Расходная накладная 2(Товар3,Товар21,Товар22)

Сессия 2

Расходная накладная 3(Товар31, Товар32,Товар33)

Расходная накладная 4(Товар33,Товар41,Товар42)

Сессия 3

Свободна, ожидает очередного документа.

Сессия 4

Свободна, ожидает очередного документа.

В этом случае мы видим, что простаивают две сессии и соответственно 2 процессора. Логично что координатор должен взять следующий документ из последовательности и распределить по свободным сессиям. Сколько именно документов он должен обработать? Если следующие два документа будут полностью независимыми - это хорошо. Они будут выполняться на двух свободных сессиях, тем самым обеспечат более эффективное использование серверных ресурсов. К примеру, если эти два документа:

Расходная накладная 5(Товар61, Товар62,Товар63)

Расходная накладная 6(Товар73,Товар71,Товар72)

Но что произойдет если мы обработаем следующие 30 документов, и все они выстроятся в очередь Сессия №1 и Сессия №2? В этом случае множество занятых товаров существенно увеличиваться. Для каждого нового документа координатор будет делать проверку по значительно большему множеству товара, что в итоге увеличит время поиска вхождений, а также увеличит накладные ресурсы.

Общий итогнеобходим некоторый компромисс.

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

Уровень параллелизма не является величиной постоянной. Он может существенно отличаться, в зависимости от времени. Это может быть обусловлено и спецификой бизнес процессов. Например, если привезли популярны (продаваемый) и при этом дефицитный товар – пока менеджеры не продадут или не зарезервируют весь товар, то до тех пор уровень параллелизма снизится. Если на данный момент проводится акция - это может сильно повлиять на распределение товаров. Если, предположим, в каждом втором документе есть "пакет полиэтиленовый" - это крайне негативно повлияет на уровень параллелизма. В этом случае необходимо искать компромиссы – например исключать эту позицию из блокировочного механизма. В этом случае обоснований может быть несколько.

Также, хотелось бы отметить, что описанная технология для 1С УПП является лишь одной из составляющих комплексной технологии "гибкие блокировки".

 


 

Перепечатка, воспроизведение в любой форме, распространение, в том числе в переводе, любых материалов с сайта www.softpoint.ru возможны только с письменного разрешения компании "СофтПоинт". Это правило действует для всех без исключения случаев, кроме тех, когда в материале прямо указано разрешение на копирование (основание: Закон Российской Федерации "Об авторском праве и смежных правах").

Статья: Ускорение процесса восстановления последовательности в 1С 8 УПП с использованием параллельных вычислений

Перейти на главную страницу компании "Софтпоинт"