Специфика проекта
Это крупная розничная сеть, у которой на тот момент было уже довольно много магазинов, и шел их активный прирост – не то что с каждым месяцем, буквально с каждой неделей, причем даже не отдельными магазинами, а сразу десятками. И, соответственно, этот рост закономерно уперся в технологическую и техническую инфраструктуру. Приближался сезон, и заказчик сказал: «ребята, у вас есть немного времени, предложите что-нибудь подходящее».
Целью проекта было сделать эту инфраструктуру более управляемой, а также необходимо было позволить компании расширить используемую аналитику. Иначе говоря, они не видели остатки товаров, которые у них были на тот момент на складе, в разрезе характеристик и размеров,иим было довольно сложно этим управлять. Например, когда у вас есть 500 магазинов, покупатель приходит в один из них, и продавец ему даже не может сказать, есть ли конкретный размер на складе, и если нет, то на каком из других адресов он может быть, то для компании это, конечно, было большой проблемой. Из-за этого торговля шла хуже, и приходилось устраивать распродажи, чтобы те остатки, которые накапливались, как-то сбывать со складов.
Этот проект было необходимо реализовать за три с небольшим месяца. Условно его можно было разбить на три части.
- Первая часть – добавить эту необходимую аналитику.
- Вторая – пересмотреть саму инфраструктуру
- И третья часть касалась оптимизации. Она шла несколько позже, но о ней я тоже расскажу. Эта часть также была необходимым элементом общей системы.
Описание текущего состояния учета перед началом проекта
Положение в начале проекта было довольно веселое. Это был яркий пример «зоопарка систем»:
- Основная база была – УПП (больше 700 ГБ на тот момент). Она очень активно использовалась, в ней многое делалось;
- Также использовалась периферийная база в виде Розницы – это была распределенная база, у каждого магазина стояла своя файловая версия, и все это между собой каким-то образом обменивалось (всего получалось почти 500 баз);
- И еще там использовался целый ряд различных систем для других сервисов, включая базу для интернет-магазина и т.д.
И все это нужно было приводить в порядок.
Введение учета по характеристикам
Начали мы с характеристик, потому что заводить их было необходимо. И первое, с чем мы всерьез столкнулись, – это альтернативность решений.
Вроде бы, что такого? Включили в системе характеристики, вот и заводите теперь туда размеры, в чем проблема?
- А проблема была в том, что при таком объеме работы бухгалтерам показалось не очень интересным вводить в документы в 10 раз больше строк, и они, мягко говоря, против этого протестовали. Это – первый момент.
- А второй момент выходит из первого, потому что когда поступление делается на основной склад, и бухгалтеры не готовы заводить товары по размерам, то возникает вопрос – каким образом эти размеры должны появиться?
В результате было предложено решение, названное «пирамида складов»: когда на главном складе размеров еще нет, а на региональных складах и в магазинах эти размеры уже есть. Реализация этого решения предусматривала то, что характеристики включать нужно, но нужно изменить проведение. И изменить его нужно аккуратно, потому что мы не могли допустить серьезного увеличения нагрузки на систему, которая и без того «ворочалась» уже не очень хорошо.
Начали «растаскивать букет на части» путем изменения механизмов проведения. В чем это заключалось?
- По сути, для регистра бухгалтерских партий характеристики не проводились вообще никогда – там всегда проводилась только номенклатура (и при приходах, и прирасходах).
- А для управленческих партий это выглядело несколько иначе. В справочник складов был добавлен реквизит и, в зависимости от того, включен он или не включен, проверялось:
- Если реквизит включен, то для этого склада характеристики проводились;
- А если он не включен, то не проводились.
- Интересная ситуация возникала тогда, когда производилось перемещение между разноименными складами, на одном из которых характеристик не было, а на другом –были. Для того чтобы разрешать такие ситуации, пришлось прилично «похимичить» в партионном модуле, но мы аккуратно «скальпелем все обрезали», и стало проводиться довольно красиво.
При оформлении перемещения между такими складами характеристики указывались в любом случае:- Если перемещалось на склад «без характеристик», то они указывались для того, чтобы все корректно списывалось,
- А если перемещалось на склад «с характеристиками», то они указывались для того, чтобы товары правильно приходовались (чтобы этим потом можно было как-то еще управлять).
В принципе, задача была реализована, и это уже стало серьезным «толчком» вперед.
Однако возникал вопрос по поводу «бесшовного перехода» регионов на учет по характеристикам. Что помогло в его решении:
- Первое – это ориентир на наличие дополнительного реквизита в складах.
- А все остальное было решено с помощью центральной базы РИБ, которая использовалась и до этого. В частности, от нее решили не отказываться в пользу «бесшовности», как в случае с характеристиками, так и при переходе на онлайн-учет, о котором я скажу позже. Переход на онлайн-учет у нас тоже происходил не сразу, заказчику нужно было дать время, потому что перевести на новую архитектуру 500 магазинов за один день было практически нереально – я таких алгоритмов не знаю. Тем более с той структурой организаций, которая была у заказчика, это невозможно. Поэтому мы решили от центральной базы не отказываться, и это тоже серьезно помогло.
Еще один интересный момент возник, когда мы начали забивать в систему штрихкоды. На тот момент производственный цикл по проекту был уже запущен, заказчик уже готовился к окончательному переходу на новую систему, и нужно было на коробки наклеивать штрихкоды уже поразмерно.
Но обработка назначения штрихкодов отрабатывала довольно долго, потому что надо было учесть десятки тысяч номенклатуры, а в разрезе размеров – это уже сотни тысяч. Мы подключились к этому процессу, довольно быстро его оптимизировали, и стало работать в восемь раз быстрее. В итогек моменту запуска успели, штрихкоды были готовы, их наклеили на коробки, и они приходили на склады уже в том виде, как это было нужно.
Решив эту проблему, мы переключились на следующую.
Разработка архитектуры системы и баз данных
Следующее решение можно назвать «облачным». Если коротко, то мы создали у заказчика свое личное «облако», которым он может управлять. Это решение состояло из:
- IT инфраструктуры;
- Самой структуры;
- И выбора СУБД для нее.
Во-первых, у нас возник довольно серьезный вопрос относительно того, использовать чисто «железную» реализацию или все-таки использовать виртуализацию?
- От виртуализации мы практически сразу отказались – в основном, из-за нестабильности работы на ней программного лицензирования на больших объемах. Она вроде бы работает, но как только что-то меняется в характеристиках сервера, все сразу ломается и рассыпается. А это – серьезное ограничение. Даже на сегодняшний день, хотя мы и проводили на эту тему уже немало испытаний, мы все равно еще не смогли реализовать такую схему. Хотя попытки ведутся до сих пор.
- Поэтому мы использовали «железную» реализацию.
Возник вопрос: как построить эту новую схему с чисто архитектурной точки зрения и как сделать ее масштабируемой? В результате было принято решение реализовать разбивку по регионам:
- Во-первых, для того, чтобы сотрудники магазинов владели информацией об остатках товаров на других адресах этого региона, и могли покупателя отправить, куда нужно.
- Также это было довольно удобно с точки зрения работы интернет-магазина.
- И, кроме того, деление по регионам позволяло обеспечить наиболее оптимальную нагрузку на серверы. Потому что когда вы покупаете сервер в районе миллиона долларов и систему хранения данных уровня КОРП, то вы беспокоитесь о том, чтобы все это работало производительно. По сути, там чуть ли не целая стойка была с блейд-серверами, и по ней нужно было аккуратно все это распределить.
- В результате поделили регионы по часовым поясам – получилось хорошо, работает быстро и по сей день.
Еще один интересный момент – это выбор между PostgreSQL и MS SQL.
Когда объем данных вырастает, соблазн использовать для их хранения бесплатную СУБД становится довольно большим. Однако что может этому помешать?
- Во-первых, специалистов по PostgreSQL практически не найти, по крайней мере, за Уралом – это я могу точно сказать. И, если возникают какие-то проблемы, то время от их возникновения до решения становится довольно большим. А постоянно вызывать для подключения к этим вопросам кого-то из Москвы – это не вариант.
- Во-вторых, на тот момент в PostgreSQL были серьезные проблемы с RLS (разделением доступа на уровне записей). Иначе говоря, включаем RLS – все, PostgreSQL ложится, и с этим ничего нельзя сделать – падение производительности настолько большое, что становится просто невозможно работать. Это ограничение на тот момент тоже сыграло свою роль.
В результате решили, что мы будем использовать более стабильную систему, поэтому заказчик купил необходимое количество лицензий на MS SQL, чем счастлив и доволен по сей день.
Правда, сейчас в PostgreSQL проблема с RLS, в принципе, решена (в версии 9.4.1, если я не ошибаюсь). По крайней мере, мы в нашем облаке тестировали базы, с которыми раньше были проблемы с RLS, и сейчас их нет. Поэтому можно сказать, что на данный момент решение с PostgreSQL было бы более оправдано. И вообще очень радует, что PostgreSQL становится более используемым, потому что все равно заказчик не всегда может позволить себе потратить на СУБД столько денег.
Информация об актуальных остатках товаров в целом по сети
Еще один интересный момент заключался в том, чтобы обеспечить сотрудников интернет-магазина информацией об актуальных остатках товаров во всей сети.
Как это происходило раньше? При поступлении заказа в интернет-магазин его сотрудник начинал прозванивать все магазины региона (если не сети) и узнавать, есть ли у них вещь такого-то размера – можете себе представить, сколько времени это занимало. Конечно, эту проблему надо было решать.
В инфраструктуре, которую мы придумали с учетом того, что базы у нас были поделены по регионам, на всю сеть получалосьв районе 40 баз. Причем в середине дня в текущей базе актуальные остатки можно было получить только в рамках своего региона, потому что обмены с базами других регионов происходили не каждую минуту, не каждые полчаса, а только раз в сутки. Нужно было придумать какое-то интересное решение, учитывающее эту особенность.
Здесь нам во многом помогла центральная база, потому что в ней завели регистр сведений, который для всех узлов РБД содержал веб-адреса (точнее, веб-сервисы). В результате мы по отдельному веб-сервису обращались к базе, из него получали адреса веб-сервисов всех подчиненных баз, и, обращаясь к ним, уже получали остатки.
Естественно, этот отчет потребовал ввода дополнительных ограничений по регионам, потому что если запрашивать остатки сразу по всей сети, то все «зависнет». И, чтобы пользователи не «косячили», такую возможность сразу прикрыли, ограничив количество регионов, по которым можно одновременно получать остатки.
Переделка интерфейсов на управляемые формы и переход на 8.3
Следующая «веселая» вещь заключалась в том, что у нас использовалась Розница 1.0 на обычных формах. И получалось, что та архитектура, которую мы придумали для заказчика, конечно, замечательная, но как с этим теперь работать? Представьте себе терминальный доступ для 500 магазинов – это весьма сомнительное решение, к тому же администрировать его очень непросто.
Конечно, для доступа к базе логичнее было бы использовать тонкий клиент, например, Розницу 2.0. Но в ней не было того функционала, который был нам нужен в реализации этого проекта, тем более, что в нашей базе также использовалось несколько дополнительных объектов, которые пришлось бы заново писать в Рознице 2.0. К тому же менять привычную для всех логику работы на то, что предоставляет Розница 2.0, тоже не вариант, потому что переучивать пользователей, особенно в таком количестве, и когда они далеко не всегда самые выдающиеся, весьма проблематично. Поэтому было решено переписать интерфейсы Розницы 1.0 на управляемые формы.
Сразу хочу оговориться, что переписывали мы сразу с учетом возможностей платформы 8.3, а не на 8.2, которая на тот момент еще повсеместно использовалась. Почему? Один из простейших моментов, сыгравший очень важную роль, это часовые пояса. Когда у вас все базы хранятся на одном сервере, и в этих базах работают пользователи из разных регионов, то вопрос часовых поясов начинает вас волновать очень серьезно, потому что время расходится.
В платформенном механизме 1С этот функционал уже был заложен, но в 8.2 он не отрабатывал вообще, а в 8.3 все работало превосходно.
Переписывать этот механизм в конфигурации – это долго и бессмысленно. Поэтому пришлось форсированными темпами некоторые базы заказчика сразу переводить на 8.3. Также это пришлось проделать и с УПП, но уже по другим причинам (чуть позже тоже расскажу).
После того как переписали интерфейсы, система была протестирована, правда, довольно простыми способами: грубо говоря, консультант тестировал пользовательскую часть, а программист - техническую, включая нагрузочное тестирование и тому подобные вещи. Оказалось довольно эффективно. Если бы мы отдали это на откуп пользователям, мы могли сорвать сроки проекта, а это недопустимо. Поэтому пришлось тестировать самим и очень быстро. В принципе, все удалось.
Про центральную базу я уже сказал: ее по некоторым причинам оставили, и сейчас не жалеем, потому что архитектура стабильная, легко масштабируется, работает безупречно.
Реализация работы в офлайне
Было еще одно интересное решение – это реализация работы магазинов в офлайне.
При переводе учета из файловых баз в «облако» наличие постоянного доступа к данным для каких-то видов деятельности не всегда критично (например, если вы ведете бухгалтерию в стартапе и доступ к базе вам нужен раз в месяц). Но когда вы ведете в базе продажи и оперативную деятельность, это становится очень критично. Тем более что заказчик сказал: «ребята, ваше решение с нашим облаком – это здорово, но что мы будем делать, если у нас пропадет интернет (а в некоторых регионах связь не очень стабильная и может пропадать)?»
Для таких случаев мы решили разработать свое отдельное приложение. Оно было, в принципе, довольно простым:
- Там были реализованы почти такие же интерфейсы, как и в основной базе.
- Но была очень интересная особенность: все было на примитивных типах данных (по сути дела, на строках). Этого было вполне достаточно, потому что:
- Когда мы считываем шрихкод, он конвертируется в строку, которая соответствует конкретной номенклатуре или характеристике,
- Цены вводились вручную по ценнику
- Магазин всегда можно использовать текущий – с этим никаких проблем не было.
- При этом, конечно,было ограничение в видах продаж: нельзя было продавать по эквайринговым терминалам, в кредит и т.д. Но этого в принципе нельзя было сделать и в предыдущей схеме при отсутствии интернета, поэтому это никого особо не беспокоило.
Однако пришлось разработать еще одну схему «семафоров», чтобы обеспечить корректный обмен между этим приложением и основной базой, и исключить при этом «кривые руки» пользователей, которые могли запустить обмен, а могли не запустить. Я думаю, вы понимаете, что если данные в 1С разойдутся с данными фискального регистратора, то это будет очень печально. Следовательно, этого надо было в корне избежать. Решение было довольно простым и состояло в следующем:
- Фактически, когда мы запускали офлайновую базу и проводили первый чек, на диске в скрытой папке формировался файл с данными. С одной стороны, это было рискованно, потому что пользователь мог этот файл найти и удалить, но у нас ведь смысл был не в том, чтобы защититься от какой-то хакерской атаки или случайного удаления, поэтому такое решение оказалось достаточно стабильным, и проблем с этим до сих пор нет.
- А когда интернет снова появлялся и мы открывали онлайн-базу заново, осуществлялась проверка, и если этот файл был на диске, мы в рабочее место кассира зайти не могли: была надпись «извините, но перед началом работы необходимо обеспечить обмен».
- Пользователь нажимал соседнюю кнопку, запускал обмен и, если он проходил успешно и все данные были распознаны, этот файл пропадал, и разрешалась дальнейшая работа.
Конечно, пришлось отдельно реализовывать механизмы закрытия кассовых смен, потому что случались переходящие моменты, когда интернет давали только на следующий день. Но этот момент тоже обошли, причем довольно просто.
Оптимизация работы
После того как мы все это реализовали, у нас возник дополнительный вопрос: хорошо, у нас есть облако, оно стабильно работает, есть офлайн-базы, и даже характеристики мы учли. Но партии у нас восстанавливаются более 70 часов. Как с этим жить? А никак, потому что партионный учет мы не могли успеть восстановить даже за выходные, а актуальную работу пользователей в реальном времени никто не отменял. Соответственно, возникали блокировки и другие проблемы.
Поэтому нам пришлось оптимизировать этот механизм. Это происходило в несколько этапов:
- Первый этап –переход на 8.3. Смысл в следующем: когда мы, работая на 8.3, отключаем режим совместимости, у нас появляется возможность использовать для MS SQL уровень изоляции READ COMMITTED SNAPSHOT, и это очень серьезно решает проблему блокировок. В частности, когда мы начинаем восстанавливать партии с использованием стандартных партионных модулей, и в этот момент у нас одновременно работают пользователи (а именно так это и происходило у заказчика, причем от этого нельзя было отказаться), данный уровень изоляции очень спасает.
- Еще одним важным моментом было использование типовой обработки проведения по партиям. По некоторым причинам заказчик ее не использовал:
- Во-первых,в модулях было сделано немало доработок, но именно в модулях документов, а не в партионном модуле, поэтому если бы мы использовали типовую обработку, то у нас те данные, которые записаны в проводках и в документах, могли бы не совпасть. А это, собственно, проблема.
- Во-вторых, типовая обработка не отрабатывает моменты, когда возникают блокировки – в этих случаях она просто заканчивает свою работу.
- И третий, довольно важный момент – это логирование. Потому что когда у вас в течение 30-40 часов что-то восстанавливается, и при этом происходит какой-то системный сбой, то вам бы не хотелось начинать все сначала. Поэтому заказчик выставил требование, чтобы можно было использовать хотя бы какие-то данные, которые обработка на этот момент успела создать, хотя бы в залогированном виде. Чтобы можно было сразу что-то решать и не ждать, когда в следующий раз на следующих выходных эта обработка снова будет запущена. Это было необходимым требованием.
Соответственно, чтобы можно было использовать типовую обработку проведения по партиям, мы переработали логику проведения документов: перенесли доработки из их модулей в партионный модуль, а саму типовую обработку проведения снабдили необходимыми качествами, чтобы она удовлетворяла требованиям заказчика.Это позволило начать пользоваться преимуществами этой обработки.
- Кроме этого, мы распараллелили проведение:
- Отдельно – управленческий учет;
- И отдельно – бухгалтерский. Причем для движений по бухгалтерскому учету производится деление на потоки, каждый из которых проводится примерно одинаковое время. После этого проводиться начало заметно быстрее, но не настолько, насколько хотел заказчик.
- Начали разбираться дальше, и пришли к такому интересному выводу: оказалось, что пересчет итогов в базе у заказчика не делался довольно давно, и как только итоги пересчитали, стало работать гораздо быстрее. Естественно, это нужно было каким-то образом регламентировать, поэтому добавили регламентное задание, и периодически следим, чтобы оно не «слетало».
- И уже после того, как все эти операции были проведены, мы еще и оптимизировали код самой обработки:
- Исключили из проведения некоторые измерения, которые не участвуют.
- И переделали запросы под текущие реалии заказчика для того, чтобы не «тянуть» лишние данные и оптимально использовать то, что есть.
В итоге время проведения того же самого объема документов на текущий момент сократилось практически в три раза и составляет около 20-24 часов.Таким образом, мы стали все успевать за выходные и обеспечили заказчику дополнительный зазор на прирост магазинов в будущем.
Заключение
Вот такое получилось интересное решение. Все задачи, поставленные заказчиком, были решены. Сейчас архитектура масштабируется и намного легче администрируется. Потому что администрировать 40 баз, которые находятся у вас в офисе (практически в ближайшем доступе), гораздо проще, чем получать данные от пользователей, которые работают где-то в удаленных регионах и когда этих баз 500. Плюс – естественно, механизмы использования актуальных остатков.
Заказчик остался доволен, и сейчас происходит дальнейшее развитие системы, уже немного в другом ключе.
****************
Данная статья написана по итогам доклада, прочитанного на конференции INFOSTART EVENT 2015 CONNECTION 15-17 октября 2015 года.
Приглашаем вас на новую конференцию INFOSTART EVENT 2019 INCEPTION.