Comments 24
Использую систему лока ключей кеша. Первый процесс делает лок, остальные ждут.
+1
данный пост предлагает не ждать, а вы своим комментом опять предлагаете ждать… зачем???
нужно просто начинать делать SQL запрос раньше времени устаревания на время выполнения запроса(среднее время выполнения запроса + запас)… т.к. в разное время суток(или по др. признаку) среднее время может меняться, то его хорошо бы всегда считать и хранить вместе с результатами запроса…
таким образом 1 процесс зависнет на 1 секунду выполняя запрос, а остальные в это время ещё получают актуальные(т.к. время жизни ещё не истекло) данные из memcached…
нужно просто начинать делать SQL запрос раньше времени устаревания на время выполнения запроса(среднее время выполнения запроса + запас)… т.к. в разное время суток(или по др. признаку) среднее время может меняться, то его хорошо бы всегда считать и хранить вместе с результатами запроса…
таким образом 1 процесс зависнет на 1 секунду выполняя запрос, а остальные в это время ещё получают актуальные(т.к. время жизни ещё не истекло) данные из memcached…
0
Устаревание по времени это только один из use-case'ов. При этом достаточно равномерно распределенынй по времени. В остальных двух (когда данных вообще нет в кеше и, что более ресурсоемко и концентрированно во времени, сброс тегов) что делать? Предуагадать когда момент устаревания тега невозмоно. Поэтому чтобы не городить огород, думаю лучше всегда ждать.
0
1. если данных нет, понятное дело придётся ждать…
2. данные есть, всегда берём из memcached и только один готовит новую порцию данных заранее… остальные никогда не ждут.
3. если ключ зависит от тега, а тег изменился — значит по новому ключу данных нет, а это 1й случай… (даже прогать ничё не надо)
PS: Коль уж зачем городить огород, зачем вообще браться за memcached, брать из базы да и всё… Да и вообще зачем прогать…
2. данные есть, всегда берём из memcached и только один готовит новую порцию данных заранее… остальные никогда не ждут.
3. если ключ зависит от тега, а тег изменился — значит по новому ключу данных нет, а это 1й случай… (даже прогать ничё не надо)
PS: Коль уж зачем городить огород, зачем вообще браться за memcached, брать из базы да и всё… Да и вообще зачем прогать…
0
99% вероятность что любой SQL-запрос по выборке товаров в магазине не будет выполняться 10 секунд. Там просто нечего так долго искать.
Надо не кеш собственный делать а проверить структуру таблиц и запросов. Тем более что любой взрослый SQL-сервер сам кеширует данные результатов запросов и делает это очень эффективно.
Надо не кеш собственный делать а проверить структуру таблиц и запросов. Тем более что любой взрослый SQL-сервер сам кеширует данные результатов запросов и делает это очень эффективно.
+9
Меня всегда умиляет, когда о проектировании системы кэширования пишут в трех пунктах и за основу берут какой-нибудь интернет-магазинчик, у которого просто чуть-чуть выросла посещаемость.
Лушче напишите в девяносто седьмой раз о локах, гонках, о кольцевом кэшировании, о тэгах и версионных тэгах в кэше.
Лушче напишите в девяносто седьмой раз о локах, гонках, о кольцевом кэшировании, о тэгах и версионных тэгах в кэше.
+8
Порекомендуйте хорошую статью, что ли.
+1
посмотрите доклад по мемкешу с хайлоад smotri.com/video/view/?id=v649374d232 — оч доходчиво и полезно
+2
Чистить кэш по времени и заполнять его новым значением по крону своим скриптом.
1. Сгенерили кэш
2. Записали в базу
3. Стерли старый (если не перезаписан в пункте 1)
1. Сгенерили кэш
2. Записали в базу
3. Стерли старый (если не перезаписан в пункте 1)
0
Как уже было сказано выше, небольшой инет-магазин просто не может генерировать такие нагрузки. Скорее всего, проблема в структуре БД или неоптимальных запросах. Выкладывайте свои запросы (желательно с планами), будем разбираться. Можно в личку.
0
Алгоритм должен быть такой: строим новый кэш -> удаляем старый + блокировка.
Тот же MySQL умеет кэшировать запросы. Едиственное но, он использует ключ для кэша — сам sql запрос, мало того, ключ регистрозависим.
Тот же MySQL умеет кэшировать запросы. Едиственное но, он использует ключ для кэша — сам sql запрос, мало того, ключ регистрозависим.
0
Странно, что никто еще не написал про memcached :)
0
habrahabr.ru/blogs/sql/127871/#comment_4227182 — я вот тут писал ;))
0
Глобально :)
0
судя по всему вам надо грубо говоря 1 запрос — почему бы не делать это по крону и класть в кеш?
0
Судя по тому, что у кеша есть время жизни (думаю, не меньше часа, учитывая, что приходится 10 сек запрос выполнять — иначе смысле нет), на сайте интернет-магазина не очень большой товарооборот, иначе топ10 просто не будет отображать реальную ситуацию. В этом случае, целесообразно создать новую таблицу типа
Эта таблица будет содержать столько строк, сколько различных единиц товара есть в вашем магазине (могу предположить, что различных позиций меньше 100К).
Затем, на таблицу покупок можно повесить триггер, который бы обновлял(или добавлял) значение в таблицу MART.GOODSCNT. Учитывая мое предположение, что товарооборот не слишком велик, дополнительная нагрузка на базу будет незначительной.
В этом случае будет довольно просто вывести топ10 (вместо SELECT COUNT(), который вы, возможно используете)
Второй вариант, который мне приходит в голову — это создание материализованных таблиц, которые специально созданы для кеширования результатов запроса в виде таблицы. Не факт, правда, что используемая вами СУБД их поддерживает. Если такие таблицы поддерживаются, вам потребуется лишь настроить расписание их обновления.
Третий вариант — создание специализированного хранилища данных (Data warehouse) и ETL-jobs для переливки и агрегации аналитических данных. Но, в случае с небольшим интернет магазином это решение слишком дорогостоящее.
Все эти варианты можно рассматривать, если вы уверены, что текущими средствами не удается добиться прироста производительности вашего SQL запроса.
В целом, я согласен с комментарием . 10 секунд слишком много для выполнения запросов по интернет магазину. Для примера, могу сказать, что на моей практике формирование аналитического запроса с таблицей фактов >37M строк занимает 5-6 секунд.
CREATE
TABLE MART.GOODSCNT
(
--Идентификатор товара
GID INTEGER NOT NULL,
--Количество товара
GCNT INTEGER,
CONSTRAINT GD_PK PRIMARY KEY (GID)
)
Эта таблица будет содержать столько строк, сколько различных единиц товара есть в вашем магазине (могу предположить, что различных позиций меньше 100К).
Затем, на таблицу покупок можно повесить триггер, который бы обновлял(или добавлял) значение в таблицу MART.GOODSCNT. Учитывая мое предположение, что товарооборот не слишком велик, дополнительная нагрузка на базу будет незначительной.
В этом случае будет довольно просто вывести топ10 (вместо SELECT COUNT(), который вы, возможно используете)
SELECT GID FROM MART.GOODSCNT ORDER BY GCNT DESC FETCH FIRST 10 ROWS ONLY
Второй вариант, который мне приходит в голову — это создание материализованных таблиц, которые специально созданы для кеширования результатов запроса в виде таблицы. Не факт, правда, что используемая вами СУБД их поддерживает. Если такие таблицы поддерживаются, вам потребуется лишь настроить расписание их обновления.
Третий вариант — создание специализированного хранилища данных (Data warehouse) и ETL-jobs для переливки и агрегации аналитических данных. Но, в случае с небольшим интернет магазином это решение слишком дорогостоящее.
Все эти варианты можно рассматривать, если вы уверены, что текущими средствами не удается добиться прироста производительности вашего SQL запроса.
В целом, я согласен с комментарием . 10 секунд слишком много для выполнения запросов по интернет магазину. Для примера, могу сказать, что на моей практике формирование аналитического запроса с таблицей фактов >37M строк занимает 5-6 секунд.
0
Sign up to leave a comment.
О кэшировании ресурсоемких SQL-запросов на веб-сервере