Комментарии 40
Какая же это база данных? Транзакции? Репликация? Снапшотинг?
Это просто кэширующий сервис.
Получается MySQL на движке MyIsam не считался базой данных из-за отсутствия транзакций?
Да, отличное сравнение, MySql имеет репликацию, персестирует данные, да и еще поддерживает разные движки, как вы сами и заметили.
Тут же вообще ничего нет, вы реализуйте репликацию для своего решения, для начала, ждет много интересных открытий.
Если спорить о терминах, то я тогда процитирую википедию, как источник, которому я доверяю:
"База Данных — совокупность данных, хранимых как в соответствии со схемой данных так и в произвольном порядке, манипулирование которыми выполняют в соответствии с правилами средств моделирования данных"
Под этот термин решение в статье попадает, потому что это совокупность данных, а именно доступность отелей. Но думаю вы говорили о СУБД, а не о БД, тогда копнём еще глубже:
"СУБД — комплекс программ, позволяющих создать базу данных и манипулировать данными (вставлять, обновлять, удалять и выбирать). Система обеспечивает безопасность, надёжность хранения и целостность данных, а также предоставляет средства для администрирования БД"
Но и под этот термин решение подпадает, потому что позволяет создавать и манипулировать данными. Кроме того, решение в статье поддерживает ACID.
Всё о чём вы говорите, это дополнительный функционал, к которому мы привыкли в готовых решениях СУБД. Что-то в текущем решении есть, чего-то нет, но это не отменяет того факта, что это рабочая база данных.
Если ваше решение субд/бд (блог конечно корпоративный но давайте без буквоедства) то почему оно не работает без постгри? Забавная рекурсия получается. Кстати под определение бд из википедии попадает любой контейнер из языка программирования, тоже бд получается?
Про ACID как хорошо что вы сказали слово "решение" ведь ACID в вашем решении обеспечивает postgress, а вы написали кэширующий прокси. Но видимо звучит не достаточно солидно.
О, это случаем не пересказ из конференции golang conf X? Можно было и видео тогда прикрепить
Приходилось искать баланс: как разработчики, мы предпочитаем писать бизнес-логику на Python или Go, а не на SQL. Это означает, что чаще мы загружаем данные из базы и обрабатываем их в приложении. Однако для лучшей производительности желательно фильтровать данные сразу на уровне SQL, что требует переносить часть логики в базу — а этого нам делать не хочется.
ССЗБ?
Взяли нормальную базу -PostgreSql ,
Загнали туда кучу данных, а потом стали таскать все на клиента для расчетов и удивляемся что производительность упала?
У нас тут 3 камеры делают фото с частотой 30 KHz и льют в базу данных постргреса. И это практически в режиме 24х7. Правда запросы сложные писать не приходится так как там только числа в итоге.
Что то сомнения меня берут:
Вынуждены кэшировать доступность: почему это плохо
Приведу пример: кэш показывает, что номер доступен для бронирования, а на самом деле в базе данных он уже продан. В такой ситуации, если клиент попытается его забронировать, скорее всего, гость не сможет заселиться, и Островку придётся компенсировать расходы или искать альтернативный вариант размещения
Заходим на ваш сайт и ищем одеть где -нибудь на Канарах.
Нашли номер.
Звоним в отель, бронируем номер по телефону.
Жмем кнопку забронировать на вашем сайте - забронировали номер которого уже нет.
Я не думаю что товарищи с Канар вам сразу в систему введут что номер забронирован и отправят всем агрегаторам данных…,
Шах и мат :)
Работаю в той же сфере, что и автор, только компания другая)
Так вот, товарищи с Канар очень быстро увидят такую ситуацию в своей Property Management System (PMS), быстренько свяжутся с вами и попросят отменить бронирование в островке(комиссия же)
Это я к тому, что отели тоже все понимают и овербукинг по такого рода ситуациям не всегда решается в минус для поставщика услуги онлайн бронирования.
А вот когда ситуация становится стабильно неприятной (много оверов в период ажиотажа, например, черные пятницы) - вот тогда у отелей возникает вопросик уже, в том числе и финансовый.
Ну и последний момент, есть такая штука у отелей как "In-house квота" - это определенное количество номеров, которые не продается онлайн, а придерживается как раз под описанные вами ситуации (таким обычно довольно зрелые отели занимаются, где развито управление доходами через оптимизацию продаж, оно же Revenue)
Как так получается, что искать отели удобнее через агрегаторов, а бронировать лучше напрямую? - в этом случае отели дают хорошие скидки. При этом свободных номеров там практически нет.
Почему искать отели удобнее через агрегаторов - думаю ответ очевиден. А почему бронировать лучше напрямую - так просто потому, что отели агрегатору неплохо так комиссии отстегивают за каждое бронирование. И в некоторых случаях отелю выгодно сделать вам скидку по прямому бронированию вместо оплаты комиссии условному "booking.com"
Добрый день! Такой сценарий маловероятен. Если отель подтверждает доступность для OTA-канала (включая нас), он обязан отражать изменения в своей системе. Если бронь была продана в обход систем и возникнет конфликт, мы компенсируем клиенту бронь или предлагаем аналог, а дальше вопрос решается уже с отелем.
Поэтому подобная ситуация — скорее исключение, чем типичный кейс.
Проект был полностью инженерной инициативой — без запроса от бизнеса
Редкий случай. Но, очевидно, вы продали его через бизнес метрики
Если на этом этапе происходит ошибка, мы просто снимаем все локи и выходим — в базе транзакция откатится атомарно, а в память мы ничего не успели записать. Таким образом данные остаются корректными.
In-memory database -SQLite?
Ещё есть Aerospike и иже с ними. …
Предположим, есть функция апдейта календаря. Она получает контекст, в котором мы фиксируем, какие локи уже удерживаются. Далее мы перебираем все изменения и для каждого элемента заранее лочим соответствующую ячейку календаря в памяти.
есть подозрения что вы пытались реализовать старый добрый блокировщик - как большинство ДБ работали в старые добрые времена, пока Oracle/ Interbase не завезли версионники. Теперь в 21 века народ опять блокировщики пишет на коленке…..
Кстати вопрос, вы в строгого duckdb смотрели? Нормальная аналичточеская БД для больших данных. Как раз может обрабатывать все ваши запросы. А резервацию отдать на откуп PostgreSQL. Кстати duckdb - in-process DB
Кстати duckdb - in-process DB
DuckDB удобна на аналитических запросах, когда сами данные меняются редко. Как я понял из статьи, у них всего 130К отелей, но данные по бронированиям и доступным номерам разложены в общие таблицы. Поэтому, хоть по логике, ситуация для каждого из отелей в отдельности меняется не часто, суммарно в таблицы идёт большой постоянный поток изменений.
Так ВАК это не проблема. Меняются данные для одного отеля- нормальная задача решаемая на «калькуляторе»
Данные независимы. Единственное что надо быстро сделать это агрегировать их. Что аналитические БД эффективное могут делать.
Дальше работайте себе на здоровье.
Это не high frequency trading - номеров конечное количество и изменений мало.
Если номе разбронирован, то скорее всего в течение дня ситуация не поменяется.
У островка вроде 200 тыс «отелей» и 3 млн «размещений» в год. Т.е. можно сказать что 15 «номеров» на «отель»
15*365 =5.475 вариантов на год. (Занято/свободно) *200 тыс = ххх вариантов
Это модно упаковать в 130 МБ массив используя битовое представление: [день] [отель][номер]
130 мб это вообще не объем
Скорее всего можно ещё и кластеризовать на расположению: если вы ищите отель на Канарах, то вряд ли вас интересует отель в Тайланде.
Делим на 10 регионов:
Западная Европа, Африка, Ближний Восток, …
Грубо получаем 13 мб на регион.
Под каждый регион - по серверу. 10 серверов потянем.
допустим что у нас 1000 признаков классификации номеров/ сервисов на отель/номер.
Тогда нам надо 1000* 13 мб матриц= 13000 МБ= 1.3Гб. Все еще влезает в ОЗУ с запасом. Да и можем тупо с HHD читать все равно скорость выше чем открытие сетевого соединения. При нормальной скорости, можем передать на «клиента» за 1.7 минуты- сей час столько сайты грузятся :)
В итоге клиент может у себя в браузере запросы крутить сколько влезет, а нам только кидать данные на бронирование.
Индексы дней, строка отеля и комнаты. И список из 1000 атрибутов которые в 125 байт влезают. В общем 1 кБт данных нам выше крыши хватит чтобы за рост обработать.
В общем нет у них проблемы «больших» данных есть проблема с представлением данных. И понимания «бизнеса на земле »
БД вообще - то и сейчас блокировщики используют. Кто - то «почти» не использует - как PostgreSQL, а кто - то весьма активно - как SQL Server. А версионники и в 20 веке использовались, но не как механизм оптимизации, а для решения конкретных проблем конкурентного доступа
Высокопроизводительная decimal-библиотека fixed вместо популярной, но тяжёлой
shopspring/decimal
почему бы просто в integer не считать? У вас меньше 0.01 рубля все равно цены быть не может. Остальные цены либо в eur либо в usd. Поскольку вы в России, то скорее всего все придется в любом случае в рубли пересчитывать. Считаете к копейка/1000 и будет вам счастье
Во многих сценариях у нас применяются процентные скидки, комиссии, деление и другие вычисления. Поэтому нам важна точность до копеек — это уменьшает накопление погрешностей и снижает риск расхождений при финальном расчёте цены.
У вас на графиках идёт 30 тыс запроса в секунду на протяжении 4 часом.
Это 432 млн. Запросов за 4 часа.
Население Росси пусть будет. 200 млн.
У вас каждый житель +туристы сделали по два запроса в течение случайных 4-х часов?
Что-то не клеится….
Я бы предположил, что каждый запрос - это запрос по одному отелю. Если поисковая выдача содержит 30+ отелей, например, на одну страницу выдачи, то это уже 30+ запросов в движок от одного пользователя, а потом пользователь листает до следующей страницы (подгружает данные) или меняет даты проживания...
Сюда же добавим всяких ботов-парсеров, внешних партнёров с кривой интеграцией которые на каждый чих шлют кучу запросов и картинка, в общем-то, может сложиться.
Однако, 30к RPS звучит очень солидно, конечно, с текущими вводными.
Если посмотреть на механику реальных поисков, нагрузка формируется иначе.
Например, условный «серп» по Москве может включать ~10 000 отелей. Одно открытие такой страницы генерирует около 100 поисковых запросов, сгруппированных батчами. Есть и точечные запросы по одному отелю — их много со стороны b2b-клиентов и партнёров. Это даёт тот общий объём.
Ниже написал. У вас нет столько бронирований чтобы генерить столько запросов. Если создали кривую архитектуру что каждая запись из таблицы отдельным http запросом дергается, то ССЗБ. Тут вам никакое решение не поможет, так как время http request/response будет больше чем выборка из кеша/базы.
Проект был полностью инженерной инициативой — без запроса от бизнеса.
От первого коммита до полного переключения прошло три года.
Особенно порадовало: три года развлекались за счёт фирмы. Зачем это было нужно бизнесу? Не ясно…
Ну как же - у них же возникла проблема, которая ни у кого и никогда в истории человечества не возникала! Явно же, что использовать OLAP, другие кеши кроме редиса/другие OLTP не было вариантом.
не надо бояться писать кастомные решения
Да. Добавить только, что надо докупить памяти на 500к+ для экспериментов. Но для компаний уровня островка это капля в море. Ram лишней никогда не будет.
По описанному, задача не выглядит такой уж сложной. Часто сталкивался с кастомными кешами. Кроме арены еще часто sync.Pool используют. Странно по времени - 3 года. Обычно такие mvp за месяц пишут, взамен каким - нибудь готовым, но платным решениям.
По факту разработка окупилась примерно за месяц за счёт увеличения скорости поиска, улучшения конверсии и роста доли успешных бронирований.
К тому же три года — это не непрерывная full-time разработка. Пилотная версия была сделана довольно быстро, большая часть времени ушла на портирование поисковой логики, интеграции и тестирование под реальной нагрузкой.
Я не верю что увеличение скорости поиска сильно повлияло на результат. У вас уже цифры запросов не бьются с население России а тем более с количеством людей которые реально бронируют номера. Если чат гпт не врет то у вас около 3 млн бронирований в год. Это 8000 бронирований в день. Где тут 30 тыс запросов в секунду?
Могу сказать - браво! Вы проделали действительно сложную работу. Ну и CTO вашему тоже браво, что тему данную протащил и поддержал (думаю не без поддержки от него все произошло).
Эк меня тема зацепила…. Даю ещё бесплатный лайф хак. Переводим систему из «real-time” в режим пакетной обработки. Скажем с шагом. 1000msec.
Имеем замороженное состояние А. Отдаем его клиентам по запросу.
В течении 400msec собираем заявки на бронирование.
400 msec. Запускаем «аукцион» пытаемся продать номер максимально дорого. Поскольку у на экс мало шансов. Что все 30000 запросов в секунду хотят забронировать тот же самый номер, все не так уж и плохо и достаточно хорошо оптимизируется.
200 msec - обновить данные и подготовить состояние Б
Цикл повторяется. Клиентам которые шлют запросы на «забронированные номера» шлем ошибку и обновленные данные.
В результате никаких проблем с синхронизацией , блокировками и т.д.
Делаем один поток на отель = 200 000 потоков - erlang/go на одной машине легко потянет.
Решение сложное. Но расстраивает, что опять пишут велосипед. Нужно нанять архитектора и он за месяц выдаст принципиальное решение. Реализовывать которое небольшие полу года!
Почему не рассматривали переход на колоночную субд, имея столько признаков и аналит запросы?
Пользователь при бронировании взаимодействовал бы с постгрей, модификации улетали бы в OLAP, там агрегировались.
При поиске номеров - запрос к OLAP
Обновления можно и нужно заменить insert с новой версией записи.
Пишем свою in-memory базу на Go, ускоряем поиск отелей в десятки раз