Приемы обработки больших данных в 1С




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

25 Comments

  1. starik-2005

    Хорошая статья.

    Reply
  2. support

    Ну, вы выдали!

    Reply
  3. WKBAPKA

    мда 🙂

    Reply
  4. ZLENKO

    В пункт «Минимизация ожидания на блокировках данных» можно еще добавить «Используем версионную СУБД (например, база MS SQL Server в режиме версионирования)».

    В «Используем привилегированный режим» можно добавить «В свойствах документа устанавливаем галочки «Прив.режим при проведении» и «Прив.режим при отмене проведения»»

    Reply
  5. tormozit

    При версионную СУБД или режим действительно в тему. Спасибо. Дополню.

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

    Reply
  6. tormozit

    Добавил раздел «Многопоточный обмен данными» со схемой.

    Reply
  7. MaxS

    Здорово. Осталось найти такого идеального заказчика продукта, который морально, физически и материально готов поддержать все этапы оптимизации.

    Reply
  8. tormozit

    (7) Подозреваю, что имеются ввиду неудобные приемы типа удаления программного кода. Конечно такие приемы в большинстве случаев недостижимы в реальных рабочих базах на достаточно длительное время. Однако каждый из них мы применяли, например очистку программного кода в копиях рабочих баз и при создании начального образа периферийной базы. Естественно для каждой ситуации нужно подбирать подходящие приемы.

    Reply
  9. tormozit

    (9) Под обработкой в статье понимается обработка больших данных. «Отключение того, другого» — это некоторые из приемов, обещанные в анонсе к статье. При обработке больших данных участие человека (оператора) должно быть сведено к минимуму. Но кроме максимальной автоматизации обработки, важно обеспечить ее выполнение в имеющееся технологическое окно (например ночь между рабочими днями или серия выходных дней).

    Reply
  10. DrZombi

    (10)

    например ночь между рабочими днями или серия выходных дней

    Зачем? Для чего нужно такое, что бы по ночам загружать систему?

    На каждый процесс необходимо свой смысл. Каков смысл, ускорять автомат, «многопоточностью»?

    …восстановление последовательности под средством перепроведения документов?…

    …У 8.ххх уже ненужно фактически проводить документ, что бы формировать движения документа, быстрее всего выполнить манипуляцию по нужному регистру, нежели обрабатывать 100 ненужных проверок, преобразований, которые программисты 1С так наравят запихнуть в Процедуру Обработки проведения 🙂

    Reply
  11. Evil Beaver

    Не знаю, как кого, а меня пугают ситуации, как на картинке в начале… А ну как Старых напишет «ЗаменительРазработчика» на базе «Инструментов» и все, пиши-пропало)

    Reply
  12. kolya_tlt

    Добрый день.

    у вас были проекты по Многопоточному обмену данными? поделитесь опытом?

    Reply
  13. tormozit

    (13) Вроде бы в статье я им как раз поделился. Что еще интересует?

    Reply
  14. kolya_tlt

    (14) до самого подхода, что выгрузить данные из одного плана обмена порциями я додумался 🙂 а вот до организации выгрузки порциями руки не дошли 🙁 если поделитесь каким-то кодов или на пальцах расскажите «делал так, так и так» буду очень благодарен

    Reply
  15. n0ther

    Внезапная статья, но интересно. Спасибо

    Reply
  16. tank68

    Буду иметь в виду

    Reply
  17. alextalov

    Поздновато, но вставлю свои 5 копеек про многопоточность…

    Пару лет назад реализовывал свертку базы, вот некоторые особенности.

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

    Внутри блока сначала формируются наборы данных для обработки с изначально заданным количеством элементов. Например миллион документов разных видов можно раскидать на 1000 блоков, каждый блок содержит только набор определенных объектов.

    Данные наборы выстраиваются в очередь (чередуясь по типам объектов) и начинают последовательно заданным количеством фоновых заданий обрабатываться, при таком подходе можно в любой момент изменить количество потоков (фоновых заданий) для обработки. Такой подход обусловлен тем, что при наличии нескольких баз для обработки с разным железом, приходится для каждой индивидуально подстраивать оптимальное число потоков, при этом для удаления документов это будет одним числом, а для пересчета итогов другим. Перебрав с числом потоков не просто не будет роста, а начнется явное замедление из-за эскалации блокировок — они легко ловятся без профайлера по очереди задач в мониторе активности. Еще плюс такого подхода в том что вы всегда можете управлять количеством потоков, а следовательно и нагрузкой на железо, по факту если свертка не успевала закончиться до утра, то просто убавлялось количество потоков до 1-3 и пользователи могли спокойно работать пока база чистилась.

    p.s. авторы, спасибо, отличная статья

    Reply
  18. venvlad

    Интересно, спасибо)

    Reply
  19. DarkAn

    Статья интересна, давненько читал, из-за обновления вновь присоединился

    Если интересно, предлагаю ознакомиться с моей реализацией (http://infostart.ru/public/626117/).

    Основные особенности относительно описанной Вами реализации это:

    * Отсутствие необходимости разбивать Множество на порции;

    * Передача данных между потоками осуществляется средствами БД, а не файлов, при этом ни каких дополнительных таблиц создавать не надо.

    и бонус:

    * возможность настроить зависимость одних объектов от других.

    Буду рад за комментарии если они будут 🙂

    Reply
  20. Александр056

    1с сами пишут что платформа одно поточная, какая много поточность? все же скорее какие «финты ушами», которые полезны, но ребят, нет у нас много поточности, нету. Увы.

    Reply
  21. WKBAPKA

    (22) ну регламентные задания работают не в основном потоке приложения. где то на эту тему была статья… а саму эту статью не читал, много букф

    Reply
  22. its64

    авторы конфигурации Конвертация рассуждают о многопоточности и больших объемах данных!

    это та самая конфига которая в одном потоке может перегрузить 40000 доков всего за несколько дней? а 5 летнюю базу всего за 3 года? улыбнуло) господа как вам удалось ее вштырить во все типовые? за что вы так не любите людей?

    Reply
  23. WKBAPKA

    (24) в БСП вроде как реализована многопоточность, есть целая процедура, которая вызывает выполняет метод в фоне, но толи руки кривые, толи звезды не так встали, не работает как надо. Замораживает UI-поток. А что бы добавить эффекту, разрабы поставили фиксированное время в секундах на выполнение задания. Если у меня задание выполняется чучуть дольше, все привет.

    А регламентные задания все-же работают в отдельном потоке.

    Reply
  24. its64

    (25) многопоточность предполагает выполнение задачи не одном отдельном потоке а во многих отдельных потоках. столкнулся с переходом на связку розница <> УТ . 15000 доков в розницу загрузка заняла час или два . из розницы в ут эти доки ползут более 17 часов и конца не видно. из чего ставлю под сомнение работоспособность и надежность связки РТ УТ способом предложеным разработчиками с применением их «чудесной конвертации» основные принципы которой не менялись со времен 77. В результате авторы написали Рассказ об эффективных приемах организации обработок больших объемов данных на платформе 1С и они же написали конвертацию в которой не применен ни один из рассказанных приемов.

    Reply
  25. DoReMi

    Эх. Сдохли картинки.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *