|
Как передать в фоновое задание большую таблицу значений (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)у тебя его нет потому что тебе он не поможет.
тем кто умеет его готовить дают. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |