Имя: Пароль:
1C
1С v8
Как передать в фоновое задание большую таблицу значений (12 млн записей)
,
0 Solemn
 
12.11.14
14:24
Добрый день коллеги, пытаюсь с помощью многопоточности ускорить обработку таблицы значений, но встал вопрос как эту таблицу передать в фоновое задание, через параметры если передавать, то пожирается гигов 30 памяти на сервере 1С и повисает, запуска самих заданий не дождался, есть какие идеи?
151 zsergey
 
13.11.14
13:49
(55) <<Мне то они не нужны, типовой расчет себестоимости в упп 1.3
152 zsergey
 
13.11.14
13:49
+ в каком именно регистре столько записей?
153 tridog
 
13.11.14
13:51
(148) Если правильно понимаю - это плата за кластер
154 H A D G E H O G s
 
13.11.14
13:51
Копирование ТЗ в памяти - это глупости и мелочи, это не о чем.
А вот передача ТЗ через временное хранилище вызовет ее сериализацию (самое забавное, что 1С скорее всего делает тупо инкремент результирующей строки, вызывая realloc) и передачу строки в соседний процесс.

И это логично и понятно.
155 H A D G E H O G s
 
13.11.14
13:52
(153) Да. Но, балин, че бы не разрулить эту ситуевину через глобальные временные.
156 H A D G E H O G s
 
13.11.14
13:53
(153) Или хоть бы теже локальные, доступные пока сеанс 1С не ушел на другой сеанс SQL.
157 tridog
 
13.11.14
13:57
(154) Фоновое задание может запустить на другом rphost'е. А еще - перед вызовом все параметры фонового задания передаются в rmngr и удерживаютя в нем - фиг знает сколько времени после того, как задание выполнится, можно прочитать его параметры через ФоновыеЗадания.Получить() - именно за счет того, что параметры удареживаются в rmngr.

Поэтому все, что передается параметром фонового задания не может быть просто скопировано в памяти - только сериализация, только хардкор)
158 H A D G E H O G s
 
13.11.14
13:58
(157) У меня там приписка:

И это логично и понятно.
159 cons74
 
13.11.14
14:03
тз хз фз тч xdto...
160 tridog
 
13.11.14
14:35
(158) упс, не заметил)
161 MM
 
13.11.14
14:39
(154) На другом компьютере с другой битностью, и даже на другую ОС.
(155) А они точно есть под Постгре и ДБ2? Решение-то задумано как универсальное.
162 H A D G E H O G s
 
13.11.14
14:41
(161) "На другом компьютере с другой битностью, и даже на другую ОС. "

Не понял вопроса.

(155) "А они точно есть под Постгре и ДБ2? Решение-то задумано как универсальное."

А ХЗ. Даже если так - Постгре и ДБ2 вместе с Линуксом идут лесом. Микрософт - наше фсё!
163 Solemn
 
13.11.14
14:48
(36)>"Пусть фоны читают ТЗ и ждут, пока все флаги в служебном регистре сведений не установятся в "Можно писать""

Не догоняю как организовать 1С-ным кодом чтобы фоны "ждали"

(152) УчетЗатратРегл например
164 MM
 
13.11.14
14:50
(162) То что сериализация решает проблему с длинной указателей (связывающих структуры данных, из которых состоит объект), порядком байт и способом хранения в развёрнутом виде у получателя этих передаваемых данных.
1С стремилось к кроссплатформенности. А плата как обычно эффективность.
165 DrZombi
 
гуру
13.11.14
14:50
(149) Приведенный код состоит из разных частей :)
Один код, где объявлен "&НаКлиене НаСервере". Выполняется на форме ;)
Где этого кода нет, выполняется в модуле обработки.
166 DrZombi
 
гуру
13.11.14
14:52
(150) Не будет, если напишешь правильно, то нечего не будет лишнего сдаваться. :)
И что значит создавать?
Тебе нудно просто получить ТЗ, вместо объекта на форме. :)
167 H A D G E H O G s
 
13.11.14
14:52
(164) Нет. Сериализация решает проблему прежде всего с отсутствием объекта в памяти, на который ссылается ячейка таблицы значения. И уже потом длины указателей.
168 DrZombi
 
гуру
13.11.14
14:52
+(166) Не забывай, фоновое задание, это как бы отдельный пользователь.
169 MM
 
13.11.14
14:59
(167) Т.е. если скопировать память объекта из 32х битного процесса в 64х битный, в которой будут находится указатели или целые числа, длина которых зависит от архитектуры процессора, то проблем не будет? Там же всё сползёт.
Если сериализация почему-то табу, то указатели можно попробовать заменить на дескрипторы, без привязки к адресу памяти, тогда данные можно будет копировать memcpy, но это уже в порядке бреда.
170 H A D G E H O G s
 
13.11.14
15:08
(169) Длина целых чисел не зависит от процессора.
А вот размер указателя - да.
И в этом случае все равно можно извратиться - резервируя 4 лишних старших байта возле указателя возле 32-х разрядного процесса. Но все равно, для длинных строк придется выделять динамическую память и заполнять указатели новыми значениями. Но это все равно на порядки быстрее, чем сериализация.
171 H A D G E H O G s
 
13.11.14
15:09
(170) Но это не решает проблему непримитивных типов, которые могут содержаться в ячейке таблицы.
172 MM
 
13.11.14
15:18
(170) Размер int зависит от компилятора. Никто не мешает ему сделать 64-битный int на 32-хразрядной машине. И наоборот. Многие компиляторы для 64-битных платформ все равно оставляют int 32-хбитным.
http://rsdn.ru/forum/cpp/2334752.flat
Или авторитетнее: http://ru.cppreference.com/w/cpp/language/types
(171) Непримитивный тип - это объект, значит в ячейке хранится ссылка на него. А как эта ссылка технически реализована это уже детали, может как указатель на память, а может, как гуид объекта, который был ему задан в процессе сериализации.
173 H A D G E H O G s
 
13.11.14
15:24
(172)
"Размер int зависит от компилятора. Никто не мешает ему сделать 64-битный int на 32-хразрядной машине. И наоборот. Многие компиляторы для 64-битных платформ все равно оставляют int 32-хбитным. "

Итить колотить, да какая разница. Речь о данных, а не о коде.

Это я к тому, что системе пофиг, какие там данные, ей важно чтобы указатели/дескрипторы/callback параметры были нужной размерности.
174 MM
 
13.11.14
15:34
Так и я о данных, rphost 32х не обязан создавать точные аналоги структур ДАННЫХ используемые под 64х, тут ведь глядишь и 128-битные процессоры выпустят. )
И не забываем про Линукс. Не думаю, что указатели/дескрипторы/callback имеет смысл переносить между компьютерами.
А ещё многие просят платформу под Мак, там, кажется, даже порядок байт в числах может быть другим. wiki:Порядок_байт
175 К_Дач
 
13.11.14
15:44
(168) 1 сеанс получает ТЗ, передает на сервер 1С и кладет во временное хранилище. Как тут уже выше писали, это сериализация в строку в чистом виде, передача строки из 12 млн записей - не думаю, что это быстро, это раз... уж если xml-ка с 5 млн записей регистра весила у меня порядка 10 Гб, то тут.....

все последующие сеансы (фоны) должны работать с ТЗ, а не со строкой из ВХ, следовательно, они должны оттуда ее достать, твоя строчка Тз = Фон.Выгрузить() как раз это и делает. Тз грузится в ОЗУ, а значит каждый фон сожрет все ОЗУ на сервере 1С.

Или я что-то в твоем коде не увидел особенного?
176 H A D G E H O G s
 
13.11.14
15:48
(175) Передача строки из 12 млн записей - это быстро.
Медленно - это формирование строки, особенно если инкрементом.
177 H A D G E H O G s
 
13.11.14
15:50
Кстати, менеджер rmmngr мог бы работать с rphost-ами через именованные каналы, но я не заметил этого. Надеюсь, он работает через shared memory.
178 H A D G E H O G s
 
13.11.14
15:52
Эххх, поработать бы мне разработчиком платформы, я бы там такого наворотил! А потом бы вы все плакали горючими слезами.
179 К_Дач
 
13.11.14
15:53
(177) имхается, что shared memory все же, недаром советуют ее включать в случае разворачивания элементов кластера на 1 физическом сервере
180 Serginio1
 
13.11.14
15:55
(177) Для этого нужен свой менеджер памяти как в Delphi
http://rsdn.ru/article/Delphi/memmanager.xml

или Exchange Heap


http://rsdn.ru/article/singularity/singularity.xml#EFKAC
181 H A D G E H O G s
 
13.11.14
15:56
(179) Это между сервером 1С и SQL.
182 DrZombi
 
гуру
13.11.14
15:56
(177) Теоретически он не должен работать вообще :)
183 DrZombi
 
гуру
13.11.14
15:56
+(182) Между заданиями
184 H A D G E H O G s
 
13.11.14
15:56
(180) Это для какого случая?
185 H A D G E H O G s
 
13.11.14
15:58
(180) Именнованные каналы шикарны. Там уже все реализовано (передача данных, синхронизация) на уровне ОС, там даже данные по сети можно передавать.
186 MM
 
13.11.14
16:08
(185) И опять я со своим дёгтем, это должно как-то работать в Линуксе, так что каналы не подходят. А общая память пойдёт только в пределах одной машины, а значит будет писаться когда отладят межмашинное взаимодействие.
Я Линукс не знаю, но 1С почему-то радеет за кроссплатформенность.
Кстати, именованные каналы у меня зависали чаще, чем сокеты на UDP.
187 H A D G E H O G s
 
13.11.14
16:13
(186) А я счаст говорю о уровне
менеджер кластера- процессы сервера 1С.
188 Serginio1
 
13.11.14
16:13
(185) Ты плохо прочитал про Exchange Heap  это использование общей памяти между доменами, а не просто передача.

Передача по каналам например тебе нужно все равно сериализовывать, ибо в 1С для объектов идет подсчет ссылок, свой менеджер памяти итд.
Можно так передавать только массив структур Валуе типов.
Проблема все этой темы это глобальные временные таблицы которых нет в 1С.
189 H A D G E H O G s
 
13.11.14
16:16
(188) Да понятно, что нужно сериализовывать.
190 Гёдза
 
13.11.14
16:19
(188) может в 8.4 будут )))
191 Гёдза
 
13.11.14
16:19
я так и не понял почему от регистра отказались?
192 H A D G E H O G s
 
13.11.14
16:23
(191) Там всякие гейтсо-мерские индексы будут обновляться.
193 tridog
 
13.11.14
16:24
(178) И что же мешает?)
194 Serginio1
 
13.11.14
16:25
(190) Можно конечно внешние источники использовать, но как там с типизацией, как впрочем и для глобальных таблиц?
(191) Наверное потому, что в отличие от временных таблиц у 1С нет массовой записи в регистр из тз.
Самому приходилось через булки и Merge обновлять регистры напрямую.
195 MM
 
13.11.14
16:27
(187) Так рабочие процессы могут работать на серверах в сети, для масштабируемости и отказоустойчивости, отделённых от менеджеров кластеров. Даже менеджеры кластера можно сделать различными и разнести по разным компьютерам, раздав им свои сервисы, вроде сервисов нумерации, работы с внешними источниками, блокировок разных видов и т.д.
А ещё там есть передача сеансовых данных от главного менеджера к резервному, она тоже требует сериализации.
196 Serginio1
 
13.11.14
16:29
194 Вернее он есть, но такой медленный. Там мало того, что по 1 записи, попутно удаляя старые записи. Нет Merge.
А учитывая индексы там можно просто вешаться на 12 миллионах. По 3 часа помню на 4 миллионах было.
197 К_Дач
 
13.11.14
16:59
(194) а как ты сам писал регистратора или ссылочные типы?
198 Solemn
 
13.11.14
17:06
(133) Только так и проводим
199 Serginio1
 
13.11.14
17:27
(197) Я писал в регистр сведений.
Типа такого
Стр="
     |BEGIN TRAN;
     |If OBJECT_ID('TempDB.dbo.#TempPrice') is not NULL DROP TABLE  #TempPrice;
     |Declare @ТекущаяДата as datetime= GetDate()
     |Declare @Прайс as binary(16) = "+ПолучитьGUIDПоУникальномуИдентификатору(ТипЦен.УникальныйИдентификатор())+"
     |Declare @Импорт as Binary(1) ="+ ?(ТипЦен.Импорт,"0x01","0x00")+";
     |Declare @x as int= (Select Count(*) From dbo."+СтрРегПрайсов.ИмяТаблицыХранения+ " WITH (UPDLOCK)
     | where "+РегПрайсовПоля.ТипЦен+"=@Прайс);";

     Если МейкУстановлен Тогда
         Стр=Стр+"
         |Declare @Мейк as binary(16) = "+ПолучитьGUIDПоУникальномуИдентификатору(УстановленМейк.УникальныйИдентификатор())+";";
     КонецЕсли;
     СтрАртикул=ТзЗагрузКолонок[0];
     СтрСелект="SELECT distinct "+СтрАртикул.СтрокаПоля+",@Прайс as Прайс,";
     Если МейкУстановлен Тогда
         СтрСелект=СтрСелект+"@Мейк as Мейк"
     Иначе
         СтрСелект=СтрСелект+"ТаблицаМейков._IDRRef as Мейк";
     КонецЕсли;
    
     Для сч=4-1 По ТзЗагрузКолонок.Количество()-1 Цикл
         Строка=ТзЗагрузКолонок[сч];
         Если Строка.Использование Тогда
             СтрСелект=СтрСелект+","+Строка.СтрокаПоля
         КонецЕсли;
     КонецЦикла;
    
     Стр=Стр+"
     |"+СтрСелект+"
     |INTO #TempPrice
     |FROM OPENROWSET( BULK N'"+ФайлСПрайсом+"',
     |FORMATFILE = N'"+ИмяФайлаФрмата+"',";
200 Serginio1
 
13.11.14
17:29
201 К_Дач
 
13.11.14
17:33
(200) я имел ввиду как ты Справочник.Номенклатура например преобразовывал в binary(16), там же в поле таблицы, соответствующей ссылочному измерению этот тип
202 Serginio1
 
13.11.14
17:43
(201)
Функция ПолучитьGUIDПоУникальномуИдентификатору(UUID1)
    UUID=ВРЕГ(UUID1);
    ч1 = Сред(UUID,20,4);
    ч2 = Сред(UUID,25,12);
    ч3 = Сред(UUID,15,4);
    ч4 = Сред(UUID,10,4);
    ч5 = Сред(UUID,1,8);
    Возврат "0x" + ч1 + ч2 + ч3 + ч4 + ч5;
КонецФункции
203 Целина
 
13.11.14
17:43
(0)у тебя ответ в вопросе
алгоритм допускает многопоточную обработку
(кстати любой)
нужно или до создания таблицы его изменить так чтобы было много мелких таблиц
или передавать частями
а лучше выпилить таблицы значений и вычислять всё в скулях
204 Целина
 
13.11.14
17:45
проблему с недокументированными ссылочными полями можно решить. сделать записей сколько нужно где нужно платформой а потом их проапдейтить скулем.
205 Reaper_1c
 
13.11.14
17:51
(198) Какой из процессов ты надумал распустить на потоки? А то я слабо верю, чтобы матрица системы одного узла корректировки стоимости набрала 12 миллионов строк...
206 Reaper_1c
 
13.11.14
17:58
В (205) фигню ляпнул - имелся в виду не узел а выделенный граф из всего расчета. Или ты кораблестроение автоматизируешь?
207 Solemn
 
13.11.14
18:04
(206) 12 млн это количество записей в регистре УчетЗатратРегл перед сверткой
208 Целина
 
14.11.14
10:37
(207)и что их сразу на сервере прочитать нельзя??? )))
209 Serginio1
 
14.11.14
10:42
(0) Сериализуй в файл
ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.ОткрытьФайл(ИмяФайла);
   СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Источник);
   ЗаписьXML.Закрыть();

А в параметрах передавай ИмяФайла и загружай сериализатором через чтение файла
210 Solemn
 
14.11.14
11:08
(208) Можно, но только 1 раз, потом они будут изменены, это уже обсуждалось выше
211 Solemn
 
14.11.14
11:30
+(210) в одном фоне можно прочитать
212 Serginio1
 
14.11.14
11:44
(211) Можешь и в разных. Скорее всего ЧтениеXML открывается только на чтение.
213 tridog
 
14.11.14
11:51
(209) Это будет работать до появления второго сервера в кластере
214 Serginio1
 
14.11.14
11:58
(213) Всмысле? Что при этом с файлом случится?
215 tridog
 
14.11.14
12:10
(214) Он останется на том сервере, на котором был создан.
А фоновое задание запустится на другом сервере. На котором этого файла отродясь не было.
216 Serginio1
 
14.11.14
12:21
(215) Угу то есть если ты файл записал в расшаренную то ты этот файл не увидишь? Есть еще FTP, НTTP ресурсы
217 tridog
 
14.11.14
12:54
(216) Из расшаренной - увидишь, если она будет доступна с обоих серверов. Только это:
1. Снижает надежность - появляется еще одна точка отказа
2. Усложняет развертывание - представь, что в серверной был пожар и надо срочно все поднять из бекапов - про расшаренную папку никто и не вспомнит
3. Не по феншую
218 Serginio1
 
14.11.14
13:27
(217) Главное, что бы работало, а все остальное это уже поиски фэншуя. Так или иначе, большинство файлов держат не в базе а рядом с ней. Например
Хранилище FILESTREAM объединяет компонент SQL Server Database Engine с файловой системой NTFS, размещая данные больших двоичных объектов (BLOB) типа varbinary(max) в файловой системе в виде файлов. С помощью инструкций Transact-SQL можно вставлять, обновлять, запрашивать, выполнять поиск и выполнять резервное копирование данных FILESTREAM. Интерфейсы файловой системы Win32 предоставляют потоковый доступ к этим данным.

Для кэширования данных файлов в хранилище FILESTREAM используется системный кэш NT. Это позволяет снизить возможное влияние данных FILESTREAM на производительность компонента Database Engine. Буферный пул SQL Server не используется, поэтому данная память доступна для обработки запросов.


http://technet.microsoft.com/ru-ru/library/bb933993(v=sql.105).aspx
219 Serginio1
 
14.11.14
13:38
220 Целина
 
14.11.14
14:10
(210)
не читал всё внимательно
но
если ты держишь их в памяти в тз только чтобы иметь исходник сделай регистр2 и храни там
221 Solemn
 
14.11.14
15:12
(220) большая потеря времени на запись в регистр2, теряется смысл многопоточности, время работы в итоге не уменьшается, а может еще и увеличится
222 arsik
 
гуру
14.11.14
15:15
самое нормально мне кажется напрямую с SQL работать. Вытащить там все данные во временную таблицу внутри SQL и уже фоновыми оттуда забирать то что нужно.
223 H A D G E H O G s
 
14.11.14
15:17
Можно вопрос - а что мешает прочитать по частям этот УчетЗатрат в несколько потоков?
224 H A D G E H O G s
 
14.11.14
15:17
(223) Если там алгоритм обработки можно распаралелить.
225 Гёдза
 
14.11.14
15:19
(221) у тебя небось регистр со всеми полями - измерениями?
226 Лефмихалыч
 
14.11.14
15:19
(223) гы, я уже спрашивал на первой странице
227 arsik
 
гуру
14.11.14
15:21
(223) Я так понимаю. он динамично меняется. Надо одномоментно прочитать, и потом уже разбиратся с тем что прочитали. Иначе из этих частей не соберется исходный массив.
228 H A D G E H O G s
 
14.11.14
15:33
(227) Из родительского процесса наложить разделяемую блокировку.

Фоновые процессы прочтут регистр накопления и отчитаются в Регистр сведений.

Родительский процесс ждет отчета от всех фоновых и снимает блокировку.
229 Целина
 
14.11.14
15:51
(221)пиши скулем какие проблемы?
230 Целина
 
14.11.14
15:54
(223)(224)для этого нужен мозг
(228)сабж предполагает волшебную галочку типа птичка типа чекбокс в настройках сервера
231 H A D G E H O G s
 
14.11.14
16:01
(230) "типа птичка типа чекбокс в настройках сервера"

Это какую?
232 tridog
 
14.11.14
16:05
(228) Вот мы и дошли до изобретения RPC) Как предлагаешь из фоновых передавать инйормацию в родительский?)
233 H A D G E H O G s
 
14.11.14
16:08
(232)
Написал же, регистр сведений.
234 Целина
 
14.11.14
16:12
судя по вопросам автор сабжа со всем отделом всё равно не справится )))
235 H A D G E H O G s
 
14.11.14
16:21
(234) Ты справишься еще меньше.
236 tridog
 
14.11.14
16:26
(233) Я тоже лучше ничего не придумал. RPC через базу данных. Тоска, пичаль.
237 Serginio1
 
14.11.14
16:33
(236) Лучше это прямой доступ к БД и использование всей мощи SQL
238 Целина
 
14.11.14
16:35
(235)тогда поставь сервак 64 и подкачку 100 и жди )))
авось!
239 tridog
 
14.11.14
16:36
(237) SQL-сервер не есть "серебрянная пуля"
Если задача реально обеспечить параллельность - то чем он тебе поможет?
240 Serginio1
 
14.11.14
16:40
(239) А  транзакции и блокировки для кого придуманы?
241 Serginio1
 
14.11.14
16:42
Вернее уровни изоляции транзакции
242 Целина
 
14.11.14
16:50
(239)ну если распараллелить расчеты лень то можно дать скулям посчитать.
мы же не знаем нафига ему эта таблица и насколько он знает скуль.
выигрыш там будет несколько порядков. естественно на апдейтах. ибо не исключено что с помощью курсоров он и там сервак повесит.
243 Solemn
 
14.11.14
17:00
(228) Расчет происходит ВНЕ ТРАНЗАКЦИИ, блокировки не сработают, плюс таймаут (если бы было в транзакции) никто не отменял
(232) Для получения из фоновых в родительский обычно используется ПоместитьВоВременноеХранилище
(234) Вы предлагаете свою помощь? Справитесь? :)
(240) Расчет ВНЕ ТРАНЗАКЦИИ
(242) :) нет доступа к БД, так что ваш совет не подходит
244 Serginio1
 
14.11.14
17:02
(243) Так десериализацию из файла не пробовал?
245 H A D G E H O G s
 
14.11.14
17:03
(243) Расчет происходит ВНЕ ТРАНЗАКЦИИ.

Как это относиться к тому, что я написал в (228)?
246 H A D G E H O G s
 
14.11.14
17:04
(243) Таймаут реализуй через скрипт.
247 Solemn
 
14.11.14
17:08
(245)управляемые блокировки работают только в транзакции
248 Господин ПЖ
 
14.11.14
17:10
>нет доступа к БД

разверни рядом другой экземпляр скуля, суй в него
249 H A D G E H O G s
 
14.11.14
17:10
(247) Используй
НачатьТранзакцию();
250 Целина
 
14.11.14
17:33
(243)у тебя его нет потому что тебе он не поможет.
тем кто умеет его готовить дают.
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.