company_banner

Tarantool: история ускорения поиска в 1С


    Недавно у наших добрых друзей из крупной розничной сети возникла задача ускорения поиска в 1С.


    Во-первых, искать нужно было по клиентам (три справочника, 9 текстовых полей, поиск типа %like%) и всего-то по 2,5 млн записей. Сразу скажем, что полнотекстовый поиск и морфология — это пока не про Tarantool. В результате ряда экспериментов мы остановились на ElasticSearch, но т.к. он не в тему статьи, то можем написать отдельную, если будет интерес. Скажем только, что скорость выросла на порядок по сравнению с тем, что мы могли выжать из полнотекстового поиска MS SQL.


    Во-вторых, нужен был поиск и подбор по товарам с выводом остатков по всем складам без дополнительных запросов. Скорость поиска должна была быть сопоставима с обычным откликом интерфейса, то есть около 0,2 сек вместо текущих 5-12 секунд в 1С (в зависимости от уровня нагрузки). 90 тысяч строк, список номенклатур меняется не часто, примерно по 10-50 позиций в день.


    Stage 1


    И тут в полный рост встал вопрос онлайн-обновления остатков товаров на складах. В двух 1С (производственная и розничная) в общей сложности было порядка 700 складов с постоянно меняющимися остатками и 90 тысяч активных позиций товаров. Планируемая система должна была переваривать 200 пользовательских запросов по остаткам в секунду.


    Первым делом посмотрели, что нам скажет Elastic. И мгновенно уперлись в проблему реиндексации (остатки меняются часто и помногу) и значительного замедления поиска из-за вложенности складов и остатков. При 50 запросах в секунду на поиск и при одновременном изменении порядка 100 записей в секунду реиндексация начинала отставать, и скорость поиска росла экспоненциально.


    Далее были MySQL и PostgreSQL, результат был примерно одинаковый. Один запрос к номенклатуре от пользователя рассыпался в среднем на 10 запросов к характеристикам номенклатуры и поиску остатков 10 характеристик по 700 складам. При 10 пользовательских запросах в секунду и тех же 100 рандомных insert в секунду поиск был около 0,9 сек, а при 20 запросах уходил за 2,5 секунды. При 30 одновременных запросах всё было сравнимо с поиском в 1С.


    Наши 1С-эксперты заявили, что «сейчас оптимизируют поиск в 1С и никаких сторонних систем нам не надо». Пропущу результат и сразу перейду к той части, где 1С-эксперты сказали, что «ну, тогда мы будем обращаться напрямую к MS SQL».


    MS SQL показал себя лучше и выдохся примерно на 45 запросах. После чего мы согласились, что нам нужна in-memory БД.


    Дальше был скучный поиск решения, которое работало бы с требуемой производительностью и при этом восстанавливалось при перезапуске серверов не позднее, чем через 3-5 секунд.


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


    Также мы понимали, что вместо привычной в эксплуатации системы на 1С мы получим затратный по администрированию и контролю показателей набор систем.


    Конечно, мы начали экспериментировать со стеком RabbitMQ + Memcached / Redis, но открытым оставался вопрос сохранения данных в случае сбоя и быстрой их подгрузки. К тому же нужно было придумывать механизм подтверждения обмена данными с 1С. В довершении всего этот стек не решал будущую задачу — построение «центрального хранилища данных» с быстрым поиском.


    Параллельно с этим мы изучали возможности MS SQL 2017 — Memory Optimized Tables.


    И вот тут мы познакомились с Tarantool.


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


    К сожалению, первичных результатов замеров не сохранилось, поэтому прикладываю более поздние результаты, только для сравнения MS SQL с Tarantool.


    Выполняли префиксный поиск (текст*) без морфологии и учета ошибок по базе примерно в 5 млн пользователей (15 полей для каждого пользователя, включая связанные данные, например, бонусные карты).


    image


    Stage 2


    Первое, что мы сделали после экспериментальных замеров, это поставили Tarantool 2.1 с поддержкой SQL-команд и коннектор к Tarantool на PHP.


    Какое-то время ушло на осознание, что каждый инстанс Tarantool является однопоточным и нужно поднимать много инстансов для распределенных запросов, а не выжимать всё из одного.
    Далее мы разбирались с компоновкой данных и тем, как их правильно разложить. В итоге написали на Lua свой велосипед по шардированию (тогда мы ещё не знали о Tarantool Cartridge и Vshard). Результаты показали длительность поиска от 0,004 сек до 0,21 сек в зависимости от нагрузки. Последнее значение получено при 30 пользовательских запросах к одному инстансу и 100 обновлениях данных в секунду. Встроенным шардированием до 7 инстансов мы получили требуемые показатели производительности.


    По мере знакомства с Tarantool мы всё больше понимали, что использование SQL — это просто привычка. Мы попробовали реализовать всё то же самое на Lua, и результат превзошёл все ожидания. Загрузка и обработка массива данных из 6 млн. записей в первоначальной SQL-реализации занимала до 20 минут, а после перехода на Lua этот же массив стал обрабатываться за 50 секунд и, как бонус, мы получили уменьшение нагрузки на 1С за счет прироста скорости выгрузки.


    С помощью двух инстансов Tarantool (мастер и read only, по updated: 3 ядра и 1,5 Гб памяти на инстанс) мы добились требуемой производительности: MS SQL не смог показать хорошую скорость при 50 запросах в секунду, а на Tarantool мы смогли выжать 120 запросов в секунду на одном инстансе (и это не предел: мы тестировали на Tarantool версии 2.2, но разработчики говорят, что в версии 2.3 выборка по префиксу стала использовать индекс, поэтому на Tarantool 2.3 результаты должны быть еще лучше — мы проверим это и добавим результаты в статью). В обоих случаях мы упирались в загрузку процессора. В среднем за 1 запрос выгружалось до 300 строк, данные при этом все хранились в памяти (Tarantool memtx).


    Текущий код написан на Lua, встроенном в Tarantool. Порог вхождения в язык для нас оказался минимальный.


    Вот пример одной из функций: добавление товаров в очередь обмена с ElasticSearch.


    --- Добавить товары в очередь для обмена, на основе изменения остатков
    local function get_stockBalance_to_queue(spaceIn)
        local x = os.clock();
    
        local space_name = 'STOCKBALANCES';
        if spaceIn ~= nil and 'string' == type(spaceIn) and spaceIn ~= '' then
            space_name = spaceIn;
        end
    
        local maxRows = 50000;
        local goods = {};
        local goodsIds = '';
    
        --- счетчики
        local i = 0;
        local iStock = 0;
    
        local session = os.time(os.date("!*t"));    
        local borderTime = session — (10); 
    
        box.begin()
        for _, tuple in pairs(box.space[space_name].index.ISPROCESSED:select(0, { iterator = box.index.EQ, offset = 0, limit = maxRows })) do
    
            if i == maxRows then break end
            --- tuple[1] — GUID 1С товара
            --- tuple[2] — GUID 1С Склада
            --- tuple[6] — Время, когда последний раз обрабатывалось
            if tuple[6] < borderTime then
    
                --- Все, что попадет в этот массив, будет обрабатываться для установки признака товару —  выгрузыть в эластик
                if goods[tuple[1]] == nil then
                    goods[tuple[1]] = 1;
                    --- Счетчик — сколько товаров может быть обновлено
                    i = i + 1;
                    --- последняя запятая обрежется в вызываемых функциях
                    goodsIds = goodsIds .. '"' .. tuple[1] .. '",';
                end
                --- Устанавливаем последнее время обработки = текущее время
                pcall(function() box.space[space_name]:update({ tuple[1], tuple[2] }, { { '=', 5, 1 }, { '=', 6, session } }) end);
                --- Счетчик — сколько товаров всего попало в обработку
                iStock = iStock + 1;
            end
        end
    
        local stockTmp = {};
        local goodsInStockTmp = {};
        local instock = 0;
    
        --- в функции getSumStock происходит создание массива остатков по товару (сколько в резерве, в наличии и т.д.)
        local stockBalance = _G.Functions.getSumStock(goodsIds);
    
        --- в функции getGoodsInStock происходит создание массива со значением in stock — 1/0 (Да/Нет)
        local goodsInStock = _G.Functions.getGoodsInStock(goodsIds);
    
        local iGoods = 0;
        for _, tuple in pairs(goods) do
    
            --- Берем количество товара в наличии (не может быть такого, что в массиве нет товара с текущим tuple[1], поэтому нет проверки)
            stockTmp = stockBalance[tuple[1]]['quantityNet'];
    
            --- Берем значение товара в наличии (не может быть такого, что в массиве нет товара с текущим tuple[1], поэтому нет проверки)
            goodsInStockTmp = goodsInStock[tuple[1]];
    
            --- в товаре хранится просто признак в наличии — Да/Нет, поэтому мы приводим все к 1/0 (Да/Нет)
            if not stockTmp then
                instock = 0;
            elseif stockTmp > 0 then
                instock = 1;
            elseif stockTmp < 0 then
                instock = 0;
            else
                instock = 0;
            end
    
            --- если текущее наличие в товаре отличается от наличия по всем складам, то помечаем товар к выгрузке в эластик
            if instock ~= goodsInStockTmp then
                --- Счетчик — сколько товаров было изменено
                iGoods = iGoods + 1;
                --- Поле 100 — Обработано (индекс — ISPROCESSED) (ДА/НЕТ), если нет, то попадет в этот цикл
                --- Поле 105 — Наличие, Да/Нет (1/0)
                pcall(function() box.space.GOODS:update(tuple[1], { { '=', 100, 0 }, { '=', 105, instock } }) end);
            end
        end
    
        box.commit();
        return space_name .. ' for update: ' .. iStock .. '  Goods for update: ' .. i .. ' Updated goods: ' .. iGoods .. ', ' .. (string.format("elapsed time: %.2f", os.clock() — x));
    end;

    Теперь мы ищем в ElasticSearch с учетом морфологии и ошибок по наименованиям/свойствам и другим текстовым полям, а после этого запрашиваем данные о наличии товаров в различных разрезах в Tarantool и возвращаем результат.


    Примерная схема работы такая:


    image


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


    Мы мониторим показатели ресурса сервера (процессор, память, диски) и показатели Tarantool box.slab.info. Со стороны 1С мониторится уменьшение очереди на отправку и отсутствие ошибок в ответе от бэкенда. В случае достижения пороговых значений оповещается техподдержка.


    И да, мы очень благодарны специалистам Mail.ru Group, которые отвечали на наши вопросы, и сообществу в Telegram, которое пока небольшое, но очень активное.


    Stage 3


    «Ну вот, — подумали мы. — Всё так здорово работает. А не подключить ли нам сайт напрямую к Tarantool, чтобы избавиться от медленных Bitrix-обменов и Bitrix-кеширования?» (кто в теме, тот грустит вместе с нами)


    «Почему только сайт? — спросил заказчик. — Наверняка туда нужно подключить мобильное приложение, партнеров и франшизу».


    «Ух» — сказали мы, и поскольку представление о быстром хранилище данных уже сложилось, мы ушли придумывать шину обмена данных на Tarantool. Надо сказать, что результаты уже впечатляющие. Напишем, если эта тема вам, уважаемые читатели, зайдет.


    P.S. Спасибо, что уделили прочтению статьи столько своего времени. Ждем народной любви и народного гнева в комментариях. Всех обнимаем, команда Зионек

    Mail.ru Group
    Строим Интернет

    Комментарии 63

      0
      Не совсем понял как из 1С в тарантул попадает?
        0
        В 1С с помощью подписки фиксируем изменения данных (хранится на случай, если Тарантул в это время отвалился) и сразу отправляем их на простой web-сервис. web-сервис принимает, проверяет формат, передает на app-сервис на LUA.
          +1
          Т.е. дергается тарантул в момент начала транзакции на стороне 1С? А если по какой-то причине транзакция в 1С не зафиксировалась, а откатилась. Какая реакция в сторону тарантула?
            0
            Нет. в 1С изменил по подписке пишутся в регистре. Фоновое раз в 15 секунд (этого достаточно для данной задачи) выкидывает данные из регистра в веб сервис тарантула. Если подтверждения об обработке данных не приходит, фоновое будет продолжать попытки выкинуть изменения в тарантул.
              0
              Т.е. начинается транзакция на стороне 1С — срабатывает подписка (пишем изменения в регистр для тарантула) — натыкаемся на ошибку (транзакция на стороне 1С откатывается) — … фоновое задание кидает изменения в тарантул (записи ж не удалены при откате транзакции) или чего-то не хватает?
        +1
        Тема интересная, ждём продолжения!
          0
          "… нам нужна in-memory БД" — А чем MS-SQL не угодила? В статье не указывается версия MS SQL, которую использовали, пара слов о том, что рассматривали MS SQL 2017, но никакого сравнения новой версии. Понятно только, что на существующей версии MS SQL намного медленнее, чем на tarantool 2.1, который 2019 года.
            0
            Тестировали на SQL Server 2016 SP2 CU11 (13.0.5598.27)
            Можно было продолжать дальше, но решили с клиентом, что данная задача не стоит покупки полноценных SQL лицензий, вместо существующих Runtime 1C
            +4
            Вот лично я не верю, что хорошо настроенный MS SQL с нормальной структурой таблиц и индексов (а не тем, что создает 1С) и на нормальном железе (не мега крутом, а просто нормальном) не справится с подобным количеством запросов.
            Все эти данные легко помещаются в оперативку, и при правильной настройке СУБД все будет в памяти…
            Загрузка и обработка массива данных из 6 млн. записей в первоначальной SQL-реализации занимала до 20 минут
              0
              Вы про MEMORY_OPTIMIZED=ON? Там вроде бы есть разные ограничения, вроде отсутствия btree индексов, nullable полей и тому подобное.
                +2
                Нет. Самое обычное кэширование в оперативку.
                90 тысяч наименований товаров и 700 складов дают нам максимум 63 миллиона записей. На практике, подозреваю, речь идет о не больше чем 10 миллионах.
                Вы пытаетесь меня уверить, что MS SQL не сможет обрабатывать несколько сотен запросов в секунду на чтение на таких объемах?
                MS SQL показал себя лучше и выдохся примерно на 45 запросах.

                Это надо как то очень извращенно настроить СУБД, чтобы была такая низкая производительность.
                  0
                  Нет, меня интересует настройка MSSQL для того, чтобы (фактически) хранить всё в памяти без использования диска. Мне показалось, что вы про это. С кэшом всё понятно, однако есть предположение, что у авторов запросы на чтение выполняются во время непрерывной записи данных на диск.
                    0
                    Сто инсертов в секунду — это не очень много. Они ведь маленькие — каждый меняет несколько записей.
                    Разумеется, надо СУБД правильно настроить — журнал и данные на разные диски и т.д.
                    0
                    Вы пытаетесь меня уверить, что MS SQL не сможет обрабатывать несколько сотен запросов в секунду на чтение на таких объемах?

                    Думаю кстати нет, они же по лайку ищут сразу по многим полям, даже с миллионом записей будут проблемы
                      0
                      они же по лайку ищут сразу по многим полям, даже с миллионом записей будут проблемы

                      Товаров всего 90 тысяч. И поиск по лайку делают отдельно.
                      Теперь мы ищем в ElasticSearch с учетом морфологии и ошибок по наименованиям/свойствам и другим текстовым полям, а после этого запрашиваем данные о наличии товаров в различных разрезах в Tarantool и возвращаем результат.
                      +1

                      Без конкретной структуры 1С, без конкретных запросов, конфигурации оборудования и настроек SQL Server можно долго гадать, но на самом деле умеренно прошаренные 1С-ники и DBA вполне могли уткнуться примерно в такие цифры (там где-то 126 мс на запрос в статье фигурировало по конкретной строке и 15 мс у тарантула).
                      Запрос по остаткам, если не приложить особых усилий, это соединение 3 таблиц (справочник с фильтром, остатки и движения). Если действовать по рекомендациям 1С (т.е. фильтр по справочнику в параметрах виртуальной таблицы), то четырёх (фильтр отдельно джойнится к остаткам и движениям). Но MS SQL отлично (лучше других СУБД, применимых к 1С) умеет прокидывать фильтр в отдельные таблицы подзапроса.
                      В любом случае без дополнительных приседаний это в SQL будет что-то типа


                      SELECT Ref.ref, Reg2.s 
                      FROM Ref 
                          JOIN 
                              (SELECT SUM(Reg1.s) s, Reg1.ref 
                              FROM 
                                  (SELECT ref, -s FROM Reg WHERE DateCodition1 
                                  UNION ALL 
                                  SELECT ref, s FROM RegTotals WHERE DateCodition2) Reg1
                              GROUP BY Reg1.ref
                              HAVING SUM(Reg1.s)<>0
                              ) Reg2
                         ON Ref.Descr like '1293%'

                      (это очень упрощённо! И если писать "как рекомендует 1С", то джойны будут к Reg и RegTotals — так SQL Server работает хуже в данном кейсе)
                      А каждое изменение остатков это изменение конечного остатка в RegTotals и движений в Reg (и, если обмен данными, то ещё регистрация изменений)
                      Дальше можно заставить 1С:


                      1. Не брать движения вообще, а брать только из итогов. Для этого, как минимум, не должно быть движений "в будущем"
                      2. Вести отдельный регистр остатков с строкой поиска (если правильно делать, то с индексами там будет правильно)
                        Тогда запрос станет примерно таким:
                        SELECT Reg2.ref, Reg2.s 
                        FROM  
                            (SELECT SUM(Reg1.s) s, ref 
                            FROM 
                                (SELECT ref, s 
                                FROM RegTotalsWithDescr 
                                WHERE DateCodition2 AND RegTotals.Descr like '1293%') Reg1
                            GROUP BY ref
                            HAVING SUM(Reg1.s)<>0
                            ) Reg2

                      Но кроме банальных планов запросов и индексов там надо ещё смотреть:


                      1. Работает ли RCSI (он может работать) в 1С.
                        • Если не работает, то не фигню ли показывают остатки (т.к. тогда запросы с readuncommitted)
                        • Если не работает, то не уприраемся ли в блокировки?
                        • Если работает, то не упираемся ли в tempdb
                      2. Не упираемся ли в журнал транзакций (если да, то планируем диски правильно)
                      3. Не упираемся ли в компиляцию запросов (если временные таблицы используем, то легко, у 1С временные таблицы всё время с новыми именами)
                      4. Не упираемся ли в какие-то другие изменения (регистрация в план обмена, например)
                      5. Не упираемся ли вообще в другие механизмы.

                      Короче, там много всего еще надо посмотреть. 15 мс в тарантуле это в общем-то тоже дофига.

                        0
                        Вот вы тут хотя бы что-то дали, в отличии от автора статьи. Тем не менее, даже того, что тут написано абсолютно недостаточно, чтобы делать выводы о 125 мс или 10 мс.

                        Я не 1Сник, логики тут не понимаю, на вид запросы очень странные. Но в любом случае, непонятно, что тут с железом, сколько памяти, что с дисками, где расположен журнал, что с индексами, что со статистикой.

                        Вот если бы можно было бы скачать базу для тестов, тут можно было бы делать выводы.
                          0
                          Я ведь не просто так написал
                          хорошо настроенный MS SQL с нормальной структурой таблиц и индексов (а не тем, что создает 1С)


                          Вообще, само по себе желание использовать 1С на относительно крупных внедрениях является странным. Когда надо увеличивать производительность — важна возможность «тюнить» узкие места. А при использовании 1С такие возможности ограничены.
                            0
                            А нельзя в 1C использовать всякие мат вьюхи созданные вручную или хранимки?
                              0
                              Можно и нужно. Все зависит от конкретно поставленной задачи.
                                0
                                Ниже в комментарии:
                                Здесь еще нужно понимать, самовольное создание индексов в 1С является нарушением лицензионного соглашения. Начальство на это смотрит крайне подозрительно, потому любой удачный индекс после следует удалить и создать легальными средствами 1С. Зачастую процесс поиска таких индексов выносится на тестовую среду, в исключительных случаях (критическое падение производительности) могут разрешить что-то попробовать на продакшене.
                                  0
                                  Мне кажется, что если система крупная и не хватает производительности, то на лицензионное соглашение всем чихать.
                                    0
                                    Тоже верно. Но смысл заранее себе жизнь усложнять?

                                    Структура таблиц для регистров остатков у 1С совсем не оптимальная. Намного лучше, чем для регистра бухгалтерии, но все равно — не очень. И если предвидятся большие нагрузки…
                    0
                    А как вы потом в 1С используете поиск по тарантулу?
                      0
                      с помощью http-запросов. Т.е. в форме 1С ловим нажатие кнопки в поле поиска (событие «ИзменениеТекстаРедактирования») и отправляем запрос с этим текстом тарантулу, затем ответ подгружаем в таблицу значений
                        +1
                        Интересно насколько плохой должна быть архитектура 1с-решения, если даже подобный выверт работает быстрее? Вообще по производительности 1С у меня куча вопросов, разработчики утверждают, что пишут её на с++, но почему то элементарная запись в текстовый файл на питоне выполняется в десятки раз быстрее, а на java в тысячи, это какой шлак должен быть внутри платформы, если даже такие элементарные вещи делаются так долго?
                          0

                          У вас устаревшая информация насчёт записи в файл, но такая проблема имела место быть в прошлом

                            0
                            Проверяли недели 2 назад, с коллегой, на последнем релизе платформы.
                              0
                              Скорее всего вы использовали «ЗаписьТекста» в файл, есть новый механизм через «ФайловыйПоток», он работает гораздо быстрее и сравнимо с другими ЯП
                                0
                                Нет, я использовал ТекстовыйДокумент, про файловый поток не знал, но он оказался не так хорош как ЗаписьТекста.
                                Запись строки «стр» 1 000 000 раз, результаты в секундах:
                                ТекстовыйДокумент: 67
                                ЗаписьТекста: 1
                                ФайловыйПоток: 9
                                Python: 1
                                Java: 0.1

                                Запись строки «стр» 5 000 000 раз:
                                ТекстовыйДокумент: 1162
                                ЗаписьТекста: 6
                                ФайловыйПоток: 46
                                Python: 5
                                Java: 0.4

                                Запись строки «стр» 10 000 000 раз:
                                ТекстовыйДокумент: недоступно, остановил когда время перевалило за 1.5 часа
                                ЗаписьТекста: 11
                                ФайловыйПоток: 99
                                Python: 11
                                Java: 0.5
                                  0
                                  Спасибо за тесты, как вы сами видите ЗаписьТекста сравнима с python (правда непонятно почему через ФайловыйПоток медленее, так как работает с памятью), думаю это связано больше не с самой записью в текст, а с тем что питон и 1с интерпретируемые ЯП, а java компилируется, скорее всего потеря на цикле
                                    0
                                    Можете привести код этих проверок?
                                      0
                                      Боюсь что нет, это просто ради любопытства на коленке было сделано, в рамках беседы про производительность 1С.
                                        0
                                        Жалко, хотел у себя проверить.
                              0
                              Я думаю ответ: Кроссплатформа (Win, Mac, Lin, Android, iOS, web) — везде работает
                              0
                              А если много значений в ответе? Первые 10 берете или как?
                                0
                                Выводим все, в среднем это 10 характеристик, по каждой около сотни остатков по складам. Это массив который возвращается.
                            +3
                            Какое-то время ушло на осознание, что каждый инстанс Tarantool является однопоточным и нужно поднимать много инстансов для распределенных запросов, а не выжимать всё из одного

                            С помощью двух инстансов Tarantool (мастер и read only, по 4 ядра и 1,5 Гб памяти на инстанс)


                            Интересно, зачем нужны 4 ядра на инстанс если инстанс однопоточный?
                              0

                              там ядро в одном потоке, сетевая часть в другом

                                +1
                                А вот ошибка в тексте, спасибо, сейчас исправлю. На самом деле нужно 3 ядра на инстанс. Вот описание .
                                +3
                                Осталось остальной 1с на tarantool переписать :)
                                  0
                                  Bitrix-обмен товарами из 1С не упирается в СУБД MS SQL (или PostgreSQL). Bitrix-обмен упирается в обмен XML-кой зажатой в zip-файл (в ней же и картинки товаров передаются), в передачу через инет (или через локальную сеть) этого файла в Bitrix, и упирается в разбор полученного XML на стороне Bitrix. При разборе этой XML-ки на стороне Bitrix СУБД MySQL хорошо так нагружена.
                                  Как тут помогает Tarantool? Ускорят выборку данных из 1С?
                                    0
                                    Нет, мы не будем передавать количества в MySQL вообще. Да это кастомизация, но битрикс (как и мобильное приложение и мобильные рабочие места сотрудников) будет показывать остатки прямо из тарантула. И да, тарантул отлично держит запросы к товарам и остаткам без дополнительных кэшей.
                                  0

                                  статья про 1с, а в блоге мейла


                                  когда-то в мейле работал Алейников, который и был первоначально автором проекта Тарантул, а потом он ушёл как раз в 1с.


                                  интересно, он участвует ещё в этом проекте?

                                    +6
                                    Мне очень печалит, до чего дошел Хабр последнее время. Нет, поймите меня правильно, я не против рекламных статей. Я абсолютно уверен, что есть ниша, где действительно Тарантул будет показывать хорошие результаты. Но то, что мы видим в этой статье, это позор автора.

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

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

                                    После чего, следует нудный рассказ про внедрение Тарантула (и потом, еще волшебным образом Elastic) и вывод, что все хорошо. При этом не сказано ни слова о целостности данных или их сохранности в процессе отказа.

                                    Вы меня простите, конечно, но вот те выводы, которые сделал я.

                                    У нас есть SQL база 1C, в которой у нас 63 млн записей. Даже если представить строки по 500 байт, это меньше 32Гб памяти, т.е. все эти данные могут легко располагаться в памяти. Вместо того, чтобы разобраться с индексами и журналами, докупить копеечной памяти и SSD,
                                    реализовать всю логику на одном MsSql сервере, не потратив силы на контроль целостности данных, клиентам начали врать, что им нужна In-Memory BD.

                                    Конечно же нужна, что лучше, потратить пару дней DBA MsSql и копейки денег на железо или целая команда людей, кто проводит «тесты», изучает Тарантул «без документации», пишет связки еще и с Эластиком. Конечно же второе, что может быть лучше, чем позаниматься прикольными вещами и развести клиента на деньги!

                                    Отмечу еще, что у автора статьи нет самых базовых знаний MsSql, как пишется журнал, как закачиваются данные в память. Но выводы-то делаются!
                                      +1
                                      +100500
                                      Есть задачи, когда действительно нужны Big Data, NoSQL, In Memory DB и прочие хайповые вещи.
                                      Но есть огромная куча задач, которые проще решить правильной настройкой обычных СУБД — это будет в РАЗЫ дешевле и надежнее.
                                      0
                                      1) заводим регистр сведений
                                      2) заводим реквизит «первые 3 буквы» и реквизит «полное наименование», индексируем
                                      3) выполняем запрос с подзапросом (сначало по первым 3 буквам, затем по полному наименованию).
                                      4) получаем свои пикосекунды поиска

                                      Как смасштабировать по нескольким реквизитам и нескольким словам, думаю, понятно.
                                      В данном кейсе никакие эластиксичи не нужны. И миллион записей это копейки. Все это делается средствами 1с или СУРБД (смотря где вас застал этот кейс).
                                      Проверено не раз, сам впервые столкнулся когда нужно было искать по табличке с миллиардами записей весом в 350 гигабайт (микросекунды до получения результата).
                                        0
                                        По какому принципу вы собираетесь хранить весь текст по товарам и клиентам?
                                        Просто первые три символа для каждого наименования товара, папки, вида номенклатуры, фио клиента, телефона и карты лояльности? Т.е. если у меня наименование «Вертикальный пылесос Samsung», то оператор уже не сможет найти «Пылесос Samsung»?
                                        Или все-таки отдельными словами? Тут непонятный толк от такой фильтрации для, например, карт лояльности и номеров телефонов, т.к. они начинаются одинаково. Хотя здесь вы, наверное, ищете только по полному совпадению и отказываетесь от живого поиска, когда оператор видит фильтрацию в реальном времени. Но кроме этого же есть фамилии/имена, в которых первые 3 буквы повторяются очень часто (вам придется искать и по фамилии, и по имени, т.к. никто не гарантирует, что ФИО внесли в правильной последовательности). По какому принципу вы разбиваете по словам? Например, наименование товара «Браслет КТ 7405708/01-А552-01 01Б760365Ж.» (это реальный товар) как будет разбито? Сколько по вашим оценкам будет занимать первоначальное заполнение такого регистра (регистров?) и насколько хорошо будет происходить обновление данных? Какой объем будет занимать?
                                        И не зависимо от способа заполнения еще вопрос: я так понимаю, что никакого поиска с учетом морфологии и синтаксических ошибок у вас быть не может как у авторов?
                                          0
                                          Про поиск вспомнилось вот это видео на Infostart Event. Видео на 24 минуты, но если в двух словах — там всю большую строку дробили на подстроки по N символов, со сдвигом в 1 (т.е. «Вентил», «ентиля», «нтилятор» и т.д.). Т.е. жертвовали местом на диске (на таблицу и на индекс), но выигрывали по производительности.
                                            0
                                            Таким образом получим:
                                            1. Затраты на диск (меньше всего волнует, но все же)
                                            2. Более медленное обновление данных. Просто зарегистрировать объект к обмену со сторонней системой намного быстрее, чем обновить все подстроки в регистре поиска + обновить статистику
                                            3. Бессмысленность регистра при популярных комбинациях
                                            А в реальности придется делать подстроку не 6 символов (как в видео), а 3, что только усугубит ситуацию. Т.е. Elasticsearch выигрывает по всем пунктам еще и бонусом вы получаете поиск с учетом ошибок и морфологии. Ведь смысл же реализовать быстрый поиск, а не любыми путями сделать это на 1с пусть и с худшими показателями
                                              0
                                              Ну так в видео этом и не делают акцент на «это лучший вариант из возможных». Там именно постановка вопроса «а еще вот так можно прямо на 1С, без сторонних средств». Softpoint вообще годами продвигают и продают инструментарий, который позволяет «более лучше» использовать возможности СУБД в обход ограничений платформы.
                                              Я же вам это видео привел как пример (более проработанный) реализации концепции описанной в комментарии выше.
                                        0
                                        А вы говорили, что 1С скучно. Вот вам и Tarantool, и ElasticSearch! =)
                                          0
                                          Несколько лет назад в одной очень большой организации внедряли зарплатный проект на 1С. А он, что называется, «не взлетел». Разработчики голову ломали, админы, сотрудники отдела-эксплуатанта. Перепробовали все что можно, на MS SQL Server шли дидлоки, процесс сбивался. Я там долгое время просил кое-что сделать, но когда все остальное перепробовали- разрешили. Проблему решили 4 индекса по таблицам на 80 мегабайт. Аж запрыгало.
                                          Здесь еще нужно понимать, самовольное создание индексов в 1С является нарушением лицензионного соглашения. Начальство на это смотрит крайне подозрительно, потому любой удачный индекс после следует удалить и создать легальными средствами 1С. Зачастую процесс поиска таких индексов выносится на тестовую среду, в исключительных случаях (критическое падение производительности) могут разрешить что-то попробовать на продакшене.
                                          В дальнейшем была проведена большая работа по анализу кода. Основной объект анализа- процедурный кэш, анализируется в момент наибольшей нагрузки, высоких блокировок и высокой дисковой активности.
                                          Для понимания- по счетчику Page lookups/sec|SQLServer:Buffer Manager удалось установить, что в отдельные моменты запрос данных из памяти сервера достигает 2 Тб в минуту и более (!!). То есть, память используется не как средство ускорения доступа к информации на СХД а как некий математический механизм, эта нагрузка разительно отличается от рабочей нагрузки других серверов.
                                          Выявлялись наиболее ресурсоемкие запросы, оптимизировались индексами либо передавались разработчикам на изменение кода. При системном подходе никаких ин-мемори таблиц и колумнсторе индексов не понадобилось, и так замечательно заработало.
                                          Кроме того, хорошо поработали с флажками трассировки.
                                          На сегодняшний момент проблемы оптимизации 1С возникают только при внедрении новых задач или существенных изменениях (меняются запросы).

                                          Если модератор пропустит- небольшая моя статья на тему оптимизации MS SQL Server
                                          www.digger.dp.ua/optimizaciya-ms-sql-server
                                            0
                                            Круто!
                                            Просьба/совет: Дублируйте на Инфостарте, там хотя бы смогут оценить практическую часть применения и не будут писать пустых комментариев как все плохо в 1С
                                              0
                                              Никто не пишет, как все плохо в 1С.

                                              Пишут, что люди не умеют использовать MsSql и из проблемы на пару дней для опытного DBD делают проблему распила денег интересной работы на пару месяцев для команды разрабов.
                                              0
                                              я правильно понимаю, что тарантул для этой задачи работает на 3 ядрах и 1.5ГБ памяти в 2.5раза быстрее чем MSSQL в этих же условиях? сколько инстансов тарантула нужно?
                                                +1

                                                Готов согласиться, что индексы просадят инсерты. Но про это ничего не сказано.
                                                Готов согласиться что даже на индексах поиск по %like% может быть медленным.
                                                Но авторы даже не пытались.
                                                На лицо пользовательский подход к типичной задаче DBadmin.
                                                Ищем профайлером кандидатов на отстрел, бьём лицо разработчикам, учим писать запросы.
                                                Вообще, заметил эту проблему в последнее время. Разработчики привыкли не думать о данных. Мол, фреймворк позаботиться обо всем… Грусть...

                                                  0
                                                  даже на индексах поиск по %like%

                                                  какой индекс поддерживает %like%?

                                                      0

                                                      а ну это фигня.


                                                      ещё в своё время Федя Сигаев писал для PostgreSQL триграммы.
                                                      позволяли условно индексировать регексповый поиск.


                                                      есть ещё вариант сделать %ilike% таким образом.


                                                      пишем функцию SQL которая на строку возвращает все входящие в неё подстроки


                                                      foo('Привет')
                                                      привет
                                                      ривет
                                                      ивет
                                                      вет
                                                      ет
                                                      т
                                                      риве
                                                      иве
                                                      ив
                                                      и
                                                      ...

                                                      Затем строим GIN индекс:


                                                      CREATE INDEX ON "bla" USING GIN(foo("text"))

                                                      И это тоже будет индексированно искать аналог ilike.


                                                      Только проблема в том что все эти решения либо частные случаи, либо (цитата из ссылки):


                                                      не факт что стоимость такого плана будет ниже
                                                        0

                                                        Ну, собственно, я это ми написал ты исходном сообщении.

                                                      0
                                                      Есть мнение, что если размер записи велик а в индекс вынесено нужное varchar поле, то размер индекса может быть значительно меньше размера таблицы. Кластерный индекс (или куча) пусть 10 Гб, индекс 1 Гб. Поиск по такому индексу даже лайком будет идти значительно быстрей.

                                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                  Самое читаемое