ФорумПрограммированиеPHP для идиотов → Способ синхронизации товаров высоконагруженного интернет-магазина.

Способ синхронизации товаров высоконагруженного интернет-магазина.

  • Professor

    Сообщения: 2089 Репутация: N Группа: Адекваты

    Spritz 2 марта 2013 г. 8:48

    Привет всем.
    Проектируем сейчас интернет магазин под высокие нагрузки, с огромным ассортиментом(переделка с нуля существующего магазина)

    Суть:
    1) "оффлайн" база, куда поступает информация от поставщиков. Ее модифицировать крайне сложно, есть минимальное API.
    2) Есть интернет магазин
    3) Возможно наличие других интернет магазинов работающих с этими же товарами(теже товары, только разная функциональность, разные пользователи, разный контент, и как итог разные БД)

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

    Суть такая. В интернет магазине был заказ, информация о том что наличие товара должно уменьшиться на 1 отправляется в эту прослойку, оттуда по всем интернет магазинам и в "оффлайн" БД
    Раз в сутки обновляемся с "оффлайн" БД.

    Есть мысли, как это реализовать по другому? Какие нибудь советы?
  • master

    Сообщения: 3236 Репутация: N Группа: Джедаи

    Spritz 2 марта 2013 г. 10:33, спустя 1 час 44 минуты 46 секунд

    одна база с наличием, все магазины работают с ней с изоляцией транзакций
    либо заказы принимаются, а если вдруг взяли лишний заказ - менеджеры разруливают
    не всё полезно, что в swap полезло
  • Professor

    Сообщения: 2089 Репутация: N Группа: Адекваты

    Spritz 2 марта 2013 г. 15:18, спустя 4 часа 45 минут 16 секунд

    А если нет возможности работать с одной базой?
  • master

    Сообщения: 3236 Репутация: N Группа: Джедаи

    Spritz 3 марта 2013 г. 3:45, спустя 12 часов 27 минут 9 секунд

    если у тебя больше одной базы - возьми одну, а остальные выкинь
    если нет ни одной базы - настрой одну
    не всё полезно, что в swap полезло
  • Professor

    Сообщения: 2089 Репутация: N Группа: Адекваты

    Spritz 3 марта 2013 г. 4:42, спустя 56 минут 51 секунду

    master, смотри.
    Есть база товаров. и есть несколько сайтов с различным функционалом и различной структурой БД. Одинаково у всех только структура хранения товаров.
    Все сайты лежат на разных серверах. Использование 1 базы как бы не гуд. Даже по той причине, что некоторые сайты это сайты партнеров и давать им доступ к основной базе не желательно.
  • master

    Сообщения: 3236 Репутация: N Группа: Джедаи

    Spritz 3 марта 2013 г. 10:14, спустя 5 часов 32 минуты 6 секунд

    Professor, одной базой проще обеспечить консистентность.
    но можно и не гнаться за консистентностью и распределёнными транзакциями, а сделать по-простому из говна и палок:
    - основная база хранит остатки
    - каждый сателлит(магазин) раз в 10 минут синкает остатки в виде одного xml или yml или ещё чего (именно одного, это важно), т.е. делает запрос и получает от базы ответ в таком например формате
    артикул: остаток (если склад один)

    1: 123
    2: 200
    3: 250


    либо в формате артикул % склад:количество, склад:количество

    1 % 1:123, 2:12
    2 % 1:100, 2:100
    3 % 1:123, 2:127


    либо в любом другом, важно чтобы ответ был одним куском
    - если каких-то артикулы сателлит встречает впервые - отдельно запрашивает информацию о товаре у основной базы
    - все продажи сателлит записывает в свою базу и отправляет логи продаж (а продажа - это две связанные операции: списание товара и зачисление денег) в основную базу. то есть
    сателлит: база, база, я первый. продал артикул 111 в количестве 6 штук по 123 рубля и артикул 112 в количестве 1 штук по 9999 рублей. приём.
    база: первый, первый, я база. продажа засчитана. конец связи. (если все товары есть)
    либо
    база: первый, первый, я база. продажа не засчитана. конец связи. (это если какого-то из проданных товаров нет в нужном количестве)
    если продажа не засчитана то менеджер магазина звонит клиенту и извиняется. деньги возвращает. смотря по ситуации.

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

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

    Сообщения: 2089 Репутация: N Группа: Адекваты

    Spritz 3 марта 2013 г. 10:46, спустя 31 минуту 31 секунду

    Спасибо.

    Но почему ты предлагаешь "именно одного, это важно" и каждые 10 минут?
    Почему нельзя по факту изменения наличия стучать в основную базу о том, что у товара ID100 количество уменьшилось на 10, а основная проверяет, есть ли вообще сейчас такое количество и если есть, то отправляет теже данные остальным сателитам.
    Таким образом каждый сателит сам следит за своими остатками, а "прослойка между главной базой и сателитами" просто информирует, на сколько уменьшить или увеличить какой продукт.
    Так и косяков меньше будет.
    Да и по нагрузке на эту прослойку будут стучаться только реальные заказы, это не просмотры страниц, их в разы меньше.
  • master

    Сообщения: 3236 Репутация: N Группа: Джедаи

    Spritz 3 марта 2013 г. 11:30, спустя 44 минуты 46 секунд

    Но почему ты предлагаешь  "именно одного, это важно" и каждые 10 минут?

    для консистентности. если сателит получил 1 ответ, распарсил его - ты на 99% уверен в том что данные не потерялись. если сателит будет делать 2 запроса - то один может проебаться где-нибудь, в результате у сателита по галошам остатки актуальные, а по принтерам - нет.

    правильная схема такая по идее
    сателит: база, база, я первый. хочу остатки. моя последняя продажа - 123456
    база: ок, вот остатки для твоей последней продажи 123456

    либо

    сателит: база, база, я первый. хочу остатки. моя последняя продажа - 123456
    база: хуй тебе, твоя последняя продажа в моей базе только 123454. давай недостающие продажи

    либо (менее правильно)

    сателит: база, база, я первый. хочу остатки. моя последняя продажа - 123456
    база: держи. но учти, что эти остатки учитывают только твои продажи по 123454.
    сателит сам учитывает 2 свои последние продажи. но это гемор имхо.

    Почему нельзя по факту изменения наличия стучать в основную базу о том, что у товара ID100 количество уменьшилось на 10, а основная проверяет, есть ли вообще сейчас такое количество и если есть, то отправляет теже данные остальным сателитам.

    потому что в случае ошибки заебёшься разбираться почему где и сколько списалось. каждый факт списания в отдельном сателите должен быть пронумерован.

    Так и косяков меньше будет.

    когда передаёшь дельту а не остатки целиком косяков наоборот больше. у тебя же не полноценная ACID база, а имитация из говна и палок. потеряешь одну дельту (связь между серверами глюканула) - вот пропущенное списание. посетитель дважды нажал кнопку не дожидаясь перезагрузки страницы - вот дополнительное списание. поэтому каждая продажа должна иметь id, более того, когда сателлит отправляет отчёт о продаже в основную базу он называет id продажи и id предыдущей продажи, а база сверяет id предыдущей продажи для конкретного сателлита с последним ею обработанным.
    не всё полезно, что в swap полезло

Пожалуйста, авторизуйтесь, чтобы написать комментарий!