PostgreSQL и кэш
Речь не про кэширование JPA, а про собственное кэширование БД.
1) на сервере есть 2 уровня кэширования: PostgreSQL buffer cache и Linux page cache. В отличие от Kafka, где он один.
А если использовать кэширование на уровне JPA, в итоге получается 4 уровня)
2) по умолчанию кэша выделяется мало, для PROD like его размер нужно увеличить.
Посмотреть сколько:
Изменить:
или через /etc/postgresql/../postgresql.conf
c рестартом сервера.
Универсальных рекомендаций по размеру быть не может, но можно начать с 1/4 ОЗУ.
3) размером Linux page cache напрямую управлять нельзя. Но его максимальный размер можно ограничить косвенно, через
Да, это процент использования swap файла, но как побочный эффект он ограничивает использование ОЗУ под page cache, и оставшееся пространство можно выделить PostgreSQL.
Зная эти два параметра можно рассчитать максимальное значение для кэша PostgreSQL:
4) со значением shared_buffers нужно быть осторожным, также как и с настройкой heap space в JVM. PostgreSQL ожидает, что вся эта память будет ему доступна.
Если ОЗУ закончится, а процесс будет все равно пытаться запрашивать память, придет злой OOM Killer и убьет его).
5) есть расширение pg_buffercache, предоставляющее одноименное view с информацией о страницах кэша PostgreSQL: к какой таблице относится, как используется.
Перед его использованием нужно само собой установить:
перегрузить сервер и дать права:
Использование:
6) при старте PostgreSQL все кэши пустые.
Интересно, что "SELECT *" не заполняет кэш на 100%, т.к. используется более хитрый механизм, когда для каждой выполняемой операции выделяется часть кэша.
А вот изменение данных, которое тоже идет через буфер, точно кэширует все изменяемые данные.
7) изменение данных - плохой способ заполнить кэш.
А часто прогреть кэш нужно, как минимум для справочных данных.
Да вообще говоря и для любых данных, т.к. если удастся поместить всю БД в кэш, то это ускорит работу с БД на пару порядков (ОЗУ vs диски).
Ну и если быть точным - ускорит серверную часть процесса, см. https://t.me/javaKotlinDevOps/487
И ... для прогрева кэша тоже есть расширение:
и рестарт.
Использование:
8) PostgreSQL сам чистит кэш в фоновом режиме, а явно сбросить кэш можно только перезагрузкой сервера. Что-то мне это напоминает из мира Java)
#cache #postgresql #performance
Речь не про кэширование JPA, а про собственное кэширование БД.
1) на сервере есть 2 уровня кэширования: PostgreSQL buffer cache и Linux page cache. В отличие от Kafka, где он один.
А если использовать кэширование на уровне JPA, в итоге получается 4 уровня)
2) по умолчанию кэша выделяется мало, для PROD like его размер нужно увеличить.
Посмотреть сколько:
SHOW shared_buffers
Изменить:
ALTER SYSTEM SET shared_buffers TO <your_value>; -- при наличии прав
или через /etc/postgresql/../postgresql.conf
c рестартом сервера.
Универсальных рекомендаций по размеру быть не может, но можно начать с 1/4 ОЗУ.
3) размером Linux page cache напрямую управлять нельзя. Но его максимальный размер можно ограничить косвенно, через
sysctl vm.swappiness
Да, это процент использования swap файла, но как побочный эффект он ограничивает использование ОЗУ под page cache, и оставшееся пространство можно выделить PostgreSQL.
Зная эти два параметра можно рассчитать максимальное значение для кэша PostgreSQL:
shared_buffers ~= ОЗУ * vm.swappiness - резерв ОС - резерв PostgreSQL
4) со значением shared_buffers нужно быть осторожным, также как и с настройкой heap space в JVM. PostgreSQL ожидает, что вся эта память будет ему доступна.
Если ОЗУ закончится, а процесс будет все равно пытаться запрашивать память, придет злой OOM Killer и убьет его).
5) есть расширение pg_buffercache, предоставляющее одноименное view с информацией о страницах кэша PostgreSQL: к какой таблице относится, как используется.
Перед его использованием нужно само собой установить:
CREATE EXTENSION pg_buffercache;
перегрузить сервер и дать права:
GRANT pg_monitor TO xxx;
Использование:
SELECT count(*)
FROM pg_buffercache
WHERE relfilenode = pg_relation_filenode('table'::regclass);
6) при старте PostgreSQL все кэши пустые.
Интересно, что "SELECT *" не заполняет кэш на 100%, т.к. используется более хитрый механизм, когда для каждой выполняемой операции выделяется часть кэша.
А вот изменение данных, которое тоже идет через буфер, точно кэширует все изменяемые данные.
7) изменение данных - плохой способ заполнить кэш.
А часто прогреть кэш нужно, как минимум для справочных данных.
Да вообще говоря и для любых данных, т.к. если удастся поместить всю БД в кэш, то это ускорит работу с БД на пару порядков (ОЗУ vs диски).
Ну и если быть точным - ускорит серверную часть процесса, см. https://t.me/javaKotlinDevOps/487
И ... для прогрева кэша тоже есть расширение:
CREATE EXTENSION pg_prewarm;
ALTER SYSTEM SET shared_preload_libraries = 'pg_prewarm';
и рестарт.
Использование:
SELECT pg_prewarm('table');8) PostgreSQL сам чистит кэш в фоновом режиме, а явно сбросить кэш можно только перезагрузкой сервера. Что-то мне это напоминает из мира Java)
#cache #postgresql #performance
Telegram
(java || kotlin) && devOps
EXPLAIN не так прост, как кажется.
Многие - сужу по проводимым собесам - знают про EXPLAIN и план выполнения запроса.
Вопрос - насколько этот план, а точнее цифры в нем, отражают реальность? Например, время выполнения запроса.
Я бы ввел 4 уровня приближения…
Многие - сужу по проводимым собесам - знают про EXPLAIN и план выполнения запроса.
Вопрос - насколько этот план, а точнее цифры в нем, отражают реальность? Например, время выполнения запроса.
Я бы ввел 4 уровня приближения…