|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
Здравствуйте. Начитался тут https://m.habr.com/ru/company/oleg-bunin/blog/316652/ У меня вроде как аналогично. Ну только разве что масштабы не те) и без memcached Клиент делает запрос, если в редисе нет данных— берет с базы и по пути складывает в redis. Последующий заход — сразу из редиса Тут вроде как все более менее понятно. А вот со стороны сервера данные, которые относятся к конкретному клиенту могут меняться в базе за сутки раз 10. Вернее добавляться новые. Пока сделал так. Если данные клиента добавлены— после добавления в базу удаляется запись из редиса Ну и если клиент зайдет чуть позже , то не найдет ничего в редисе. Ну а далее по алгоритму что выше описан. Вроде как все красиво более менее. Только смущает что данные клиента как уже писал за сутки могут раз 10 поменяться. Причем внутри суток все может быть размазано почти равномерно. В итоге получается, что может возникнуть такая ситуация, что будет постоянно со стороны сервера будут добавляться данные и грохаться запись редиса. А клиент будет постоянно «долбиться», не находить ничего в редисе и брать все из базы. Иди я слегка перемудрил? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 02:32 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
Максимум что скудный умишко подсказывает — ставить в редисе ttl записи минут 20. В итоге запись протухнет через 20 минут и при следующем запросе данные подскребутся с базы ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 02:36 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
sergq В итоге получается, что может возникнуть такая ситуация, что будет постоянно со стороны сервера будут добавляться данные и грохаться запись редиса. А клиент будет постоянно «долбиться», не находить ничего в редисе и брать все из базы. Ну а в чём проблема? Это абсолютно нормально. Вы можете поставить метрики на эти операции и следить как часто используется кеш для передачи данных клиенту. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 10:22 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
sergq Максимум что скудный умишко подсказывает — ставить в редисе ttl записи минут 20. Тогда в течение 20 минут клиент может получать не актуальные данные. Если по бизнесу это ок, делайте так. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 10:22 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
>sergq, сегодня, 02:32 https://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1324233&msg=22113944][22113944] >...Если данные клиента добавлены— после добавления в базу удаляется запись из редиса ... < А если так: 1. после добавления в базу меняется запись в редисе по клиенту, если она там есть (у клиента суррогатный ключ). 2. запрос клиента. ЕСЛИ нет в кеше ТО { //--у каждой записи в кеше имеется параметр - время крайнего обращения ЕСЛИ есть место в кеше ТО запись с сервера в кеш ИНАЧЕ { удаляем ту запись из кеша, которая имеет максимальное время не использования; запись с сервера в кеш } } берем из кеша. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 13:02 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
sergq Иди я слегка перемудрил? Скорее слегка не додумали. При изменении вы удаляете запись из редиса - это правильно. Но делать это надо не после сохранения в базе, а до. Чтобы, если непосредственно что-то упадёт при сохранении в бд, то в кэше не остались старые данные. А после сохранения следует поместить актуальные данные в редис, так, как вы это делаете при чтении. Это называется Декоратор: вы оборачиваете работу с БД логикой работы с кэшем. На чём код пишите? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 14:13 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
Дмитрий Мух Но делать это надо не после сохранения в базе, а до. Чтобы, если непосредственно что-то упадёт при сохранении в бд, то в кэше не остались старые данные. Если важно всегда 100% получать актуальные, то этого тоже недостаточно. Нужна блокировка. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 15:24 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
Дмитрий Мух sergq Иди я слегка перемудрил? Скорее слегка не додумали. При изменении вы удаляете запись из редиса - это правильно. Но делать это надо не после сохранения в базе, а до. Чтобы, если непосредственно что-то упадёт при сохранении в бд, то в кэше не остались старые данные. А после сохранения следует поместить актуальные данные в редис, так, как вы это делаете при чтении. Это называется Декоратор: вы оборачиваете работу с БД логикой работы с кэшем. На чём код пишите? nodejs на сервере. чуток я не так описал как было с клиентом. приходит. если в редисе нет - формирует запрос табличке, где уже подготовленные json лежат. если и там нет - запрос в базу, кладется в табличку json и в редис. вчера убрал эту промежуточную таблицу с подготовленными json и огреб ступор сервера. те когда на сервере что то добавлялось, то удалялось и редиса и в следующий раз клиенту приходилось делать полный запрос к базе. Все стало раком а схема основная не понравилась потому, что замечал такое, что в промежуточной табличке с json для клиента ничего не было, а в редисе было. но уже протухшее. приходилось отдельный скрипт запускать чтоб все актуализировать. А протухало думаю по такой причине. тк все идет параллельно. и на сервере добавляется и клиенты читают если выполняется в такой последовательности Клиент:Считал старое из базы. json в промежуточной таблице Сервер(идет добавление инфы относящейся к клиенту): удалил json в промежуточной таблице Транзакции разные. Значит теоретически видно и старое и новое значение json в таблице сервер(идет добавление инфы относящейся к клиенту): удалил из редиса клиент: положил в редис старое что считалось В итоге в редисе старое . В базу никто не ходит . Для клиентов это актуальное значение ну по крайней мере количество записей в редисе не совпадало с количеством записей в промежуточной таблице где json хранятся ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 16:30 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
hVostt Дмитрий Мух Но делать это надо не после сохранения в базе, а до. Чтобы, если непосредственно что-то упадёт при сохранении в бд, то в кэше не остались старые данные. Если важно всегда 100% получать актуальные, то этого тоже недостаточно. Нужна блокировка. в том то и дело, что когда сменил логику (выше описал), то огреб большое количество запросов к базе. тк, допустим, в минуту на сервере может добавиться инфа, относящаяся к клиенту раз 10-15. и все в разных "транзакциях" не знаю на сколько это правильно, но есть еще мысль. когда в базу добавляется со стороны сервера что то, относящееся к клиенту - брать из редиса json, добавлять в него данные и класть обратно в редис Хотя врятли это тоже будет работать, тк может получиться так. 1. на сервере добавилась запись для клиента 2. сервер взял из редиса json, добавляет данные 3. в это ж время еще записи добавились для клиента. 4. сервер опять забрал json из редиса. но получается в данном случае оригинальный-первичный. и тоже добавляет. В итоге рассинхрон ( Можно чуть подробней про блокировку ) ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 16:37 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
воспользовался темой как диалогом ) я правильно додумал, что чтоб рассинхрона не произошло, то можно, например, использовать кролика. при добавлении на сервер данные кидать в очередь. и обрабатывать ее. получится последовательно. и никакого рассинхрона ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 16:47 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
hVostt Дмитрий Мух Но делать это надо не после сохранения в базе, а до. Чтобы, если непосредственно что-то упадёт при сохранении в бд, то в кэше не остались старые данные. Если важно всегда 100% получать актуальные, то этого тоже недостаточно. Нужна блокировка. Блокировка чего и зачем? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 17:11 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
sergq, что-то не понимаю я ваших проблем... седьмой год используем Декоратор поверх Репозитория Hit Ratio 98-100% и в кэше всегда актуальные данные за исключением тех редких случаев, когда кто-то напрямую в базу полез и что-то там изменил ручками, или скриптом ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 17:18 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
sergq hVostt пропущено... Если важно всегда 100% получать актуальные, то этого тоже недостаточно. Нужна блокировка. в том то и дело, что когда сменил логику (выше описал), то огреб большое количество запросов к базе. тк, допустим, в минуту на сервере может добавиться инфа, относящаяся к клиенту раз 10-15. и все в разных "транзакциях" не знаю на сколько это правильно, но есть еще мысль. когда в базу добавляется со стороны сервера что то, относящееся к клиенту - брать из редиса json, добавлять в него данные и класть обратно в редис Хотя врятли это тоже будет работать, тк может получиться так. 1. на сервере добавилась запись для клиента 2. сервер взял из редиса json, добавляет данные 3. в это ж время еще записи добавились для клиента. 4. сервер опять забрал json из редиса. но получается в данном случае оригинальный-первичный. и тоже добавляет. В итоге рассинхрон ( Можно чуть подробней про блокировку ) зачем из редиса брать json? в каком виде вы данные кладёте в редис? из чего их получаете (сериализуете)? и что это вообще за данные? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 17:23 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
sergq воспользовался темой как диалогом ) я правильно додумал, что чтоб рассинхрона не произошло, то можно, например, использовать кролика. при добавлении на сервер данные кидать в очередь. и обрабатывать ее. получится последовательно. и никакого рассинхрона поясните, что такое "данные, которые относятся к конкретному клиенту могут меняться в базе за сутки раз 10"? чем вы оперируете: Сущностями, агрегатами, командами? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 17:25 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
Дмитрий Мух sergq пропущено... в том то и дело, что когда сменил логику (выше описал), то огреб большое количество запросов к базе. тк, допустим, в минуту на сервере может добавиться инфа, относящаяся к клиенту раз 10-15. и все в разных "транзакциях" не знаю на сколько это правильно, но есть еще мысль. когда в базу добавляется со стороны сервера что то, относящееся к клиенту - брать из редиса json, добавлять в него данные и класть обратно в редис Хотя врятли это тоже будет работать, тк может получиться так. 1. на сервере добавилась запись для клиента 2. сервер взял из редиса json, добавляет данные 3. в это ж время еще записи добавились для клиента. 4. сервер опять забрал json из редиса. но получается в данном случае оригинальный-первичный. и тоже добавляет. В итоге рассинхрон ( Можно чуть подробней про блокировку ) зачем из редиса брать json? в каком виде вы данные кладёте в редис? из чего их получаете (сериализуете)? и что это вообще за данные? В редисе лежит json. Имя ключа — ид клиента. В json данные дляотображения на клиенте в виде таблицы. Если упрощенно— журнал документов в которых фигурирует клиент ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 17:45 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
Дмитрий Мух sergq воспользовался темой как диалогом ) я правильно додумал, что чтоб рассинхрона не произошло, то можно, например, использовать кролика. при добавлении на сервер данные кидать в очередь. и обрабатывать ее. получится последовательно. и никакого рассинхрона поясните, что такое "данные, которые относятся к конкретному клиенту могут меняться в базе за сутки раз 10"? чем вы оперируете: Сущностями, агрегатами, командами? Документы, в которых фигурирует клиент. На сервер за минуту— две может добавиться 10 документов, в которых данный клиент (его ид) имеется. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 17:46 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
sergq Дмитрий Мух пропущено... поясните, что такое "данные, которые относятся к конкретному клиенту могут меняться в базе за сутки раз 10"? чем вы оперируете: Сущностями, агрегатами, командами? Документы, в которых фигурирует клиент. На сервер за минуту— две может добавиться 10 документов, в которых данный клиент (его ид) имеется. А если кэшировать сами документы, а не составлять из них JSON? Что вообще такое этот JSON? Некий отчёт, или что? По идее простой запрос списка документов, в которых фигурирует клиент, не должен вводить сервер в ступор. Откуда вдруг он случился? Пробовали понять? Вообщем будет лучше если вы толком объясните задачу, которую решаете. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 18:38 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
Дмитрий Мух sergq пропущено... Документы, в которых фигурирует клиент. На сервер за минуту— две может добавиться 10 документов, в которых данный клиент (его ид) имеется. А если кэшировать сами документы, а не составлять из них JSON? Что вообще такое этот JSON? Некий отчёт, или что? По идее простой запрос списка документов, в которых фигурирует клиент, не должен вводить сервер в ступор. Откуда вдруг он случился? Пробовали понять? Вообщем будет лучше если вы толком объясните задачу, коорую решаете. Откуда он случился понять не осилил) Или скорее не успел. ибо погряз в сообщениях и звонках. Как одну из простых мер увеличил пул коннектов к базе в три раза— ушло в ступор через 15 минут. Все коннекты в пуле были заняты. Ну и соответственно последующему запросу клиента приходилось ждать, пока в пуле появится свободный коннект. Пришлось вернуть предидущую версию сервера. В базе хранятся стандартные документы. Две таблицы. Шапка, тело. Со стороны сервера ( скорее один тип клиентов) идет добавление этих документов. Это один экземпляр nodejs со своим пулом коннектов к базе. Внешние клиенты(другой экземпляр nodejs) заходят и должны видеть в виде таблицы в каких введенных документах они фигурируют. По этому и формируется json. На клиенте на его основе отображается таблица. Даже если брать напрямую из тех двух таблиц данные, то все равно возвращать клиенту json. Те задача сводится к: с одной стороны навводили документов. С другой стороны конкретный клиент смотрит в каких он есть Подумал реализовать через rabbit. Те когда добавляется документ в кролика кидается инфа какие клиенты есть в документе. А с другой стороны consumer подгребает очередь, находит нужный ключ в редисе, добавляет в его json данные и обновляет значение ключа. Единственное обработка очереди должна идти последовательно ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 18:53 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
sergq Дмитрий Мух пропущено... А если кэшировать сами документы, а не составлять из них JSON? Что вообще такое этот JSON? Некий отчёт, или что? По идее простой запрос списка документов, в которых фигурирует клиент, не должен вводить сервер в ступор. Откуда вдруг он случился? Пробовали понять? Вообщем будет лучше если вы толком объясните задачу, коорую решаете. Откуда он случился понять не осилил) Или скорее не успел. ибо погряз в сообщениях и звонках. Как одну из простых мер увеличил пул коннектов к базе в три раза— ушло в ступор через 15 минут. Все коннекты в пуле были заняты. Ну и соответственно последующему запросу клиента приходилось ждать, пока в пуле появится свободный коннект. Пришлось вернуть предидущую версию сервера. В базе хранятся стандартные документы. Две таблицы. Шапка, тело. Со стороны сервера ( скорее один тип клиентов) идет добавление этих документов. Это один экземпляр nodejs со своим пулом коннектов к базе. Внешние клиенты(другой экземпляр nodejs) заходят и должны видеть в виде таблицы в каких введенных документах они фигурируют. По этому и формируется json. На клиенте на его основе отображается таблица. Даже если брать напрямую из тех двух таблиц данные, то все равно возвращать клиенту json. Те задача сводится к: с одной стороны навводили документов. С другой стороны конкретный клиент смотрит в каких он есть Подумал реализовать через rabbit. Те когда добавляется документ в кролика кидается инфа какие клиенты есть в документе. А с другой стороны consumer подгребает очередь, находит нужный ключ в редисе, добавляет в его json данные и обновляет значение ключа. Единственное обработка очереди должна идти последовательно Простая вроде задачка: сделал запрос, сформировал json, отдал клиенту. Пока не понятно для чего тут кэш и тем более очередь. Какова нагрузка на чтение, сколько запросов в секунду? Сколько по времени выполняется запрос списка документов по клиенту? Чем коннекты были заняты? Может у вас просто коннекты не освобождаются после выполнения запроса? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 19:04 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
Я бы начал не с кэширования, а с того, почему пул коннектов к базе выбирается. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 19:20 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
Дмитрий Мух Простая вроде задачка: сделал запрос, сформировал json, отдал клиенту. Пока не понятно для чего тут кэш и тем более очередь. Какова нагрузка на чтение, сколько запросов в секунду? Сколько по времени выполняется запрос списка документов по клиенту? Чем коннекты были заняты? Может у вас просто коннекты не освобождаются после выполнения запроса? Кэш просто поэспериментировать ) когда табличка из json на клиенте отображается- клиент может скачать "пристегнутый " к позиции файл. файл лежит в базе. Знаю, что это плохо. но пока так. файлы относительно небольшие. до метра. а коннекты к базе освобождались после того, как файл из базы был отдан клиенту (pipe) но что вчера что сегодня в части скачивания пристегнутого файла все идентично. те вчера была такая логика (получения списка). редис-база (подготовленный json)-непосредственно запрос к базе сегодня такая логика. редис-непосредственно запрос к базе. и вот это и стало колом. с учетом того, что файлы еще по другому url скачивались. но они и вчера и сегодня скачивались ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 19:21 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
sergq Дмитрий Мух Простая вроде задачка: сделал запрос, сформировал json, отдал клиенту. Пока не понятно для чего тут кэш и тем более очередь. Какова нагрузка на чтение, сколько запросов в секунду? Сколько по времени выполняется запрос списка документов по клиенту? Чем коннекты были заняты? Может у вас просто коннекты не освобождаются после выполнения запроса? Кэш просто поэспериментировать ) когда табличка из json на клиенте отображается- клиент может скачать "пристегнутый " к позиции файл. файл лежит в базе. Знаю, что это плохо. но пока так. файлы относительно небольшие. до метра. а коннекты к базе освобождались после того, как файл из базы был отдан клиенту (pipe) но что вчера что сегодня в части скачивания пристегнутого файла все идентично. те вчера была такая логика (получения списка). редис-база (подготовленный json)-непосредственно запрос к базе сегодня такая логика. редис-непосредственно запрос к базе. и вот это и стало колом. с учетом того, что файлы еще по другому url скачивались. но они и вчера и сегодня скачивались При получении списка ещё и все файлы, что к нему "пристегнуты" выбираются из базы? То есть в запросе к БД за списком фигурирует BLOB поле, где данные файла хранятся? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 19:36 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
Дмитрий Мух Я бы начал не с кэширования, а с того, почему пул коннектов к базе выбирается. как вариант - резвый клиент. посмотрел по логу - 20 файлов "заказал" скачивать за 2 секунды. а файлы в базе.... Но. почему вчера до смены логики такого не было. хотя в логике просто убрался промежуточный слой к базе хожу с использованием node-firebird. показывало, что все коннекты заняты. есть у этого компонента еще свойство pending. массив. описания не нашел. но оно было по размеру примерно на порядок больше, чем количество занятых коннектов к базе ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 19:36 |
|
Вопрос по кешированию
|
|||
---|---|---|---|
#18+
Дмитрий Мух hVostt пропущено... Если важно всегда 100% получать актуальные, то этого тоже недостаточно. Нужна блокировка. Блокировка чего и зачем? 1. Логика, которая приводит к изменениям данных 2. Инвалидируется кеш 3. Данные сохраняются в БД Между 2 и 3 другой клиент может выполнить запрос, который приведёт к заполнению кеша, уже не верными данными. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2020, 19:59 |
|
|
start [/forum/topic.php?fid=33&msg=39945979&tid=1547108]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
140ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
67ms |
get tp. blocked users: |
1ms |
others: | 310ms |
total: | 566ms |
0 / 0 |