diff --git a/dev/architecture/highload/Асинхронная репликация.md b/dev/architecture/highload/Асинхронная репликация.md new file mode 100644 index 00000000..399418ae --- /dev/null +++ b/dev/architecture/highload/Асинхронная репликация.md @@ -0,0 +1,53 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-06-07 +zero-link: + - "[[../../../meta/zero/00 HighLoad|00 HighLoad]]" +parents: + - "[[Репликация БД]]" +linked: + - "[[Синхронная репликация]]" + - "[[Полу-синхронная репликация]]" +--- +Изменения записываются на master и пересылаются на slaves с некоторой задержкой. Этот метод отличается от синхронной репликации тем, что подтверждение транзакции возвращается клиенту до того, как изменения применены на всех репликах, что позволяет улучшить производительность, но может привести к несогласованности данных. + +Быстро, но не надежно. Возможно используется по умолчанию. Реализовано в [MySQL](../../../meta/zero/00%20MySQL.md), [PostgreSQL](../../../meta/zero/00%20PostgreSQL.md) + +Схема выполнения на MySQL. +![](../../../meta/files/images/Pasted%20image%2020240206195611.png) + +**Как работает** +- Подготовка транзакции в движке БД: Транзакция начинается на главном сервере, где собираются все изменения данных. +- Запись транзакции в лог: Все изменения записываются в журнал транзакций (например, Write-Ahead Log в PostgreSQL). +- Завершение транзакции в движке БД: Транзакция завершается на master. +- Возврат результата клиенту: Клиент получает подтверждение о завершении транзакции +- Пересылка лога репликам: Журнал транзакций отправляется на реплики для асинхронного применения изменений. +- Воспроизведение транзакции на репликах: Реплики получают журнал и применяют изменения к своим копиям данных, но это может произойти с задержкой. + +**Преимущества** +- Высокая производительность: Поскольку подтверждение транзакции возвращается клиенту до её применения на репликах, время отклика уменьшается, что улучшает производительность системы. +- Уменьшенная нагрузка на сеть: Пересылка изменений на реплики происходит асинхронно, что снижает нагрузку на сеть и позволяет более эффективно использовать сетевые ресурсы. +- Гибкость в использовании: Асинхронная репликация позволяет использовать реплики для различных задач, таких как отчеты или резервное копирование, без влияния на производительность главного сервера. + +**Минусы** +- Потеря данных при сбое: Если master выходит из строя до пересылки изменений на реплики, данные могут быть потеряны. Это может привести к несогласованности данных и необходимости восстановления системы. +- [Отставание реплики БД](Отставание%20реплики%20БД.md): Задержка в применении изменений на репликах может привести к отставанию реплик от master, что может затруднить выполнение некоторых операций, требующих актуальных данных. +- Проблемы с консистентностью данных: Каждая реплика может отставать по разному, из-за этого данные могут быть несогласованными между репликами. Например, пользователь может получить разные результаты для одного и того же запроса. + +## Примеры использования +Асинхронная репликация широко используется в системах, где высокая производительность и низкое время отклика имеют приоритет над полной консистентностью данных. Например, в системах аналитики и отчетности, где задержки в обновлении данных не критичны, асинхронная репликация позволяет эффективно распределять нагрузку и использовать реплики для выполнения сложных запросов, не влияя на производительность основного сервера. +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 HighLoad|00 HighLoad]] +**Родитель**:: [[Репликация БД]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-06-07]] +### Дополнительные материалы +- [[Синхронная репликация]] +- [[Полу-синхронная репликация|Полу-синхронная репликация]] +### Дочерние заметки + diff --git a/dev/architecture/highload/Безмастерная репликация.md b/dev/architecture/highload/Безмастерная репликация.md new file mode 100644 index 00000000..0459ef33 --- /dev/null +++ b/dev/architecture/highload/Безмастерная репликация.md @@ -0,0 +1,67 @@ +--- +aliases: + - безмастерной репликацией +tags: + - maturity/🌱 +date: + - - 2024-06-04 +zero-link: + - "[[../../../meta/zero/00 Базы Данных|00 Базы Данных]]" +parents: + - "[[Репликация БД|Репликация БД]]" +linked: +--- +Безмастерная репликация — это метод репликации в котором отсутствует главный master. Все узлы системы являются равноправными. + +Клиентские приложения могут записывать данные на любой узел системы. Более того ==запросы отправляются сразу на все реплики, но применяются только на тех, которые доступны в данный момент.== + +Для успешного завершения операции записи требуется подтверждение от определенного количества реплик (W). Если количество успешных записей превышает значение W, операция считается успешной. ==Если их меньше, но не 0, отката транзакции не будет.== + +Клиентские приложения читают данные со всех доступных в данный момент реплик. Для успешного чтения требуется подтверждение от определенного количества реплик (R). Если количество ответивших реплик превышает значение R, операция считается успешной. + +![800](../../../meta/files/images/Pasted%20image%2020240226135429.png) + +Формула расчета кворума: W + R > number of replics +- W - в каком количестве реплик должна примениться запись, чтобы мы считали ее успешной +- R - со скольки реплик мы должны прочитать значение ключа, чтобы считать, что чтение прошло успешным + +**Преимущества:** +- **Высокая доступность:** Поскольку все узлы являются равноправными, система не имеет единой точки отказа. Даже если несколько узлов выйдут из строя, остальные узлы продолжают обслуживать запросы. +- **Горизонтальное масштабирование:** Безмастерная репликация позволяет легко добавлять новые узлы для повышения производительности и масштабируемости системы. +- **Гибкость конфигурации:** Система может быть настроена для достижения различных уровней консистентности и доступности, в зависимости от требований приложений. + +**Проблемы:** +- [Нестрогий кворум](Нестрогий%20кворум.md). Возможно чтение старых данных при W+R < N +- Проблемы с откатом транзакций: В безмастерной репликации отсутствует механизм отката транзакций, что может усложнить управление ошибками и восстановление данных. + - Как в таком случае работает обновление при чтении или противодействие энтропии, ведь эти данные становятся новыми. +- Проблемы с консистентностью данных: Поскольку запись данных может происходить на нескольких узлах одновременно, возникает риск конфликтов и несогласованности данных. Для разрешения конфликтов используются различные методы, такие как Last Write Wins или версионирование данных. +- Конфликт записей и [Потерянное обновление](Потерянное%20обновление.md). +- Проблемы с линеаризуемостью. + +**Поддержание консистентности:** +- Анти-энтропия. Реплики могут периодически синхронизоваться друг с другом, чтобы обеспечить консистентность данных. +- Противодействие энтропии. Внешний клиент опрашивает все ноды, находит устаревшие данные и обновляет их. +- Обновление при чтении (Set on read). Берем последнюю версию после чтения и отправляем в реплики с устаревшими данными. +- Last write wins. Кто последний записал, те данные и верные. +- [Happens before](Happens%20before.md). +- Векторы версий. +- [Tombstone](Tombstone.md) + +Такая репликация есть в: +- DynamoDB +- [[Cassandra]] +- Scylla (Переписанная на C++ Cassandra) +- Riak +- Voldemort + +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 HighLoad|00 HighLoad]] +**Родитель**:: [[Репликация БД|Репликация БД]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-06-04]] +### Дополнительные материалы +- +### Дочерние заметки + diff --git a/dev/architecture/highload/Групповая репликация.md b/dev/architecture/highload/Групповая репликация.md new file mode 100644 index 00000000..bf9920ff --- /dev/null +++ b/dev/architecture/highload/Групповая репликация.md @@ -0,0 +1,40 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-06-05 +zero-link: + - "[[../../../meta/zero/00 HighLoad|00 HighLoad]]" +parents: + - "[[Репликация БД]]" +linked: +--- +Работает как [Репликация master-master](Репликация%20master-master.md), но при количестве узлов больше 2 + +- Все транзакции чтения и записи фиксируются только после того, как они были одобрены группой. +- Read-only транзакции не требуют координации внутри группы и фиксируются немедленно +- Групповая репликация - eventual consistency система + +![](../../../meta/files/images/Pasted%20image%2020240605091036.png) + +## Консенсус +- Когда транзакция read-write готова к фиксации на исходном сервере, сервер атомарно передает значения записи (строки, которые были изменены) и соответствующий набор записи (уникальные идентификаторы строк, которые были обновлены). +- Транзакция отправляется через атомарную broadcast рассылку, транзакцию получают либо все серверы в группе, либо ни один. +- Если они его получат, то все они получат его в том же порядке относительно других транзакций, которые были отправлены ранее. + +Таким образом, все серверы получают один и тот же набор транзакций в одном и том же порядке, и для транзакций устанавливается глобальный общий порядок. + +## Дополнительные материалы +- [MySQL 20.1.1.2 Group Replication](https://dev.mysql.com/doc/refman/8.0/en/group-replication-summary.html) +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 HighLoad|00 HighLoad]] +**Родитель**:: [[Репликация БД]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-06-05]] +### Дополнительные материалы +- +### Дочерние заметки + diff --git a/dev/architecture/highload/Ключ кэширования.md b/dev/architecture/highload/Ключ кэширования.md index 68f0e8af..df81e5ec 100644 --- a/dev/architecture/highload/Ключ кэширования.md +++ b/dev/architecture/highload/Ключ кэширования.md @@ -27,18 +27,18 @@ public List getUsersByType(String userType, Set userIds) Значения аргументов метода также должны попасть в ключ. Возьмем наш первый аргумент `String userType`. Для аргумента также можно использовать префиксы, но это не обязательно. В данном случае пусть будет `USER_TYPE`. А вот для самого значения параметра есть несколько вариантов: - Оставить строкой и просто выполнить конкатенацию. -- Использовать [[../../cryptography/Криптографическая хеш-функция|хеш-функцию]] с фиксированной длиной выхода, например [[../../cryptography/MD5|MD5]]. Фиксированная длина выхода нужна, чтобы иметь предсказуемую и ограниченную длину ключа. +- Использовать [[../../cryptography/Хеш-функция|хеш-функцию]] с фиксированной длиной выхода, например [[../../cryptography/MD5|MD5]]. Фиксированная длина выхода нужна, чтобы иметь предсказуемую и ограниченную длину ключа. Оставим просто строкой, так как тип пользователя вряд ли может быть длинным. В итоге пока наш ключ выглядит как-то так: `USER_SERVICE:USERS:USER_TYPE:VIP:`. -Переходим ко второму аргументу `Set userIds`. С коллекцией все будет сложнее. Мы точно должны использовать какую-нибудь [[../../cryptography/Криптографическая хеш-функция|хеш-функцию]], но как? +Переходим ко второму аргументу `Set userIds`. С коллекцией все будет сложнее. Мы точно должны использовать какую-нибудь [[../../cryptography/Хеш-функция|хеш-функцию]], но как? > [!WARNING] Disclamer > Этот способ я придумал сам, возможно он не самый удачный, но он работает. Если вы придумаете лучше, напишите в комментариях ниже 👇 -Во-первых, коллекцию необходимо предварительно отсортировать. Иначе на одинаковые параметры коллекций мы будем получать разные результаты [[../../cryptography/Криптографическая хеш-функция|хеш-функции]]. +Во-первых, коллекцию необходимо предварительно отсортировать. Иначе на одинаковые параметры коллекций мы будем получать разные результаты [[../../cryptography/Хеш-функция|хеш-функции]]. -Во-вторых, нужно представить коллекцию как что-то понятное для [[../../cryptography/Криптографическая хеш-функция|хеш-функции]]. Для этого я преобразую коллекцию в JSON. JSON используется, потому что ваша коллекция может быть из сложных объектов. +Во-вторых, нужно представить коллекцию как что-то понятное для [[../../cryptography/Хеш-функция|хеш-функции]]. Для этого я преобразую коллекцию в JSON. JSON используется, потому что ваша коллекция может быть из сложных объектов. Теперь используем [[../../cryptography/SHA-256|SHA-256]], чтобы из нашей строки получить какой-то хеш. И уже этот хеш мы добавляем к нашему ключу, получается примерно такое: diff --git a/dev/architecture/highload/Монотонное чтение.md b/dev/architecture/highload/Монотонное чтение.md new file mode 100644 index 00000000..b7aa1691 --- /dev/null +++ b/dev/architecture/highload/Монотонное чтение.md @@ -0,0 +1,26 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-06-07 +zero-link: + - "[[../../../meta/zero/00 HighLoad|00 HighLoad]]" +parents: + - "[[Репликация БД]]" +linked: +--- +Монотонное чтение — это проблема, возникающая при репликации данных, когда пользователи могут получить несогласованные результаты при выполнении последовательных запросов. Это происходит, когда изменения на мастере не успевают синхронизироваться с репликами, и разные запросы пользователя могут попадать на реплики с различными состояниями данных. +## Пример проблемы монотонного чтения +Рассмотрим ситуацию, когда пользователь запрашивает список комментариев к статье. Если новый комментарий был добавлен и записан на мастер, но ещё не успел синхронизироваться со всеми репликами, пользователь может столкнуться с несогласованными результатами: + +1. Пользователь делает первый запрос и получает список комментариев без нового комментария. +2. Пользователь делает второй запрос и получает список комментариев, включающий новый комментарий. +3. При следующем запросе пользователь снова может не увидеть новый комментарий, если его запрос попадает на другую реплику. + +![](../../../meta/files/images/Pasted%20image%2020240607211612.png) + +## Методы решения проблемы монотонного чтения +- Привязка пользователя к конкретной реплике (stickiness): Один из способов решения проблемы монотонного чтения — это привязка пользователя к конкретной реплике для всех последовательных запросов. Это можно реализовать с помощью сессий или токенов, обеспечивая пользователю доступ к одной и той же реплике, пока она доступна. +- Настройка задержек при чтении: Можно настроить задержки при чтении данных с реплик, чтобы обеспечить их синхронизацию с мастером. Например, задержка может быть настроена таким образом, чтобы реплики всегда отставали от мастера на фиксированное время, достаточное для синхронизации данных. +- Использование кворумных чтений: В системах с [[Безмастерная репликация|безмастерной репликацией]] можно использовать кворумные чтения, когда запросы выполняются на нескольких репликах одновременно, и результат считается успешным только если он подтвержден большинством реплик. Это повышает вероятность получения актуальных данных. \ No newline at end of file diff --git a/dev/architecture/highload/Отставание реплики БД.md b/dev/architecture/highload/Отставание реплики БД.md new file mode 100644 index 00000000..2c9e3f56 --- /dev/null +++ b/dev/architecture/highload/Отставание реплики БД.md @@ -0,0 +1,37 @@ +--- +aliases: + - лаг репликации + - задержки репликации + - задержка репликации +tags: + - maturity/🌱 +date: + - - 2024-06-04 +zero-link: + - "[[../../../meta/zero/00 HighLoad|00 HighLoad]]" +parents: + - "[[Репликация БД]]" +linked: +--- +Отставание реплики (или лаг репликации) — это проблема, возникающая, когда изменения, выполненные на мастере, не успевают применяться на репликах вовремя. Это может привести к несогласованности данных между мастером и репликами и затруднить выполнение операций, требующих актуальных данных. + +В нормальной ситуации отставание может достигать 1 секунды. + +![](../../../meta/files/images/Pasted%20image%2020240219184314.png) + +Так как в [[../../../meta/zero/00 PostgreSQL|PostgreSQL]] мы передаем не сам запрос, а блоки данных, то отставание по идее должно быть меньше, чем в [[../../../meta/zero/00 MySQL|MySQL]]. + +Что может приводить к лагу: +- Медленные и сложные запросы: Если реплики выполняют сложные или ресурсоемкие запросы, это может замедлить процесс применения изменений. +- Сетевые проблемы: Задержки в сети могут замедлить передачу журнала транзакций (WAL) от мастера к репликам. +- Размер журнала транзакций: Большие объемы изменений могут создать нагрузку на систему репликации, увеличивая время обработки. +- Проблемы с дисковой подсистемой: Медленные дисковые операции на репликах могут замедлить процесс применения изменений. + +Рекомендации: +- Оптимизация запросов: Оптимизация сложных запросов может снизить нагрузку на реплики и ускорить процесс применения изменений. Это включает в себя индексацию, переработку запросов и использование эффективных алгоритмов. + - Убивайте медленные запросы. Если запрос висит уже 10 секунд, то лучше его прибить. +- Использование выделенных реплик: Для выполнения сложных запросов или резервного копирования можно использовать выделенные реплики, что позволит снизить нагрузку на основные реплики, обеспечивающие актуальность данных. +- Подумайте о кросс-СУБД репликации Репликация из реляционной бд в NoSQL +- Избегайте [[../../database/Write-read pattern|Write-read pattern]] +- Выделить отдельный жесткий диск под [Журнал БД](../../database/Журнал%20БД.md), чтобы обеспечить эксклюзивный доступ к ресурсам диска, тем самым улучшая производительность. Менее актуально для SSD. +- Настройка параметров репликации: Оптимизация параметров репликации, таких как размер WAL и частота его отправки, может помочь уменьшить лаг репликации. В PostgreSQL, например, можно настроить параметры wal_level и max_wal_senders для оптимизации процесса репликации. \ No newline at end of file diff --git a/dev/architecture/highload/Полу-синхронная репликация.md b/dev/architecture/highload/Полу-синхронная репликация.md new file mode 100644 index 00000000..c0e1b7ba --- /dev/null +++ b/dev/architecture/highload/Полу-синхронная репликация.md @@ -0,0 +1,53 @@ +--- +aliases: + - semi-sync +tags: + - maturity/🌱 +date: + - - 2024-06-07 +zero-link: + - "[[../../../meta/zero/00 HighLoad|00 HighLoad]]" +parents: + - "[[Репликация БД]]" +linked: + - "[[Асинхронная репликация]]" + - "[[Синхронная репликация]]" +--- +Полу-синхронная репликация — это компромиссный метод между [[Синхронная репликация|синхронной]] и [[Асинхронная репликация|асинхронной]] репликацией. Он обеспечивает более высокую надежность данных по сравнению с асинхронной репликацией, но при этом снижает время отклика по сравнению с синхронной. + +Комит прошел на одной реплике, но данные по транзакции были скопированы во все остальные реплики, но еще не были применены. + +Реализовано в [MySQL](../../../meta/zero/00%20MySQL.md) + +Схема выполнения на MySQL ![](../../../meta/files/images/Pasted%20image%2020240206195639.png) + +**Как работает** +- Подготовка транзакции в движке БД: Транзакция начинается на master, где собираются все изменения данных. +- Запись транзакции в лог: Все изменения записываются в журнал транзакций. +- Пересылка лога репликам: Журнал транзакций отправляется на реплики. Master ждет подтверждения от как минимум одной реплики о получении журнала, но не обязательно его применении. +- Завершение транзакции в движке БД: После получения подтверждения от одной или нескольких реплик транзакция завершается на master, и клиент получает подтверждение. +- Воспроизведение транзакции на репликах: Реплики применяют полученные изменения к своим копиям данных, но это может произойти с задержкой. + +**Преимущества** +- Баланс между надежностью и производительностью: Полу-синхронная репликация обеспечивает более высокую надежность данных по сравнению с асинхронной репликацией, так как master ждет подтверждения от реплик перед завершением транзакции. Это снижает риск потери данных при сбое. +- Сниженное время отклика: В отличие от синхронной репликации, master не ждет подтверждения от всех реплик, что снижает время отклика и повышает производительность системы. +- Меньшая вероятность отставания данных: Благодаря ожиданию подтверждения от реплик перед завершением транзакции, вероятность отставания данных на репликах уменьшается. + +**Минусы** +- Проблемы с консистентностью данных: Хотя master ждет подтверждения от одной или нескольких реплик, данные на других репликах могут оставаться несогласованными до применения изменений, что может привести к проблемам с консистентностью. [Фантомное чтение](Фантомное%20чтение.md). +- Сложность управления: Полу-синхронная репликация требует более сложной настройки и управления по сравнению с асинхронной репликацией, так как необходимо следить за подтверждениями от реплик и управлять задержками. +- Увеличенное время отклика по сравнению с асинхронной репликацией: Несмотря на снижение времени отклика по сравнению с синхронной репликацией, полу-синхронная репликация все же медленнее асинхронной, так как требует ожидания подтверждений от реплик. +## Примеры использования +Полу-синхронная репликация часто используется в системах, где требуется баланс между надежностью данных и производительностью. Например, в финансовых системах, где важна высокая доступность и консистентность данных, но при этом необходимо обеспечить приемлемое время отклика для клиентов. Полу-синхронная репликация позволяет снизить риск потери данных при сбоях и поддерживать консистентность данных на более высоком уровне, чем асинхронная репликация. +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 HighLoad|00 HighLoad]] +**Родитель**:: [[Репликация БД]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-06-07]] +### Дополнительные материалы +- [[Асинхронная репликация]] +- [[Синхронная репликация]] +### Дочерние заметки + diff --git a/dev/architecture/highload/Репликация master-master.md b/dev/architecture/highload/Репликация master-master.md new file mode 100644 index 00000000..5445b3de --- /dev/null +++ b/dev/architecture/highload/Репликация master-master.md @@ -0,0 +1,55 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-03-10 +zero-link: + - "[[../../../meta/zero/00 HighLoad|00 HighLoad]]" +parents: + - "[[Репликация БД]]" +linked: + - "[[Репликация master-slave]]" +--- +Все реплики являются ведущими (master). Во все реплики можно писать изменения, а они каким-то образом синхронизируются между собой. Ведущие реплики могут также иметь дополнительные реплики в режиме [[Репликация master-slave|репликации master-slave]]. + +![](Pasted%20image%2020240206194251.png) + +**Плюсы**: +- Нет единой точки отказа +- Дает максимальный [High Availability](High%20Availability.md). +- Легкий failover + +**Минусы:** +- Нет консистентности. Могут возникать конфликты при одновременной работе с одним и тем же набором данных на разных репликах. +- Усложнение логики. Встречается редко. +- Все равно не масштабирует запись. Для масштабирования нужно использовать [шардирование](Шардирование%20БД.md). + +**Варианты применения:** +- Географическая распределенность. Репликация между ЦОД-ами в разных странах. Улучшается производительность, так как пользователь из страны работает с ближайшим ЦОД. Вы устойчивы к потере ЦОД и к сетевым проблемам, так как данные есть в других ЦОД-ах. +- Hot-standby реплика (VIP). Второй мастер всегда на готове, на случай если упадет основной. Во время штатной работы второй мастер не используется. +- Offline клиенты. При плохом или вовсе временно отсутвующем интерент соединении для ассинхронного объединения данных. CouchDB является примером такой БД. + +Варианты реализаций: +- Amazon Aurora +- Google Spanner +## Решение конфликтов +- Избегайте конфликтов. Организуйте взаимодействие так, чтобы конфликты не возникали. +- Last write wins. Выигрывает последняя запись. Но обычно сложно определить кто был первым. +- Ранг реплик. Выигрывает запись от старейшей реплки. +- Слияние. Автоматическое объединение конфликтных данных. +- Решение конфликтов на клиенте. +- Conflict-free replicated data types (CRDT). +- Mergeable persistent data structures. + - В этом режиме работает [00 Git](../../../meta/zero/00%20Git.md) +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 HighLoad|00 HighLoad]] +**Родитель**:: [[Репликация БД]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-03-10]] +### Дополнительные материалы +- [[Репликация master-slave]] +### Дочерние заметки + diff --git a/dev/architecture/highload/Репликация master-slave.md b/dev/architecture/highload/Репликация master-slave.md new file mode 100644 index 00000000..afe89ebb --- /dev/null +++ b/dev/architecture/highload/Репликация master-slave.md @@ -0,0 +1,38 @@ +--- +aliases: + - репликации master-slave +tags: + - maturity/🌱 +date: + - - 2024-03-10 +zero-link: + - "[[../../../meta/zero/00 HighLoad|00 HighLoad]]" +parents: + - "[[Репликация БД|Репликация БД]]" +linked: + - "[[Репликация master-master]]" +--- +В такой схеме у нас есть одна ведущая реплика (master) в которую пишутся изменения и несколько ведомых реплик (slave), на которые эти изменения копируются, из них можно только читать. Это наиболее распространенный подход репликации, так как он относительно прост и понятен. + +![](Pasted%20image%2020240206194227.png) + +**Проблемы и недостатки:** +- Мастер обязательно когда-нибудь упадет. И нужно будет как-то выбрать из slaves нового master. +- Как и другие способы репликации не ускоряет операции вставки данных. +- Этот способ никогда не даст 99,9999 [High Availability](High%20Availability.md). + +Управление master-slave: +- MHA (MySQL Master HA) +- MySQL Failover (Oracle) +- Orchestrator +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 HighLoad|00 HighLoad]] +**Родитель**:: [[Репликация БД|Репликация БД]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-03-10]] +### Дополнительные материалы +- [[Репликация master-master|Репликация master-master]] +### Дочерние заметки + diff --git a/dev/architecture/highload/Репликация БД.md b/dev/architecture/highload/Репликация БД.md new file mode 100644 index 00000000..d0c69e85 --- /dev/null +++ b/dev/architecture/highload/Репликация БД.md @@ -0,0 +1,100 @@ +--- +aliases: + - репликация базы данных + - репликацию бд +tags: + - maturity/🌱 +date: + - - 2024-03-10 +zero-link: + - "[[../../../meta/zero/00 HighLoad|00 HighLoad]]" + - "[[../../../meta/zero/00 DevOps|00 DevOps]]" + - "[[../../../meta/zero/00 Базы Данных|00 Базы Данных]]" +parents: + - "[[Репликация|Репликация]]" +linked: +--- +## Тезисы +- Репликация это копирование измененных данных с одного сервера БД на другой. +- Не отменяет первоначального копирования БД. Сначала нужно первый раз скопировать данные, а потом уже запустить репликацию. +- Репликация не является [резервной копией БД](Резервные%20копии%20БД.md). +- Обычно реализуются на базе [[../../database/Журнал БД|журнала БД]]. +- Плюсы: + - Помогает улучшить [High Availability](High%20Availability.md). Помогает при падении. + - Ускоряет чтение данных +- Проблемы: + - Не ускоряет запись в БД + - [Отставание реплики БД](Отставание%20реплики%20БД.md) + - [[Монотонное чтение|Монотонное чтение]] + - Репликация это ресурсозатратно. +- Репликации БД: + - [Репликация в MySQL](../../database/mysql/Репликация%20в%20MySQL.md) + - [Репликация в PostgreSQL](../../database/postgresql/Репликация%20в%20PostgreSQL.md) +*** +Репликация позволяет сделать N копий одной БД. Обычно есть одна ведущая копия, которую называют master, и есть N ведомых реплик, которые называют slaves. + +Репликация не отменяет первоначального копирования БД. Сначала нужно первый раз скопировать данные, а потом уже запустить репликацию. + +**Для чего делают репликацию?** +- [[../../../../../_inbox/High Availability|High Availability]]. Если один сервер выходит из строя, другие реплики продолжают обслуживать запросы, обеспечивая непрерывный доступ к данным. +- **Масштабирование чтения**. Нагрузка на чтение может быть распределена между несколькими репликами, что улучшает производительность системы. +- **Распределение нагрузки**. Сложные аналитические запросы для построения отчетов и асинхронное [резервное копирование БД](Резервные%20копии%20БД.md) могут выполняться на отдельных репликах, не нагружая основной сервер. +- **Географическое распределение**. Реплики могут быть размещены ближе к пользователям в разных регионах, уменьшая задержки доступа к данным. + +**Недостатки репликации:** +- Не позволяет получить увеличение производительности запросов на вставку данных. Для этого нужно использовать [[../../../../../_inbox/Шардирование БД|шардирование]]. +- **Сложность управления**. Управление несколькими репликами требует дополнительных ресурсов и сложной конфигурации. Это включает настройку синхронизации данных, мониторинг состояния реплик и управление конфликтами. +- **Ресурсозатратность**. Поддержание нескольких копий данных требует дополнительных ресурсов, что может значительно увеличить расходы на инфраструктуру. +- **Проблемы консистентности:** В асинхронной репликации данные на разных репликах могут быть несогласованными, что может привести к проблемам с консистентностью. Например, пользователь может получить разные результаты для одного и того же запроса, если реплики не успели синхронизироваться. +## Роль журнала БД в репликации +Прямой способ сделать репликацию - это скопировать [[../../database/Журнал БД|журнал БД]] с master на slave и применить его. PostgreSQL работает именно так используя журнал [WAL](../../database/postgresql/Write-Ahead%20Log.md). Однако, не все так просто. Формат и возможности журнала напрямую зависят от СУБД. + +![](Pasted%20image%2020240531083508.png) +## Классификация репликаций +- **По синхронизации.** Гарантия наличия и доступности. + - [Синхронная репликация](Синхронная%20репликация.md) + - [Асинхронная репликация](Асинхронная%20репликация.md) + - [Полу-синхронная репликация](Полу-синхронная%20репликация.md) +- **По уровню работы** + - Физическая репликация. Работа на уровне хранилища, мы работаем напрямую со страницами памяти + - [Write-Ahead Log](../../database/postgresql/Write-Ahead%20Log.md) в PostgreSQL + - [InnoDB Undo/Redo Log](../../database/mysql/Журналы%20в%20MySQL.md#InnoDB%20Undo/Redo%20Log) в MySQL + - Логическая репликация. Работает с кортежами. Мы храним набор кортежей до и после. + - [Row-based Binary Log](../../database/mysql/Журналы%20в%20MySQL.md#Row-based%20Binary%20Log) в MySQL + - [Statement-based Binary Log](../../database/mysql/Журналы%20в%20MySQL.md#Statement-based%20Binary%20Log) недоразумение, которое работает на уровне запросов. Для такой репликации нужно выполнять запрос на слейве, и если запрос выполнялся 30 минут, то и на слейве он будет выполняться 30 минут. Также присутсвует зависимость в функциях, например функция времени вернет одно значение на мастере и совершенно другое на слейве. +- **По расспространению изменений** + - push. мастер сует, слейву пофиг. Реализуется редко. (Postgres) + - pull. слейв качает, мастеру пофиг. (MySQL) +- **По количеству точек записи** + - [Репликация master-slave](Репликация%20master-slave.md) + - [Репликация master-master](Репликация%20master-master.md) + - [Безмастерная репликация](Безмастерная%20репликация.md) + - [Групповая репликация](Групповая%20репликация.md). Реализовано в MySQL. +## Проблемы +- [Отставание реплики БД](Отставание%20реплики%20БД.md) +- [Монотонное чтение](Монотонное%20чтение.md) +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 HighLoad|00 HighLoad]], [[../../../meta/zero/00 DevOps|00 DevOps]], [[../../../meta/zero/00 Базы Данных|00 Базы Данных]] +**Родитель**:: [[../../../../../source/курсы/otus/Архитектор высоких нагрузок 2019/Репликация|Репликация]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-03-10]] +### Дополнительные материалы +- +### Дочерние заметки + + +- [[Согласованное префиксное чтение]] +- [[Репликация в MySQL]] +- [[Репликация в PostgreSQL]] +- [[Репликация master-slave]] +- [[Репликация master-master]] +- [[Безмастерная репликация]] +- [[Синхронная репликация]] +- [[Асинхронная репликация]] +- [[Полу-синхронная репликация]] +- [[Отставание реплики БД]] +- [[Монотонное чтение]] +- [[Групповая репликация]] + diff --git a/dev/architecture/highload/Репликация.md b/dev/architecture/highload/Репликация.md new file mode 100644 index 00000000..05167ac1 --- /dev/null +++ b/dev/architecture/highload/Репликация.md @@ -0,0 +1,37 @@ +--- +aliases: + - зеркалирование + - репликацию +tags: + - maturity/🌱 +date: + - - 2024-06-05 +zero-link: + - "[[../../../meta/zero/00 HighLoad|00 HighLoad]]" +linked: +--- +Один из видов [горизонтального масштабирования](Горизонтальное%20масштабирование.md), который позволяет создать несколько копий одного узла системы. + +**Плюсы:** +- Помогает при падениях +- Можно размазать нагрузку по узлам + +**Минусы:** +- Всегда ресурсозатратно. + +**Виды репликации:** +- [Репликация БД](Репликация%20БД.md) +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 HighLoad|00 HighLoad]] +**Родитель**:: [[Горизонтальное масштабирование]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-06-05]] +### Дополнительные материалы +- +### Дочерние заметки + + +- [[Репликация БД]] + diff --git a/dev/architecture/highload/Синхронная репликация.md b/dev/architecture/highload/Синхронная репликация.md new file mode 100644 index 00000000..c54d690d --- /dev/null +++ b/dev/architecture/highload/Синхронная репликация.md @@ -0,0 +1,45 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-06-07 +zero-link: + - "[[../../../meta/zero/00 Базы Данных|00 Базы Данных]]" +parents: + - "[[Репликация БД]]" +linked: + - "[[Асинхронная репликация]]" + - "[[Полу-синхронная репликация]]" +--- +При получении запроса от клиента master ожидает, пока все реплики получат новые данные и подтвердят их применение у себя, и только после этого сообщает клиенту, что запрос успешно выполнен. Работает надежно, но медленно. + +Реализовано в [PostgreSQL](../../../meta/zero/00%20PostgreSQL.md). + +**Механизм работы**: +- Подготовка транзакции в движке БД: Транзакция начинается на главном сервере (мастере), где собираются все изменения данных. +- Запись транзакции в лог: Все изменения записываются в журнал транзакций, что обеспечивает возможность восстановления данных в случае сбоя. +- Пересылка лога репликам: Журнал транзакций отправляется на все реплики для синхронного применения изменений. +- Выполнение транзакций на репликах: Реплики применяют полученные изменения к своим копиям данных. +- Завершение транзакции в движке БД: После успешного применения изменений на всех репликах транзакция завершается. +- Возврат результата клиенту: Клиент получает подтверждение о завершении транзакции только после того, как изменения применены на всех репликах. + +**Плюсы:** +- Высокая надежность данных: Данные не теряются даже в случае сбоя одного из серверов, так как изменения применяются на всех репликах одновременно. +- Консистентность данных: Обеспечивается консистентность данных на всех репликах, что исключает возможность получения различных результатов для одного и того же запроса. + +**Минусы:** +- Увеличенное время отклика: Поскольку подтверждение транзакции возвращается клиенту только после её завершения на всех репликах, время отклика увеличивается. Это может негативно сказаться на производительности системы, особенно при большом количестве реплик. +- Высокая вероятность сбоев: С увеличением числа реплик общая вероятность сбоя возрастает, так как транзакция завершается только при успешном выполнении на всех репликах. Если хотя бы одна реплика не отвечает, транзакция не может быть завершена. +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 HighLoad|00 HighLoad]] +**Родитель**:: [[Репликация БД]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-06-07]] +### Дополнительные материалы +- [[Асинхронная репликация|Асинхронная репликация]] +- [[Полу-синхронная репликация|Полу-синхронная репликация]] +### Дочерние заметки + diff --git a/dev/architecture/highload/Согласованное префиксное чтение.md b/dev/architecture/highload/Согласованное префиксное чтение.md new file mode 100644 index 00000000..0b6c26fd --- /dev/null +++ b/dev/architecture/highload/Согласованное префиксное чтение.md @@ -0,0 +1,32 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-06-07 +zero-link: + - "[[../../../meta/zero/00 HighLoad|00 HighLoad]]" +parents: + - "[[Репликация БД]]" +linked: +--- +Ситуация, которая возникает при наличии нескольких master-ов ([[Репликация master-master]] или [[Групповая репликация]]) или при [Шардирование БД](Шардирование%20БД.md). + +У нас есть 2 участника чата и один сторонний наблюдатель. Сначала один пользователь пишет в чат, а следом другой пользователь пишет в чат. Далее наблюдатель читает сообщения из реплики, в которую сначала пришло второе сообщение, а потом только первое. + +![](../../../meta/files/images/Pasted%20image%2020240607212223.png) + +**Возможные решения:** +- Сортировка по какому-то монотонному полю. +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 HighLoad|00 HighLoad]] +**Родитель**:: [[Репликация БД]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-06-07]] +### Дополнительные материалы +- +### Дочерние заметки + + diff --git a/dev/architecture/Кэширование.md b/dev/architecture/Кэширование.md index d660fe57..1529e7ef 100644 --- a/dev/architecture/Кэширование.md +++ b/dev/architecture/Кэширование.md @@ -38,7 +38,7 @@ linked: - Кэширование на стороне сервиса. [Схема](../../meta/files/images/Pasted%20image%2020240617194759.png). - Опережающее. Кладем данные в кэш заранее. [Схема](../../meta/files/images/Pasted%20image%2020240617194938.png). -Чаще всего кэш реализуется на основе хеш-таблиц и использует [принцип локальности](../fundamental/Принцип%20локальности.md). Для работы с хеш-таблицей вам необходим [[highload/Ключ кэширования|ключ кэширования]] и сами данные. По ключу данные кладутся и забираются из таблицы. +Чаще всего кэш реализуется на основе [[../fundamental/structure/Хеш-таблица|хеш-таблиц]] и использует [принцип локальности](../fundamental/Принцип%20локальности.md). Для работы с хеш-таблицей вам необходим [[highload/Ключ кэширования|ключ кэширования]] и сами данные. По ключу данные кладутся и забираются из таблицы. Для хранения результатов кэширования я обычно использую JSON. Использую для этого библиотеку [[../../../../knowledge/dev/java/other/Jackson|Jackson]], но есть один [[../../../../_inbox/Преобразование Json из коллекции в Java объект при помощи Jackson|нюанс при работе с коллекциям]], который стоит учитывать. diff --git a/dev/architecture/Трёхзвенная структура.md b/dev/architecture/Трёхзвенная структура.md index 415147a9..3c83306d 100644 --- a/dev/architecture/Трёхзвенная структура.md +++ b/dev/architecture/Трёхзвенная структура.md @@ -16,7 +16,7 @@ linked: - [Фронтенд](Фронтенд.md). предназначен для быстрой обработки легких данных, как правило, статики. Эти запросы обрабатываются тут и не проходят на массивный, тяжелый бэкенд. Для фронтенда используются такие легковесные сервера, как [nginx](00%20Nginx.md). В разработке подобных серверов огромное внимание уделяется тому, какое количество ресурсов тратится на обработку одного запроса. - [Бэкенд](Бэкенд.md), как правило, это тяжелые приложения, в которых происходят вычисления, зашита бизнес-логика, и обрабатывать статические запросы бэкендом попросту неэффективно. -- Следующий слой – это хранение данных, в простейшем варианте – [база данных](00%20Базы%20Данных.md). +- Следующий слой – это хранение данных, в простейшем варианте – [база данных](../../meta/zero/00%20Базы%20Данных.md). *** ## Мета информация **Область**:: [[../../meta/zero/00 Архитектура ИС|00 Архитектура ИС]] diff --git a/dev/cryptography/MD5.md b/dev/cryptography/MD5.md index 6c2a2b43..80da04b9 100644 --- a/dev/cryptography/MD5.md +++ b/dev/cryptography/MD5.md @@ -8,10 +8,10 @@ zero-link: - "[[../../meta/zero/00 Криптография|00 Криптография]]" - "[[../../meta/zero/00 Снипеты для Java|00 Снипеты для Java]]" parents: - - "[[Криптографическая хеш-функция]]" -linked: + - "[[Хеш-функция]]" +linked: --- -MD5 (Message Digest Algorithm 5) — это [[криптографическая хеш-функция]], которая преобразует входные данные в 128-битное (16-байтное) значение, называемое хешем или дайджестом сообщения. +MD5 (Message Digest Algorithm 5) — это [[Хеш-функция]], которая преобразует входные данные в 128-битное (16-байтное) значение, называемое хешем или дайджестом сообщения. > [!DANGER] @@ -37,7 +37,7 @@ MD5 (Message Digest Algorithm 5) — это [[криптографическая *** ## Мета информация **Область**:: [[../../meta/zero/00 Криптография|00 Криптография]] -**Родитель**:: [[Криптографическая хеш-функция]] +**Родитель**:: [[Хеш-функция]] **Источник**:: **Создана**:: [[2024-09-14]] **Автор**:: diff --git a/dev/cryptography/SHA-256.md b/dev/cryptography/SHA-256.md index 44e6bcea..9738e647 100644 --- a/dev/cryptography/SHA-256.md +++ b/dev/cryptography/SHA-256.md @@ -9,10 +9,10 @@ zero-link: - "[[../../meta/zero/00 Криптография|00 Криптография]]" - "[[../../meta/zero/00 Снипеты для Java|00 Снипеты для Java]]" parents: - - "[[Криптографическая хеш-функция]]" -linked: + - "[[Хеш-функция]]" +linked: --- -SHA-256 (Secure Hash Algorithm 256-bit) — это [[криптографическая хеш-функция]], которая преобразует входные данные в 256-битное (32-байтное) значение, называемое хешем. SHA-256 является частью семейства алгоритмов SHA-2. +SHA-256 (Secure Hash Algorithm 256-bit) — это [[Хеш-функция]], которая преобразует входные данные в 256-битное (32-байтное) значение, называемое хешем. SHA-256 является частью семейства алгоритмов SHA-2. **Основные характеристики SHA-256:** - **Фиксированная длина выхода**: Независимо от размера входных данных (например, файл, текст, строка), выход всегда имеет длину 256 бит (32 байта). @@ -31,7 +31,7 @@ SHA-256 (Secure Hash Algorithm 256-bit) — это [[криптографиче - [[../snippet/Реализация SHA-256 на Java|Реализация SHA-256 на Java]] ## Мета информация **Область**:: [[../../meta/zero/00 Криптография|00 Криптография]], [[../../meta/zero/00 Снипеты для Java|00 Снипеты для Java]] -**Родитель**:: [[Криптографическая хеш-функция]] +**Родитель**:: [[Хеш-функция]] **Источник**:: **Создана**:: [[2024-09-14]] **Автор**:: diff --git a/dev/cryptography/Криптографическая хеш-функция.md b/dev/cryptography/Хеш-функция.md similarity index 100% rename from dev/cryptography/Криптографическая хеш-функция.md rename to dev/cryptography/Хеш-функция.md diff --git a/dev/database/Write-read pattern.md b/dev/database/Write-read pattern.md new file mode 100644 index 00000000..8c5c3081 --- /dev/null +++ b/dev/database/Write-read pattern.md @@ -0,0 +1,37 @@ +--- +aliases: + - запись-чтение +tags: + - maturity/🌱 +date: 2024-09-17 +zero-link: + - "[[../../meta/zero/00 Базы Данных|00 Базы Данных]]" +parents: +linked: +--- +Ситуация, когда после записи данных в master реплику вы пытаетесь немедленно прочитать те же данные с другой реплики. Это может привести к проблемам из-за задержек синхронизации между основным узлом и репликами. + +![](../../meta/files/images/Pasted%20image%2020240607211343.png) + +Основные причины, почему стоит избегать этого паттерна при репликации: + +- [[../architecture/highload/Отставание реплики БД|Задержки репликации]]: Данные, записанные на основном узле, не сразу реплицируются на все реплики. При чтении с реплики можно получить устаревшую информацию. +- Непоследовательность данных: Вы можете получить неконсистентные данные, так как реплика может не успеть синхронизироваться с основным узлом. +- [[Race condition|Условие гонки]]: Возникает ситуация, когда операции записи и чтения конкурируют между собой. Это может привести к тому, что операция чтения прочитает данные до того, как завершится операция записи на всех узлах. + +Чтобы избежать этих проблем, рекомендуется: +- Чтение данных с основного узла, если требуется сразу после записи. +- Использование механизмов согласованности, таких как кворумное чтение и запись, где для подтверждения операции необходимо согласие нескольких узлов. +- Настройка задержек или проверок синхронизации для гарантии, что данные были реплицированы перед чтением. +*** +## Мета информация +**Область**:: [[../../meta/zero/00 Базы Данных|00 Базы Данных]] +**Родитель**:: +**Источник**:: +**Создана**:: [[2024-09-17]] +**Автор**:: +### Дополнительные материалы +- + +### Дочерние заметки + diff --git a/dev/database/mysql/Mixed binlog format.md b/dev/database/mysql/Mixed binlog format.md new file mode 100644 index 00000000..4b9e3f5b --- /dev/null +++ b/dev/database/mysql/Mixed binlog format.md @@ -0,0 +1,39 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-06-02 +zero-link: + - "[[../../../meta/zero/00 MySQL|00 MySQL]]" +parents: + - "[[Репликация в MySQL]]" +linked: + - "[[Row Based Replication (RBR)]]" + - "[[Statement Based Replication (SBR)]]" +--- +Mixed binlog format — это попытка объединить лучшие стороны [[Statement Based Replication (SBR)|SBR]] и [[Row Based Replication (RBR)|RBR]]. В зависимости от ситуации он может работать либо как SBR, либо как RBR. По умолчанию был дефолтным вариантом в MySQL 5.1. + +**Принципы работы** +- [[Statement Based Replication (SBR)|SBR]] используется для простых и детерминированных запросов, таких как UPDATE или INSERT, которые не зависят от текущего состояния данных и могут быть воспроизведены на slave без изменений. +- [[Row Based Replication (RBR)|RBR]] применяется для сложных запросов или запросов, которые могут быть недетерминированными, например, когда используются функции, такие как NOW() или RAND(), или для запросов, которые изменяют большое количество строк. + +**Плюсы**: +- **Гибкость**: Автоматический выбор между SBR и RBR в зависимости от ситуации позволяет использовать преимущества обоих форматов. +- **Оптимизация**: В теории, это позволяет оптимизировать использование ресурсов, выбирая наиболее подходящий метод для каждой транзакции. + +**Минусы** +- **Редкое использование**: Встречается редко, так как не всегда работает корректно и может приводить к неожиданным проблемам с репликацией. +- **Сложность**: Повышенная сложность настройки и диагностики, что может затруднять управление и устранение неполадок. +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 MySQL|00 MySQL]] +**Родитель**:: [[Репликация в MySQL]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-06-02]] +### Дополнительные материалы +- [[Statement Based Replication (SBR)]] +- [[Row Based Replication (RBR)]] +### Дочерние заметки + diff --git a/dev/database/mysql/Row Based Replication (RBR).md b/dev/database/mysql/Row Based Replication (RBR).md new file mode 100644 index 00000000..52cf392b --- /dev/null +++ b/dev/database/mysql/Row Based Replication (RBR).md @@ -0,0 +1,41 @@ +--- +aliases: + - RBR +tags: + - maturity/🌱 +date: + - - 2024-06-02 +zero-link: + - "[[../../../meta/zero/00 MySQL|00 MySQL]]" +parents: + - "[[Репликация в MySQL]]" +linked: + - "[[Statement Based Replication (SBR)]]" +--- +От мастера к слейву отправляются только измененные строки, сам результат изменений. Основан на журнале [Row-based Binary Log](Журналы%20в%20MySQL.md#Row-based%20Binary%20Log). + +RBR имеет три режима работы: +- full: При изменении сохраняются все колонки (до изменения и после), даже если в них не было изменений. Такой режим потребляет много памяти. +- noblob: Работает как full, но не передает изменения BLOB и TEXT колонок. +- minimal: При изменении строки сохраняются только измененные колонки и колонки Primary Keys. + +**Плюсы:** +- Детерминированность: Запрос выполняется на master, а slave получает уже результат. Это устраняет проблемы, связанные с недетерминированными функциями, как в SBR. +- Бинарный формат + +**Минусы:** +- **Бинарный формат**: Прочитать глазами уже не получится. Однако, есть утилита `mysqlbinlog -v`, которая позволяет читать журнал. +- Большое потребление памяти: Потребляет больше памяти, чем SBR, так как нужно сохранять изменения строк до и после. + - в mysql есть binlog_row_image, который решает эту проблему +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 MySQL|00 MySQL]] +**Родитель**:: [[Репликация в MySQL]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-06-02]] +### Дополнительные материалы +- [[Statement Based Replication (SBR)]] +### Дочерние заметки + + diff --git a/dev/database/mysql/Statement Based Replication (SBR).md b/dev/database/mysql/Statement Based Replication (SBR).md new file mode 100644 index 00000000..288d7529 --- /dev/null +++ b/dev/database/mysql/Statement Based Replication (SBR).md @@ -0,0 +1,40 @@ +--- +aliases: + - SBR +tags: + - maturity/🌱 +date: + - - 2024-06-02 +zero-link: + - "[[../../../meta/zero/00 MySQL|00 MySQL]]" +parents: + - "[[Репликация в MySQL]]" +linked: + - "[[Row Based Replication (RBR)]]" +--- +Первое, что приходит в голову, это сохранять в Binary Log непосредственно SQL-запросы: Statement-based Binary Log. На основе этого журнала работает Statement Based Replication (SBR). В этом случае master сохраняет в журнал SQL-запросы, а slave получает этот список запросов и выполняет их у себя. + +В основе данной репликации лежит журнал [Statement-based Binary Log](Журналы%20в%20MySQL.md#Statement-based%20Binary%20Log). + +**Плюсы:** +- Небольшое количество передаваемых данных, при однотипных изменениях. Например, если мы изменяем 5 миллионов строк одним запросом: `UPDATE users SET bonus=bonus+100`, то нужно передать только 1 строку запроса. +- В журнале все записано в понятном человеко-читаемом виде. + +**Проблемы:** +* Недетерминирован. Каждый запрос самостоятельно исполняется на слейве. + * Вызов функций, например функции `now()`. В момент попадания запроса на slave это будет уже другое время. + - [Остальные примеры](https://dev.mysql.com/doc/refman/8.0/en/replication-rbr-safe-unsafe.html): uuid(), fund_rows(), rand(), UDF, триггеры на апдейт, auto_increment +- Долгое выполнение сложных запросов. Если запрос выполнялся 10 минут на master, то на slave он тоже будет выполняться 10 минут. + +Для того чтобы SBR работала корректно, есть специальный флажок. +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 MySQL|00 MySQL]] +**Родитель**:: [[Репликация в MySQL]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-06-02]] +### Дополнительные материалы +- [[Row Based Replication (RBR)|Row Based Replication (RBR)]] +### Дочерние заметки + diff --git a/dev/database/mysql/Архитектура MySQL.md b/dev/database/mysql/Архитектура MySQL.md new file mode 100644 index 00000000..a4cc8c1d --- /dev/null +++ b/dev/database/mysql/Архитектура MySQL.md @@ -0,0 +1,48 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-06-16 +zero-link: + - "[[../garden/ru/meta/zero/00 MySQL|00 MySQL]]" +parents: +linked: +--- +В MysSQL есть логический слой, который занимается общими и изолированными от хранения данных операциями: кэширование, построение плана запроса и так далее. А есть конкретный физический слой, который отвечает за хранение данных. Он использует интерфейс подключения, то есть реализации хранилищ могут быть разными. ^42f122 + +Из-за этого возникают проблемы: +- [[Репликация в MySQL]]. Вынуждены писать несколько журналов, на логическом и физическом уровне +- Индексы. Реализация одного и того же индекса может отличаться в разных хранилищах +- Оптимизатор слабо связан с хранилищем, из-за этого он не может использовать какие-то особенности движка для улучшения производительности. + +![](../../../meta/files/images/Pasted%20image%2020240613195204.png) + +Клиенты, которые обращаются к серверу через функции соответствующего коннектора или C API по протоколу TCP/IP либо UNIX Socket. + +Логический слой, общий для всех движков: +- В управлении подключением происходит авторизация. Каждый клиент работает в своем независимом потоке. Каждый поток может кэшироваться сервером. +- Кэш запросов. Представлен одним общим потоком для всех клиентов. Может оказаться узким местом. +- Парсер проверяет синтаксис запроса, запрашивает у хранилищ наличие данных таблиц и полей, права доступа непосредственно к этим полям и проверяет наличие ответа в кэше запросов, после чего передает распарсенный запрос оптимизатору; +- Оптимизатор запрашивает в интерфейсе хранилищ статистику по индексам, на основании которой он строит план запроса, который передает исполнителю; +- Исполнитель. Обращается за данными в хранилище согласно плану запроса. Обновляет значения в кэше запросов. +## Оптимизатор +Выбирает самый производительный план. + +План запроса, который делает оптимизатор, это не какой-то исполняемый код, а набор инструкций, который передается исполнителю. Это некое предположение о том, как запрос будет выполняться. В отличие от PostrgreSQL, мы не можем посмотреть как фактически был выполнен запрос. Данные от 2015 года, может что-то изменилось. ^432879 + +Какие проблемы: +- Из-за архитектуры MySQL + - использует мало статистики по запросам. + - не учитывает особенности хранилищ, нагрузку, буфферы соединений и кэши + +Как влиять на оптимизатор? +- Переписать запрос. +- Использовать [[../../../../../_inbox/Индексы в MySQL|индексы]] +- user/force/ignore index. Можем явно указать когда и какие индексы использовать +- straight_join. Можем задать жесткий порядок join таблиц +- @@optimizer_switch. Позволяет включать/отключать правила, которые использует оптимизатор. +- optimizer_prune_level и optimizer_search_depth. Верхняя граница количества вариантов и времени выполнения, которые рассмотрит оптимизатор. + +## Заметки +- mariadb - форк Mysql, который пытается исправить архитектурные ошибки MySQL \ No newline at end of file diff --git a/dev/database/mysql/Журналы в MySQL.md b/dev/database/mysql/Журналы в MySQL.md new file mode 100644 index 00000000..fe0e0124 --- /dev/null +++ b/dev/database/mysql/Журналы в MySQL.md @@ -0,0 +1,65 @@ +--- +aliases: + - InnoDB +tags: + - maturity/🌱 +date: + - - 2024-05-28 +zero-link: + - "[[../../../meta/zero/00 MySQL|00 MySQL]]" +parents: + - "[[../garden/ru/dev/database/mysql/Архитектура MySQL|Архитектура MySQL]]" +linked: + - "[[Репликация в MySQL]]" +--- +Изначально в MySQL не было никаких журналов. Был движок MyISAM, а в нем журнала нет. + +![](Pasted%20image%2020240528082025.png) +На рисунке вы можете видеть штуку, которая называется Storage Engines: это такая сущность, которая занимается вопросами, как писать данные на диск и как нам их оттуда читать, как по ним искать и пр. + +Потом прикрутили репликацию. Репликация – это одна строчка в самом левом верхнем квадратике – Management Services&Utilites. Для репликации потребовался журнал. Его начали писать. Он называется Binary Log. Никто не думал про то, чтобы его использовать как-то иначе, просто сделали. + +Примерно в это же время MySQL подарили новый Storage Engine, который называется InnoDB. Это широко используемая штука, и в InnoDB свой журнал. Получилось два журнала – InnoDB и Binary Log. Этот момент стал точкой невозврата, после чего появились проблемы, которые решить очень тяжело. + +Binary Log не используется для [Point In Time Recovery](Point%20In%20Time%20Recovery%20(PITR).md), а InnoDB Undo/Redo Log не используется в репликации. Получилось, что у PostgreSQL журнал один, а у MySQL их, как бы, два. +## InnoDB Undo/Redo Log +## Binary Log +У Binary Log, который нужен для репликации, есть два или три формата (типа). +### Statement-based Binary Log +Самый первый тип, который появился, который было проще всего сделать, это Statement-based Binary Log. Что это такое? Это просто файл, в который последовательно пишутся транзакция за транзакцией. Это выглядит примерно так: + +![](Pasted%20image%2020240528082432.png) + +В транзакции указывается БД, на которой совершаются эти обновления, указывается timestamp времени начала транзакции, и дальше идет сама транзакция. +### Row-based Binary Log +Второй тип называется Row-based репликация. Это журнал, в который пишутся не сами запросы, а те строчки, которые они меняют. Он состоит из двух частей – BEFORE image и AFTER image: + +![](Pasted%20image%2020240528082516.png) +На картинке BEFORE image сверху, а AFTER image – внизу. + +В BEFORE image помещаются те строчки, которые были до выполнения транзакции. Красным цветом помечены строчки, которые удаляются: + +![](Pasted%20image%2020240528082538.png) + +Они из BEFORE image наверху, но их нет внизу – в AFTER image, значит, они удаляются. + +На следующей картинке зеленым помечены строчки, которые добавились: + +![](Pasted%20image%2020240528082552.png) + +Синие UPDATE'ы есть и в BEFORE image, и в AFTER image. Это обновления. + +Проблема такого решения связана с тем, что до недавнего времени в Row-based репликации писались в log все колонки, даже если мы обновили одну. В MySQL 5.6 это починили, и с этим должно стать полегче. +### Mixed-based +Он работает либо как Statement-based, либо как Row-based, но он широко не распространен. +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 MySQL|00 MySQL]] +**Родитель**:: [[Архитектура MySQL]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-05-28]] +### Дополнительные материалы +- [[Репликация в MySQL]] +### Дочерние заметки + diff --git a/dev/database/mysql/Репликация в MySQL.md b/dev/database/mysql/Репликация в MySQL.md new file mode 100644 index 00000000..1e0c3df8 --- /dev/null +++ b/dev/database/mysql/Репликация в MySQL.md @@ -0,0 +1,127 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-05-28 +zero-link: + - "[[../../../meta/zero/00 MySQL|00 MySQL]]" +parents: + - "[[../../architecture/highload/Репликация БД|Репликация БД]]" +linked: + - "[[Журналы в MySQL]]" +link: +--- +## Тезисы +- На slave можно реализовать другую схему БД, построить другие индексы. +- Можно использовать [libslave](libslave.md), чтобы "притвориться" репликой. +- Мастер многопоточен, а слейв - нет. Вроде исправлено в новых версиях SQL. + - В 5.6 версии можно реплицировать параллельно несколько БД + - В 5.7 версии можно реплицировать параллельно одни и те же таблицы +- Обязательно убедиться, что работают GUID идентификация транзакций. +- **Репликация сильно зависит от версии MySql** + - Всегда логическая репликация, модель master-slave, pull распространение + - 4.1 = асинхронная, SBR, logposs + - 5.1 = +RBR, +mixed. Дефолт mixed + - 5.6 = +semisync, +mtslave (per-db), +slavedelay, +GTID + - 5.7 = + mtslave, +master-master (plugin), +default-RBR (image=full?!), groupcommit +## Схема работы репликации +![Архитектура MySQL](Архитектура%20MySQL.md#^42f122) + +Физический слой хранилища должен писать журнал для работы транзакций (Write-Ahead Log). По идее, его можно было бы использовать для репликации, как в PostgreSQL, но логический слой ничего не знает про физический и не может использовать тот же журнал. Поэтому при включении репликации на логическом уровне master начинает вести свой журнал, называемый Binary Log. + +Механизм работы следующий: +- **Запись изменений в бинарный лог**: Все изменения данных записываются в бинарный лог (Binary Log) на мастере. Бинарный лог хранит последовательность всех транзакций, которые изменяют данные. +- **Передача бинарного лога на реплики**: Мастер передает бинарный лог на реплики. Для этого используются потоки binlog dump на мастере и I/O потоки на репликах. В отличие от PostgreSQL, используется pull модель распространения, то есть реплики сами забирают изменения с master. +- **Применение изменений на репликах**: Реплики считывают бинарный лог и применяют изменения к своим копиям данных, поддерживая синхронизацию с мастером. + +![](../../../meta/files/images/Pasted%20image%2020240712083105.png) + +Binary Log в MySQL может записывать данные в разных форматах, в зависимости от настроек журнала. Рассмотрим основные из них: +- [Statement Based Replication (SBR)](Statement%20Based%20Replication%20(SBR).md) +- [Row Based Replication (RBR)](Row%20Based%20Replication%20(RBR).md) +- [Mixed binlog format](Mixed%20binlog%20format.md) + +**Процесс записи данных операции в MySQL** +- INSERT INTO test VALUES (123, 'hello') +- Записываем в таблицу на мастере mysqld +- Записываем в binary log на мастере +- Записываем в relay log на слейве +- таблица на слейве mysqld + +Рабочие потоки ([MySQL Replication Threads](https://dev.mysql.com/doc/refman/8.0/en/replication-threads.html)): +- binlog dump thread. Сохраняет лог транзакций на master +- slave I/O thread. Спуливает изменения на slave с master +- slave SQL thread. Применяет изменения на slave + +MySQL не решает из коробки проблемы кластеризации. Из коробки нет переключений со slave на master если мастер сдох, распределения нагрузки и так далее. Можно решить дополнительным софтом: +- MHA (MySQL Master HA) +- MySQL Failover (Oracle) +- Orchestrator +## Фильтрация репликации +Можно реплицировать данные частично, но это стоит использовать осторожно. Например, это не работает с [Групповая репликация](../../architecture/highload/Групповая%20репликация.md) + +Опции: +- replicate_do_db +- replicate_ignore_db +- replicate_do_table + +[MySQL - CHANGE REPLICATION FILTER Statement](https://dev.mysql.com/doc/refman/8.0/en/change-replication-filter.html) + +![](../../../meta/files/images/Pasted%20image%2020240605091913.png) + + +*** + +- В InnoDB, заметьте, т.е. у нас архитектура разделяет репликацию выше, а storage engine ниже. Но storage engine, для того, чтобы репликация работала, должен, грубо говоря, замедлять insert'ы в таблицу. +- Другая проблема состоит в том, что мастер выполняет запросы параллельно, т.е. одновременно, а слэйв их может применять последовательно. Возникает вопрос – а почему слэйв не может применять их параллельно? На самом деле, с этим все непросто. Есть теорема о сериализации транзакций, которая рассказывает, когда мы можем выполнять запросы параллельно, а когда последовательно. Это отдельная сложная тема, разберитесь в ней, если вам интересно и нужно, например, почитав по ссылке – [http://plumqqz.livejournal.com/387380.html](http://plumqqz.livejournal.com/387380.html). +- В MySQL репликация упирается в процессор. Это прекрасная картинка – большой, мощный сервер, 12 ядер. Работает одно ядро, заодно занято репликацией. Из-за этого реплика задыхается. Это очень грустно. + +Для того чтобы выполнять запросы параллельно существует группировка запросов. В InnoDB есть специальная опция, которая управляет тем, как именно мы группируем транзакции, как именно мы их пишем на диск. Проблема в том, что мы можем их сгруппировать на уровне InnoDB, а уровнем выше – на уровне репликации – этой функциональности не было. В 2010 г. Кристиан Нельсен из MariaDB реализовал такую фичу, которая называется Group Binary Log Commit. Получается, мы журнал повторяем на двух уровнях – Storage Engine и репликация, и нам нужно таскать фичи из одного уровня на другой. Это сложный механизм. Более того, нам нужно одновременно консистентно писать сразу в два журнала – two-phase-commit. Это еще хуже. + +На следующей картинке мы видим два графика: +![](../../../meta/files/images/Pasted%20image%2020240528090119.png) +Синий график демонстрирует то, как масштабируется InnoDB, когда мы ему добавляем треды. Накидываем треды – число транзакций, которые он обрабатывает, возрастает. Красная линия показывает ситуацию, когда включена репликация. Мы включаем репликацию и теряем масштабируемость. Потому что лог в Binary Log пишется синхронно, и Group Binary Log Commit это решает. + +Грустно, что приходится так делать из-за разделения – Storage Engine внизу, репликация наверху. С этим все плохо. В MySQL 5.6 и 5.7 эта проблема решена – есть Group Binary Log Commit, и мастер теперь не отстает. Теперь это пытаются использовать для параллелизма репликации, чтобы на слэйве запросы из одной группы запустить параллельно. Тут я написал, что из этого нужно крутить: + +![](../../../meta/files/images/Pasted%20image%2020240528090205.png) + +## Параллельная репликация +Сценарий ([Estimating potential for MySQL 5.7 parallel replication](https://www.percona.com/blog/estimating-potential-for-mysql-5-7-parallel-replication/)): +- 1 мастер, 3 слейва +- первый реплицирует в 1 поток +- второй в 20 потоков +- третий в 100 потоков +- вставка в 25 различных таблиц внутри одной базы в 100 потоков + +![](../../../meta/files/images/Pasted%20image%2020240606094633.png) + +Полезные опции: +- sysvar_replica_parallel_workers - количество потоков +- sysvar_replica_parallel_type + - DATABASE - транзакции применяются параллельно, если они обновляют разные БД + - LOGICAL_CLOCK - транзакции применяются параллельно на реплике на основе timestamp +## Отставание реплики +- [Отставание реплики БД](../../architecture/highload/Отставание%20реплики%20БД.md) + +Диагностировать причину отставания реплики тяжело. Есть средство диагностики в MySQL, называется log медленных запросов. Вы можете его открыть, найти топ самых тяжелых запросов и исправить их. Но с репликацией это не работает. Нужно проводить статистический анализ – считать статистику – какие таблицы стали чаще использоваться. Вручную это сделать очень тяжело. + +В MySQL 5.6 / 5.7 появилась SLAVE PERFORMANCE SCHEMA, на базе которой такую диагностику провести проще. Мы обычно открываем лог коммитов в puppet и смотрим, что же мы выкатили в то время, когда репликация начала отставать. Иногда даже это не помогает, приходится ходить по всем разработчикам и спрашивать, что они сделали, они ли сломали репликацию. Это грустно, но с этим приходится жить. +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 MySQL|00 MySQL]] +**Родитель**:: [[../../architecture/highload/Репликация БД|Репликация БД]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-05-28]] +### Дополнительные материалы +- [Как устроена MySQL-репликация / Андрей Аксенов (Sphinx) - YouTube](https://www.youtube.com/watch?v=lHFaZkJk2O0) +- [Асинхронная репликация без цензуры / HighLoad](https://highload.guide/blog/asynchronous-replication.html) +### Дочерние заметки + + +- [[Row Based Replication (RBR)]] +- [[Statement Based Replication (SBR)]] +- [[Mixed binlog format]] + diff --git a/dev/database/postgresql/Write-Ahead Log.md b/dev/database/postgresql/Write-Ahead Log.md new file mode 100644 index 00000000..88a83705 --- /dev/null +++ b/dev/database/postgresql/Write-Ahead Log.md @@ -0,0 +1,31 @@ +--- +aliases: + - WAL + - Журнал в PostgreSQL +tags: + - maturity/🌱 +date: + - - 2024-05-26 +zero-link: + - "[[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]]" +parents: + - "[[../Журнал БД|Журнал БД]]" +linked: + - "[[Репликация в PostgreSQL]]" +--- +В журнал попадают физические изменения, т.е. обновления страничек. Есть [[../../fundamental/Страница|страница]] в памяти, на ней лежат какие-то данные, мы с ней что-то сделали – вот эту разницу мы записываем в журнал. + +В WAL попадает всё: обновление таблиц, создание триггеров, создание хранимых процедур и так далее. + +![](Pasted%20image%2020240531083602.png) +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]] +**Родитель**:: [[../Журнал БД|Журнал БД]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-05-26]] +### Дополнительные материалы +- [[Репликация в PostgreSQL]] +### Дочерние заметки + diff --git a/dev/database/postgresql/Настройка репликации в PostgreSQL.md b/dev/database/postgresql/Настройка репликации в PostgreSQL.md new file mode 100644 index 00000000..ae129b68 --- /dev/null +++ b/dev/database/postgresql/Настройка репликации в PostgreSQL.md @@ -0,0 +1,386 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-06-17 +zero-link: + - "[[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]]" +parents: + - "[[Репликация в PostgreSQL|Репликация в PostgreSQL]]" +linked: +--- +## Физическая репликация +Создаем сеть, запоминаем адрес +```shell +docker network create pgnet +docker network inspect pgnet | grep Subnet # Запомнить маску сети +``` + +Поднимаем мастер +```shell +docker run -dit -v "$PWD/volumes/pgmaster/:/var/lib/postgresql/data" -e POSTGRES_PASSWORD=pass -p "5432:5432" --restart=unless-stopped --network=pgnet --name=pgmaster postgres +``` + +Меняем postgresql.conf на мастере +```conf +ssl = off +wal_level = replica +max_wal_senders = 4 # expected slave num +``` + +Подключаемся к мастеру и создаем пользователя для репликации +```shell +docker exec -it pgmaster su - postgres -c psql +create role replicator with login replication password 'pass'; +exit +``` + +Добавляем запись в `pgmaster/pg_hba.conf` с `subnet` с первого шага +``` +host replication replicator __SUBNET__ md5 +``` + +Перезапустим мастер +```shell +docker restart pgmaster +``` + +Сделаем бэкап для реплик +```shell +docker exec -it pgmaster bash +mkdir /pgslave +pg_basebackup -h pgmaster -D /pgslave -U replicator -v -P --wal-method=stream +exit +``` + +Копируем директорию себе +```shell +docker cp pgmaster:/pgslave volumes/pgslave/ +``` + +Создадим файл, чтобы реплика узнала, что она реплика +```shell +touch volumes/pgslave/standby.signal +``` + +Меняем `postgresql.conf` на реплике `pgslave` +```conf +primary_conninfo = 'host=pgmaster port=5432 user=replicator password=pass application_name=pgslave' +``` + +Запускаем реплику `pgslave` +```shell +docker run -dit -v "$PWD/volumes/pgslave/:/var/lib/postgresql/data" -e POSTGRES_PASSWORD=pass -p "15432:5432" --network=pgnet --restart=unless-stopped --name=pgslave postgres +``` + +Запустим вторую реплику `pgasyncslave` + +Скопируем бэкап +```shell +docker cp pgmaster:/pgslave volumes/pgasyncslave/ +``` + +Изменим настройки `pgasyncslave/postgresql.conf` +```conf +primary_conninfo = 'host=pgmaster port=5432 user=replicator password=pass application_name=pgasyncslave' +``` + +Дадим знать что это реплика +```shell +touch volumes/pgasyncslave/standby.signal + ``` + +Запустим реплику `pgasyncslave` +```shell +docker run -dit -v "$PWD/volumes/pgasyncslave/:/var/lib/postgresql/data" -e POSTGRES_PASSWORD=pass -p "25432:5432" --network=pgnet --restart=unless-stopped --name=pgasyncslave postgres + ``` + +Убеждаемся что обе реплики работают в асинхронном режиме на `pgmaster` +```shell +docker exec -it pgmaster su - postgres -c psql +select application_name, sync_state from pg_stat_replication; +exit; + ``` + +Включаем синхронную репликацию на `pgmaster` + +Меняем файл `pgmaster/postgresql.conf` +```conf +synchronous_commit = on +synchronous_standby_names = 'FIRST 1 (pgslave, pgasyncslave)' +``` + +Перечитываем конфиг +```shell +docker exec -it pgmaster su - postgres -c psql +select pg_reload_conf(); +exit; +``` + +Убеждаемся, что реплика стала синхронной +```shell +docker exec -it pgmaster su - postgres -c psql +select application_name, sync_state from pg_stat_replication; +exit; +``` + +Создадим тестовую таблицу на `pgmaster` и проверим репликацию +```shell +docker exec -it pgmaster su - postgres -c psql +create table test(id bigint primary key not null); +insert into test(id) values(1); +select * from test; +exit; +``` + +Проверим наличие данных на `pgslave` +```shell +docker exec -it pgslave su - postgres -c psql +select * from test; +exit; +``` + +Проверим наличие данных на `pgasyncslave` +```shell +docker exec -it pgasyncslave su - postgres -c psql +select * from test; +exit; +``` + +Попробуем сделать `insert` на `pgslave` +```shell +docker exec -it pgslave su - postgres -c psql +insert into test(id) values(2); +exit; + ``` + +Укладываем репилку `pgasyncslave` и проверяем работу `pgmaster` и `pgslave` +```shell +docker stop pgasyncslave +docker exec -it pgmaster su - postgres -c psql +select application_name, sync_state from pg_stat_replication; +insert into test(id) values(2); +select * from test; +exit; +docker exec -it pgslave su - postgres -c psql +select * from test; +exit; + ``` + +Укладываем репилку `pgslave` и проверяем работу `pgmaster`, а потом возвращаем реплику `pgslave` + +terminal 1 +```shell +docker stop pgslave +docker exec -it pgmaster su - postgres -c psql +select application_name, sync_state from pg_stat_replication; +insert into test(id) values(3); +exit; +``` + +terminal 2 +```shell +docker start pgslave +``` + +Возвращаем вторую реплику `pgasyncslave` +```shell +docker start pgasyncslave +``` + +Убиваем мастер `pgmaster` +```shell +docker stop pgmaster +``` + +Запромоутим реплику `pgslave` +```shell +docker exec -it pgslave su - postgres -c psql +select pg_promote(); +exit; +``` + +Пробуем записать в новый мастер `pgslave` +```shell +docker exec -it pgslave su - postgres -c psql +insert into test(id) values(4); +exit; +``` + +Настраиваем репликацию на `pgslave` (`pgslave/postgresql.conf`) + +изменяем конфиг +```conf +synchronous_commit = on +synchronous_standby_names = 'ANY 1 (pgmaster, pgasyncslave)' +``` + +перечитываем конфиг +```shell +docker exec -it pgslave su - postgres -c psql +select pg_reload_conf(); +exit; +``` + +Подключим вторую реплику `pgasyncslave` к новому мастеру `pgslave` + +изменяем конфиг `pgasyncslave/postgresql.conf` +```conf +primary_conninfo = 'host=pgslave port=5432 user=replicator password=pass application_name=pgasyncslave' +``` + +перечитываем конфиг +```shell +docker exec -it pgasyncslave su - postgres -c psql +select pg_reload_conf(); +exit; +``` + +Проверяем что к новому мастеру `pgslave` подключена реплика и она работает +```shell +docker exec -it pgslave su - postgres -c psql +select application_name, sync_state from pg_stat_replication; +insert into test(id) values (5) +select * from test; +exit; +docker exec -it pgasyncslave su - postgres -c psql +select * from test; +exit; +``` + +Восстановим старый мастер `pgmaster` как реплику + +Помечаем как реплику +```shell +touch volumes/pgmaster/standby.signal +``` + +Изменяем конфиг `pgmaster/postgresql.conf` +```conf +primary_conninfo = 'host=pgslave port=5432 user=replicator password=pass application_name=pgmaster' +``` + +Запустим `pgmaster` +```shell +docker start pgmaster +``` + +Убедимся что `pgmaster` подключился как реплика к `pgslave` +```shell +docker exec -it pgslave su - postgres -c psql +select application_name, sync_state from pg_stat_replication; +exit; +``` + +## Логическая репликация +Меняем `wal_level` для текущего мастера `pgslave` + +Изменяем настройки `pgslave/postgresql.conf` +```conf +wal_level = logical +``` + +Перезапускаем `pgslave` +```shell +docker restart pgslave +``` + +Создадим публикацию в `pgslave` +```shell +docker exec -it pgslave su - postgres -c psql +GRANT CONNECT ON DATABASE postgres TO replicator; +GRANT SELECT ON ALL TABLES IN SCHEMA public TO replicator; +create publication pg_pub for table test; +exit; +``` + +Создадим новый сервер `pgstandalone` для логической репликации +```shell +docker run -dit -v "$PWD/volumes/pgstandalone/:/var/lib/postgresql/data" -e POSTGRES_PASSWORD=pass -p "35432:5432" --restart=unless-stopped --network=pgnet --name=pgstandalone postgres +``` + +Копируем файлы c `pgslave` в `pgstandalone` и восстанавливаем +```shell +docker exec -it pgslave su - postgres +pg_dumpall -U postgres -r -h pgslave -f /var/lib/postgresql/roles.dmp +pg_dump -U postgres -Fc -h pgslave -f /var/lib/postgresql/schema.dmp -s postgres +exit; + +docker cp pgslave:/var/lib/postgresql/roles.dmp . +docker cp roles.dmp pgstandalone:/var/lib/postgresql/roles.dmp +docker cp pgslave:/var/lib/postgresql/schema.dmp . +docker cp schema.dmp pgstandalone:/var/lib/postgresql/schema.dmp + +docker exec -it pgstandalone su - postgres +psql -f roles.dmp +pg_restore -d postgres -C schema.dmp +exit +``` + +Создаем подписку на `pgstandalone` +```shell +docker exec -it pgstandalone su - postgres -c psql +CREATE SUBSCRIPTION pg_sub CONNECTION 'host=pgslave port=5432 user=replicator password=pass dbname=postgres' PUBLICATION pg_pub; +exit; +``` + +Убеждаемся что репликация запущена +```shell +docker exec -it pgstandalone su - postgres -c psql +select * from test; +exit; +``` + +Сделаем конфликт в данных + +Вставляем данные в подписчике `pgstandalone` +```shell +docker exec -it pgstandalone su - postgres -c psql +insert into test values(9); +exit; +``` + +Вставляем данные в паблишере `pgslave` +```shell +docker exec -it pgslave su - postgres -c psql +insert into test values(9); +insert into test values(10); +exit; +``` + +Убеждаемся что записи с id 10 не появилось на `pgstandalone` +```shell +docker exec -it pgstandalone su - postgres -c psql +select * from test; +exit; +``` + +Посмотрим в логи `pgstandalone` и убедимся что у нас произошел разрыв репликации +```shell +docker logs pgstandalone + +2023-03-27 16:15:02.753 UTC [258] ERROR: duplicate key value violates unique constraint "test_pkey" +2023-03-27 16:15:02.753 UTC [258] DETAIL: Key (id)=(9) already exists. +2023-03-28 18:30:42.893 UTC [108] CONTEXT: processing remote data for replication origin "pg_16395" during message type "INSERT" for replication target relation "public.test" in transaction 739, finished at 0/3026450 +``` + +Исправляем конфликт +```shell +docker exec -it pgstandalone su - postgres -c psql +SELECT pg_replication_origin_advance('pg_16395', '0/3026451'::pg_lsn); # message from log + 1 +ALTER SUBSCRIPTION pg_sub ENABLE; +select * from test; +exit; +``` +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]] +**Родитель**:: [[Репликация в PostgreSQL|Репликация в PostgreSQL]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-06-17]] +### Дополнительные материалы +- +### Дочерние заметки + diff --git a/dev/database/postgresql/Репликация в PostgreSQL.md b/dev/database/postgresql/Репликация в PostgreSQL.md new file mode 100644 index 00000000..0bd70aa1 --- /dev/null +++ b/dev/database/postgresql/Репликация в PostgreSQL.md @@ -0,0 +1,70 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-05-28 +zero-link: + - "[[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]]" +parents: + - "[[../../architecture/highload/Репликация БД|Репликация БД]]" +linked: +--- +## Тезисы +- Реализуется на базе журнала [WAL](Write-Ahead%20Log.md). +- Репликация упирается в диск, а не в процессор. +- Реплика это точная бинарная копия мастера. +- Работает по push модели +- При физической репликации фильтрация не возможна +*** +Распространение изменений в PostgreSQL происходит по push модели. То есть, master отправляет [[Write-Ahead Log|WAL]] на реплики, а реплика применяет данные физически, согласно записям в WAL. Таким образом, если остановить запись в master, дождаться синхронизации реплик и сделать бинарное сравнение master и slaves, они будут идентичны. + +![](../../../meta/files/images/Pasted%20image%2020240606094952.png) + +Производительность репликации в PostgreSQL обычно ограничена производительностью дисков, а не процессора. Поэтому при использовании HDD рекомендуется выделять отдельный диск для WAL. + +Добавление реплики требует остановки работы приложения, чтобы никакие записи не менялись в БД. Хотя, если данные пишутся не так часто, то новая реплика может просто догнать отставание в мастер, которое образуется за время подключения слейва. + + +## Синхронизация +Async: +- synchronus_commit = + - off - не будет дожидаться даже локального подтверждения, нет гарантии что данные дошли до бд + - local - происходит локальный коммит и в этот же момент отправляется подтверждение + +Sync/Semi-symc: +- synchronus_commit = remote_write \/ on \/ remote_apply + - remote_write - транзакция подтверждается только если получено подтверждение со всех реплик +- synchronus_standby_names = \[FIRST \/ ANY\] N (replicas_list) + - позволяет настроить от скольких реплик ожидается ответ +## Логическая репликация +Логическая репликация позволяет более гибко управлять копированием данных. Она предоставляет возможность реплицировать отдельные таблицы или схемы, а не всю базу данных целиком. Это особенно полезно для частичного копирования данных и интеграции с другими системами. + +Logical Log Streaming Replication – это способ трансформировать Write-Ahead Log. Например, мы не хотим реплицировать все таблицы из данной базы, а хотим реплицировать только часть. Logical Log Streaming Replication позволяет мастеру объяснить, что из таблиц будет уезжать на слэйв. + +Logical Decoding – способ визуализировать то, что находится в PostgreSQL Write-Ahead Log. На самом деле, если мы можем напечатать в каком-то виде то, что у нас происходит на слэйве, точнее, что нам пришло через Write-Ahead Log, это значит, что мы можем программно реализовать все то, что делает libslave. Получили insert, update, delete, у нас “дернулся” нужный callback, мы узнали про изменения. Это и есть Logical Decoding. + +![](Pasted%20image%2020240606100439.png) + +**Конфликты:** +- Нужно идентифицировать запись для update/delete (по первичному ключу/по уникальному ненуллабельному индексу/по всем столбцам). +- В случае возникновения конфликта требуется вручную исправить данные. +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]] +**Родитель**:: [[../../architecture/highload/Репликация БД|Репликация БД]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-05-28]] +### Дополнительные материалы +- [[Настройка репликации в PostgreSQL]] +- [BDR User Guide - PostgreSQL wiki](https://wiki.postgresql.org/wiki/Logical_Log_Streaming_Replication) +- [PostgreSQL: Documentation: 16: Chapter 31. Logical Replication](https://www.postgresql.org/docs/current/logical-replication.html) +- [PostgreSQL: Documentation: 9.4: Logical Decoding](https://www.postgresql.org/docs/9.4/logicaldecoding.html). Аналог [libslave](libslave.md) в MySQL +- [Отладка и устранение проблем в PostgreSQL Streaming Replication / Хабр](https://m.habr.com/ru/company/oleg-bunin/blog/414111/) +- [An Overview of Logical Replication in PostgreSQL | Severalnines](https://severalnines.com/blog/overview-logical-replication-postgresql/) +### Дочерние заметки + + +- [[Настройка репликации в PostgreSQL]] + diff --git a/dev/database/Журнал БД.md b/dev/database/Журнал БД.md new file mode 100644 index 00000000..f57ea1e2 --- /dev/null +++ b/dev/database/Журнал БД.md @@ -0,0 +1,49 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-05-26 +zero-link: + - "[[00 Базы Данных]]" +parents: +linked: +--- +Основная цель журнала — фиксировать все изменения, происходящие в базе данных, до их окончательного применения. Это позволяет выполнять [[../../../../_inbox/Транзакция БД|транзакции]] и [[../architecture/highload/Репликация БД|репликацию бд]]. + +Перед тем как выполнить SQL-запрос, база данных записывает в журнал все действия, которые собирается сделать. После того как журнал зафиксировался на диске, база данных изменяет сами данные в памяти. И только через какое-то время эти данные окажутся на диске в хранилище. Этот алгоритм называется [PITR](Point%20In%20Time%20Recovery%20(PITR).md) + +![](Pasted%20image%2020240528081137.png) +Этот процесс обеспечивает два важных аспекта: +- **Надежность**: В случае сбоя системы, данные можно восстановить из журнала до последнего зафиксированного состояния. +- **Консистентность**: Все транзакции, записанные в журнал, будут применены в базе данных в правильном порядке, что предотвращает потерю данных и сохраняет целостность системы. + +> [!INFO] +> Журналы базы данных часто имеют циклическую структуру, где новые данные записываются поверх старых, когда журнал заполняется. Это позволяет эффективно использовать дисковое пространство и упрощает управление журналом. + +Реализации в СуБД: +- [[postgresql/Write-Ahead Log|Журнал в PostgreSQL]] +- [Журналы в MySQL](mysql/Журналы%20в%20MySQL.md) + +Главные вопросы, которые встают перед разработчиком любой БД: +- Как организовать журнал? +- Как его писать? +- Как писать его меньше? +- Как сделать так, чтобы это работало быстрее? +- При чем тут репликация? + +Для улучшения производительности желательно под журналы выделять отдельные жесткие диски. Чтобы у журнала был эксклюзивный доступ к ресурсам диска. Менее актуально для SSD. +*** +## Мета информация +**Область**:: [[../../meta/zero/00 Базы Данных|00 Базы Данных]] +**Родитель**:: +**Источник**:: +**Автор**:: +**Создана**:: [[2024-05-26]] +### Дополнительные материалы +- +### Дочерние заметки + + +- [[Write-Ahead Log]] + diff --git a/dev/fundamental/Copy-on-write.md b/dev/fundamental/Copy-on-write.md new file mode 100644 index 00000000..f71b321d --- /dev/null +++ b/dev/fundamental/Copy-on-write.md @@ -0,0 +1,45 @@ +--- +aliases: + - COW +tags: + - maturity/🌱 +date: 2024-09-17 +zero-link: +parents: +linked: +--- +Copy-on-Write (COW) — это техника оптимизации управления памятью, используемая в [[../../../../knowledge/dev/pc/Операционная система|операционных системах]] для эффективного копирования данных, особенно в контексте [[Многозадачность ЦПУ|многозадачности]] и управления виртуальной памятью. Этот метод позволяет нескольким процессам совместно использовать одну и ту же страницу памяти до тех пор, пока данные не нужно будет изменить, что экономит ресурсы и ускоряет выполнение программ. + +**Как работает Copy-on-Write:** +- **Совместное использование страниц:** Когда [[Процесс ОС|процесс]] создаёт копию себя (например, при вызове fork() в UNIX-подобных системах), операционная система не копирует все [[Страница|страницы]] памяти сразу. Вместо этого родительский и дочерний процессы продолжают совместно использовать одни и те же страницы памяти. +- **Установка флага защиты:** Страницы, используемые в режиме Copy-on-Write, помечаются как «только для чтения» для обоих процессов. Это означает, что оба процесса могут читать данные без необходимости создания отдельных копий для каждого из них. +- **Промах страницы** ([[Page Fault]]) при записи: Если один из процессов пытается изменить данные на странице, происходит Page Fault. Операционная система понимает, что требуется изменить данные, которые в данный момент используются совместно, и инициирует Copy-on-Write. +- **Создание копии страницы:** Операционная система создаёт отдельную копию страницы только для того процесса, который пытается внести изменения. В результате изменения затрагивают только копию, а остальные процессы продолжают использовать оригинальную страницу без изменений. +- **Обновление таблицы страниц:** После создания копии, таблица страниц соответствующего процесса обновляется, чтобы указывать на новую копию страницы, которая теперь доступна для записи. + +**Примеры использования:** +- **Процессы и fork():** Когда выполняется fork(), дочерний процесс получает копию адресного пространства родительского процесса. Copy-on-Write позволяет избежать полной копии всех данных сразу, экономя время и память. +- **Виртуальные машины и контейнеры:** Виртуальные машины и контейнеры часто используют Copy-on-Write для совместного использования одинаковых библиотек и данных между разными экземплярами. +- **Файловые системы (например, Btrfs, ZFS):** Некоторые файловые системы используют Copy-on-Write для создания снимков (snapshot) и клонирования данных без необходимости немедленного копирования всех данных. + +**Преимущества Copy-on-Write:** +- **Экономия памяти:** Позволяет избежать дублирования данных до тех пор, пока это действительно не нужно, что снижает расход оперативной памяти. +- **Ускорение выполнения:** Процессы могут начинать работать быстрее, поскольку нет необходимости мгновенно копировать большие объемы данных. +- **Гибкость и безопасность:** Совместное использование данных безопасно до тех пор, пока нет попыток изменить данные, что упрощает управление памятью. + +**Недостатки Copy-on-Write:** +- **Задержки при записи:** При попытке записи возникает задержка из-за необходимости создания копии страницы, что может вызывать временное снижение производительности. +- **Усложнение управления памятью:** Операционная система должна отслеживать и обрабатывать копии страниц, что усложняет управление виртуальной памятью. +- **Дополнительные Page Faults:** Copy-on-Write приводит к большему числу Page Faults, так как любое изменение данных требует создания новой копии страницы. +*** +## Мета информация +**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]] +**Родитель**:: +**Источник**:: +**Создана**:: [[2024-09-17]] +**Автор**:: +### Дополнительные материалы +- + +### Дочерние заметки + diff --git a/dev/fundamental/Tree.md b/dev/fundamental/Tree.md new file mode 100644 index 00000000..ce3e2733 --- /dev/null +++ b/dev/fundamental/Tree.md @@ -0,0 +1,43 @@ +--- +aliases: + - дерево +tags: + - maturity/🌱 +date: 2024-09-17 +zero-link: + - "[[../garden/ru/meta/zero/00 Разработка|00 Разработка]]" +parents: + - "[[structure/Структура данных]]" +linked: +--- +Дерево — это иерархическая структура данных, состоящая из узлов (вершин), которые связаны друг с другом ребрами. Главные характеристики деревьев: +- Корень: Узел, с которого начинается дерево. У него нет родительского узла. +- Листья: Узлы, которые не имеют дочерних узлов. +- Уровни: Глубина или высота узла относительно корня. +- Родители и потомки: В каждом узле, кроме корня, есть родитель, и могут быть дочерние узлы (потомки). + +Виды деревьев: +- [[structure/Бинарное дерево поиска|Бинарное дерево]]: Каждый узел имеет не более двух потомков — левый и правый. +- Двоичное дерево поиска (Binary Search Tree, BST): [[structure/Бинарное дерево поиска|Бинарное дерево]], в котором левый потомок содержит значения меньше родительского узла, а правый — больше. +- AVL-дерево: [[structure/Сбалансированное дерево|Сбалансированное]] [[structure/Бинарное дерево поиска|бинарное дерево поиска]], в котором разница высот левого и правого поддерева любого узла не превышает 1. +- Красно-черное дерево: [[structure/Бинарное дерево поиска|Бинарное дерево поиска]], которое поддерживает балансировку путём соблюдения определённых свойств цветных узлов. +- [[structure/B-tree]] (B-дерево): Обобщение бинарного дерева для случаев, когда узлы могут иметь больше двух потомков, эффективно используемое для больших данных. +- B+-дерево: Вариант B-дерева, в котором все ключи хранятся только в листьях, а внутренние узлы используются только для направления поиска. +- Trie: Префиксное дерево, используемое для хранения строк, где каждый узел представляет часть строки. +*** +## Мета информация +**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]] +**Родитель**:: [[structure/Структура данных]] +**Источник**:: +**Создана**:: [[2024-09-17]] +**Автор**:: +### Дополнительные материалы +- + +### Дочерние заметки + + +- [[Бинарное дерево поиска]] +- [[Сбалансированное дерево]] +- [[B-tree]] + diff --git a/dev/fundamental/structure/B-tree.md b/dev/fundamental/structure/B-tree.md new file mode 100644 index 00000000..13a0b3fc --- /dev/null +++ b/dev/fundamental/structure/B-tree.md @@ -0,0 +1,77 @@ +--- +aliases: +tags: + - maturity/🌱 +date: + - - 2024-01-29 +zero-link: +parents: [] +linked: +--- +[Сбалансированное](structure/Сбалансированное%20дерево.md) сильно-ветвистое дерево. Позволяет хранить в узле множество значений. + +![](../../../meta/files/images/Pasted%20image%2020240205190752.png) + +- Узел содержит множество элементов. +- Каждый узел является по факту страничкой на диске, это позволяет уменьшить издержки на чтение с диска. +- В каждом узле есть ссылка на следующий и предыдущий узел (B+tree). +- В узлах дерева лежат либо данные, либо указатель на данные. + +В таком дереве есть параметр t - минимальная степень. От этого параметра зависит, сколько будет храниться элементов в 1 узле дерева. В каждом узле должно храниться не мене t-1 ключе, и не более 2t-1. Правильно не выполняется для корневого значения. + +Какое t использовать? +- Больше t -> меньше высота дерева +- зависит от размера блока на диске +- зависит от объема ОЗУ +- Обычно t выбирается от 50 до 2000. +- t = 1001 и 1 млрд. записей => 3 операции для любого ключа + +Элементы в узле бинарного дерева отсортированы. + +Большое количество элементов в узле позволяет делать деревья с большим количеством элементов, но с небольшой высотой. + +**С чем может помочь:** +- Поиск по равенству (a=5) +- Поиск по открытому диапазон (a > 5 или a < 3) +- Поиск по закрытому диапазону (3 < a < 8) +- LIKE тоже работает с индексами, но только по префиксам + - LIKE 'a%' - хорошо + - LIKE '%c' - плохо +**С чем НЕ поможет:** +- Искать четные/нечетные числа +- Искать суффиксы. LIKE '%c' - плохо +## Поиск в B-tree +Пример поиска 27. + +![](../../../meta/files/images/Pasted%20image%2020240129193115.png) + +Важно. Значения в узлах могут быть не уникальными. Например, могло быть 2 числа 27. В таком случае поиск продолжается. При этом стоит учитывать, что количество элементов внутри узла ограничено, а значит следующий элемент (27) может находится в следующем узле. Поэтому для оптимизации этой проблемы блоки на одном уровне линкуют, создавая связный список, чтобы легко перейти в следующий блок. + +- алгоритм аналогичен [бинарному дереву](structure/Бинарное%20дерево%20поиска.md), но выбор не из 2-ух, а из нескольких +- поиск за O(t logt(n)) +- Но обращений к диску O(logt(n)) + +## Добавление в B-tree +Представим, что у нас уже есть вот такое дерево, и нам надо вставить в него значение 15 + +![](../../../meta/files/images/Pasted%20image%2020240129194120.png) + +Мы понимаем, что вставка должна быть между 4 и 17, там у нас есть узел 7...16. Но в него мы вставить не можем, так как в данном случае у нас t = 3, а значит в блоке не должно быть больше 5 значений. + +Поэтому блок разбивается начиная с t-1 элементу. В данном случае это 11. Элемент, по которому разбивается блок перемещается в родительский блок. Если в родительском блоке происходит переполнение, то родительский блок тоже разбивается и так далее. + +После вставки мы получим следующее дерево + +![](../../../meta/files/images/Pasted%20image%2020240129194629.png) +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 Разработка|00 Разработка]], [[../../../meta/zero/00 Алгоритм|00 Алгоритм]] +**Родитель**:: [[Tree]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-01-29]] +### Дополнительные материалы +- +### Дочерние заметки + + diff --git a/dev/fundamental/structure/Бинарное дерево поиска.md b/dev/fundamental/structure/Бинарное дерево поиска.md new file mode 100644 index 00000000..26207087 --- /dev/null +++ b/dev/fundamental/structure/Бинарное дерево поиска.md @@ -0,0 +1,38 @@ +--- +aliases: + - бинарное дерево + - бинарному дереву +tags: + - maturity/🌱 +date: + - - 2024-01-29 +zero-link: + - "[[../../../meta/zero/00 Разработка|00 Разработка]]" +parents: +linked: +--- +Дерево у которого выполняется 3 свойства +- элемент в левом под-дереве должны быть меньше родительского узла +- элементы в правом под-дереве должны быть больше родительского узла +- у каждого узла не больше 2 потомков + +![x|400](../../../meta/files/images/Pasted%20image%2020240129190639.png) + +Эти свойства дают +- гарантированный порядок элементов +- детерминированный алгоритм поиска +- в вырожденном случае придется посетить все элементы O(n). + +Чтобы улучшить поиск, можно использовать [сбалансированное](Сбалансированное%20дерево.md) бинарное дерево. + +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 Разработка|00 Разработка]] +**Родитель**:: [[Tree]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-01-29]] +### Дополнительные материалы +- +### Дочерние заметки + diff --git a/dev/fundamental/structure/Сбалансированное дерево.md b/dev/fundamental/structure/Сбалансированное дерево.md new file mode 100644 index 00000000..4dfa91e1 --- /dev/null +++ b/dev/fundamental/structure/Сбалансированное дерево.md @@ -0,0 +1,33 @@ +--- +aliases: + - сбалансированное дерево + - сбалансированное +tags: + - maturity/🌱 +date: + - - 2024-01-29 +zero-link: +parents: [] +linked: +--- +Сбалансированное дерево позволяет уменьшить сложность поиска в дереве. В сбалансированном дереве высота левого и правого дерева отличается не больше, чем на единицу. + +Балансировка заключается в + +![](../../../meta/files/images/Pasted%20image%2020240129191116.png) + +Сбалансированное дерево +- решает проблему вырожденного случая бинарного дерева +- дает поиск за O(высоты дерева) +- но требует дополнительных усилий на балансировку +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 Разработка|00 Разработка]] +**Родитель**:: [[Tree|Tree]] +**Источник**:: +**Автор**:: +**Создана**:: [[2024-01-29]] +### Дополнительные материалы +- +### Дочерние заметки + diff --git a/dev/fundamental/structure/Структура данных.md b/dev/fundamental/structure/Структура данных.md new file mode 100644 index 00000000..c54f2dc6 --- /dev/null +++ b/dev/fundamental/structure/Структура данных.md @@ -0,0 +1,28 @@ +--- +aliases: +tags: + - maturity/🌱 +date: 2024-09-17 +zero-link: + - "[[../../../meta/zero/00 Разработка|00 Разработка]]" +parents: +linked: +--- +- [[Tree|Дерево]] +- [[structure/Хеш-таблица|Хеш-таблица]] +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 Разработка|00 Разработка]] +**Родитель**:: +**Источник**:: +**Создана**:: [[2024-09-17]] +**Автор**:: +### Дополнительные материалы +- + +### Дочерние заметки + + +- [[Tree]] +- [[Хеш-таблица]] + diff --git a/dev/fundamental/structure/Хеш-таблица.md b/dev/fundamental/structure/Хеш-таблица.md new file mode 100644 index 00000000..e6e5a87e --- /dev/null +++ b/dev/fundamental/structure/Хеш-таблица.md @@ -0,0 +1,48 @@ +--- +aliases: + - хеш таблица + - хеш таблице + - хеш-таблице + - хеш-таблицу + - хеш-таблиц + - хеш таблицу + - хеш таблиц +tags: + - maturity/🌱 +date: 2024-09-17 +zero-link: + - "[[../../../meta/zero/00 Разработка|00 Разработка]]" +parents: + - "[[Структура данных]]" +linked: +--- +Хэш-таблица — это [[Структура данных|структура данных]], которая используется для эффективного хранения и поиска данных на основе ключей. Она обеспечивает быстрый доступ к элементам, используя [[../../cryptography/Хеш-функция|хеш-функцию]] для преобразования ключа в индекс массива, где хранится значение. Это делает операции вставки, удаления и поиска очень быстрыми, обычно за время O(1). + +**Основные концепции хэш-таблицы:** +- **Ключ и значение:** Каждый элемент в хэш-таблице хранится в виде пары “ключ-значение”. Ключи должны быть уникальными, а значения могут быть любыми. Например, в хэш-таблице можно хранить данные о студентах, где ключом будет идентификационный номер, а значением — информация о студенте. +- [[../../cryptography/Хеш-функция|Хеш-функция]] Это основа работы хэш-таблицы. Хеш-функция принимает ключ и вычисляет индекс в массиве, где должно быть размещено значение. Например, для ключа “apple” хэш-функция может вернуть индекс 3, и значение будет сохранено в ячейке с индексом 3. +- **Разрешение коллизий:** Поскольку разные ключи иногда могут давать одинаковый хэш (коллизии), нужно уметь их разрешать. Существуют несколько подходов: + - **Метод цепочек (Chaining):** В каждой ячейке массива хранится связанный список значений, чьи ключи дали одинаковый хэш. При коллизии элемент добавляется в этот список. + - **Открытая адресация (Open Addressing):** При коллизии элемент помещается в следующую свободную ячейку массива по определённому алгоритму (например, линейное пробирование или двойное хэширование). +- **Коэффициент загрузки (Load Factor):** Это соотношение количества элементов к размеру массива. Если коэффициент загрузки слишком велик, производительность хэш-таблицы падает, и может понадобиться увеличение массива и перерасчёт всех хешей (рехеширование). + +**Преимущества хэш-таблиц:** +- **Быстрый доступ:** Операции вставки, удаления и поиска обычно выполняются за константное время O(1). +- **Гибкость ключей:** Могут использоваться любые неизменяемые типы данных в качестве ключей (строки, числа, кортежи и т.д.). + +**Недостатки хэш-таблиц:** +- **Память:** Хэш-таблицы могут потреблять много памяти из-за большого размера массива, особенно при низком коэффициенте загрузки. +- **Коллизии:** Если хеш-функция некачественная или слишком много элементов, это может замедлить работу из-за коллизий. +- **Нет упорядоченности:** Порядок элементов в хэш-таблице не предсказуем и не сохраняется. +*** +## Мета информация +**Область**:: [[../../../meta/zero/00 Разработка|00 Разработка]] +**Родитель**:: [[Структура данных]] +**Источник**:: +**Создана**:: [[2024-09-17]] +**Автор**:: +### Дополнительные материалы +- + +### Дочерние заметки + diff --git a/dev/fundamental/Страница.md b/dev/fundamental/Страница.md new file mode 100644 index 00000000..19b5b5ee --- /dev/null +++ b/dev/fundamental/Страница.md @@ -0,0 +1,40 @@ +--- +aliases: + - страницы + - страниц +tags: + - maturity/🌱 +date: 2024-09-17 +zero-link: +parents: +linked: +--- +Страница это непрерывный блок памяти фиксированного размера. + +**Размер страницы:** Обычно размер страницы составляет от 4 КБ до нескольких мегабайт, в зависимости от архитектуры [[Центральный процессор|процессора]] и настроек [[../../../../knowledge/dev/pc/Операционная система|операционной системы]]. Например, в большинстве современных систем страница составляет 4 КБ, но на некоторых системах могут использоваться страницы большего размера, например, 2 МБ или 4 МБ. Большие страницы (так называемые Huge Pages) могут использоваться для повышения производительности, так как они уменьшают накладные расходы на управление памятью и уменьшение количества записей в таблице страниц. + +**Страницы и виртуальная память:** Виртуальная память — это механизм, который позволяет программе использовать больше памяти, чем физически доступно на компьютере. Виртуальное адресное пространство разбивается на страницы, которые могут быть размещены в оперативной памяти (RAM) или на диске (swap file или page file). + +**Таблица страниц:** Операционная система использует таблицу страниц для отслеживания, где находятся страницы виртуальной памяти (в оперативной памяти или на диске). Каждой странице виртуальной памяти соответствует страница в физической памяти. + +**Страницы в физической памяти:** Страницы, загруженные в оперативную память, называются фреймами. Размер фрейма совпадает с размером страницы, что упрощает управление памятью. + +**Защита от записи (Read-Only):** Страницы, содержащие код программы, как правило, защищены от записи. Это делает их доступными только для чтения, предотвращая случайные или злонамеренные изменения в коде программы, что повышает безопасность и стабильность системы. + +**Зачем нужны страницы:** +- **Упрощение управления памятью:** Разбиение памяти на страницы позволяет операционной системе эффективно управлять памятью, перемещая страницы между RAM и дисковым пространством по мере необходимости. +- **Изоляция процессов:** Использование страниц помогает изолировать [[Процесс ОС|процессы]] друг от друга, так как каждый процесс видит только своё виртуальное адресное пространство. +- **Подкачка:** Страницы, которые не используются, могут быть выгружены на диск, освобождая оперативную память для других нужд. +- **Обработка ошибок:** Когда процесс пытается обратиться к странице, которой нет в памяти, операционная система обрабатывает [[../../../../_inbox/Page Fault|Page Fault]], загружая нужную страницу с диска. +*** +## Мета информация +**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]] +**Родитель**:: +**Источник**:: +**Создана**:: [[2024-09-17]] +**Автор**:: +### Дополнительные материалы +- + +### Дочерние заметки + diff --git a/index.md b/index.md index 94287232..2ebf8770 100644 --- a/index.md +++ b/index.md @@ -48,16 +48,18 @@ enableToc: false - [Quarkus](meta/zero/00%20Quarkus.md) - [SpringBoot](meta/zero/00%20SpringBoot.md) - [Hibernate](meta/zero/00%20Hibernate.md) / [[meta/zero/00 Hibernate Reactive|Hibernate Reactive]] + - Сборщики + - [[meta/zero/00 Maven|Maven]] + - [[meta/zero/00 Gradle|Gradle]] - Архитектура - [[meta/zero/00 Архитектура ЭВМ|Архитектура ЭВМ]] - [Архитектура ПО](meta/zero/00%20Архитектура%20ПО.md) - [Архитектура ИС](meta/zero/00%20Архитектура%20ИС.md) - [[meta/zero/00 HighLoad|HighLoad]] + - [[meta/zero/00 Базы Данных|Базы Данных]] + - [[meta/zero/00 PostgreSQL|PostgreSQL]] - [DevOps](meta/zero/00%20DevOps.md) - [Docker](meta/zero/00%20Docker.md) - - Сборщики - - [[meta/zero/00 Maven|00 Maven]] - - [[meta/zero/00 Gradle|00 Gradle]] - [[meta/zero/00 Linux|Linux]] - [Сети](meta/zero/00%20Сети.md) - [Алгоритмы](meta/zero/00%20Алгоритм.md) diff --git a/meta/files/images/Pasted image 20240129190639.png b/meta/files/images/Pasted image 20240129190639.png new file mode 100644 index 00000000..89fcfbca Binary files /dev/null and b/meta/files/images/Pasted image 20240129190639.png differ diff --git a/meta/files/images/Pasted image 20240129191116.png b/meta/files/images/Pasted image 20240129191116.png new file mode 100644 index 00000000..11c5fc0f Binary files /dev/null and b/meta/files/images/Pasted image 20240129191116.png differ diff --git a/meta/files/images/Pasted image 20240129193115.png b/meta/files/images/Pasted image 20240129193115.png new file mode 100644 index 00000000..fb8b544a Binary files /dev/null and b/meta/files/images/Pasted image 20240129193115.png differ diff --git a/meta/files/images/Pasted image 20240129194120.png b/meta/files/images/Pasted image 20240129194120.png new file mode 100644 index 00000000..11edb108 Binary files /dev/null and b/meta/files/images/Pasted image 20240129194120.png differ diff --git a/meta/files/images/Pasted image 20240129194629.png b/meta/files/images/Pasted image 20240129194629.png new file mode 100644 index 00000000..e87f9e9d Binary files /dev/null and b/meta/files/images/Pasted image 20240129194629.png differ diff --git a/meta/files/images/Pasted image 20240205190752.png b/meta/files/images/Pasted image 20240205190752.png new file mode 100644 index 00000000..4778e2a5 Binary files /dev/null and b/meta/files/images/Pasted image 20240205190752.png differ diff --git a/meta/files/images/Pasted image 20240206195611.png b/meta/files/images/Pasted image 20240206195611.png new file mode 100644 index 00000000..4c43e3c6 Binary files /dev/null and b/meta/files/images/Pasted image 20240206195611.png differ diff --git a/meta/files/images/Pasted image 20240206195639.png b/meta/files/images/Pasted image 20240206195639.png new file mode 100644 index 00000000..ab0b61e3 Binary files /dev/null and b/meta/files/images/Pasted image 20240206195639.png differ diff --git a/meta/files/images/Pasted image 20240219184314.png b/meta/files/images/Pasted image 20240219184314.png new file mode 100644 index 00000000..b6c9af73 Binary files /dev/null and b/meta/files/images/Pasted image 20240219184314.png differ diff --git a/meta/files/images/Pasted image 20240226135429.png b/meta/files/images/Pasted image 20240226135429.png new file mode 100644 index 00000000..4ae170a8 Binary files /dev/null and b/meta/files/images/Pasted image 20240226135429.png differ diff --git a/meta/files/images/Pasted image 20240229204146.png b/meta/files/images/Pasted image 20240229204146.png new file mode 100644 index 00000000..2864dac8 Binary files /dev/null and b/meta/files/images/Pasted image 20240229204146.png differ diff --git a/meta/files/images/Pasted image 20240528082025.png b/meta/files/images/Pasted image 20240528082025.png new file mode 100644 index 00000000..adb91666 Binary files /dev/null and b/meta/files/images/Pasted image 20240528082025.png differ diff --git a/meta/files/images/Pasted image 20240528085716.png b/meta/files/images/Pasted image 20240528085716.png new file mode 100644 index 00000000..37fa87d3 Binary files /dev/null and b/meta/files/images/Pasted image 20240528085716.png differ diff --git a/meta/files/images/Pasted image 20240528090119.png b/meta/files/images/Pasted image 20240528090119.png new file mode 100644 index 00000000..b97f3b7d Binary files /dev/null and b/meta/files/images/Pasted image 20240528090119.png differ diff --git a/meta/files/images/Pasted image 20240528090205.png b/meta/files/images/Pasted image 20240528090205.png new file mode 100644 index 00000000..f7b2d5b0 Binary files /dev/null and b/meta/files/images/Pasted image 20240528090205.png differ diff --git a/meta/files/images/Pasted image 20240605091036.png b/meta/files/images/Pasted image 20240605091036.png new file mode 100644 index 00000000..51b82be5 Binary files /dev/null and b/meta/files/images/Pasted image 20240605091036.png differ diff --git a/meta/files/images/Pasted image 20240605091913.png b/meta/files/images/Pasted image 20240605091913.png new file mode 100644 index 00000000..c5a40fd5 Binary files /dev/null and b/meta/files/images/Pasted image 20240605091913.png differ diff --git a/meta/files/images/Pasted image 20240606094633.png b/meta/files/images/Pasted image 20240606094633.png new file mode 100644 index 00000000..b62f31d7 Binary files /dev/null and b/meta/files/images/Pasted image 20240606094633.png differ diff --git a/meta/files/images/Pasted image 20240606094952.png b/meta/files/images/Pasted image 20240606094952.png new file mode 100644 index 00000000..a2e50e97 Binary files /dev/null and b/meta/files/images/Pasted image 20240606094952.png differ diff --git a/meta/files/images/Pasted image 20240607211343.png b/meta/files/images/Pasted image 20240607211343.png new file mode 100644 index 00000000..10b9c153 Binary files /dev/null and b/meta/files/images/Pasted image 20240607211343.png differ diff --git a/meta/files/images/Pasted image 20240607211612.png b/meta/files/images/Pasted image 20240607211612.png new file mode 100644 index 00000000..b50adc39 Binary files /dev/null and b/meta/files/images/Pasted image 20240607211612.png differ diff --git a/meta/files/images/Pasted image 20240607212223.png b/meta/files/images/Pasted image 20240607212223.png new file mode 100644 index 00000000..6f2d05a1 Binary files /dev/null and b/meta/files/images/Pasted image 20240607212223.png differ diff --git a/meta/files/images/Pasted image 20240613195204.png b/meta/files/images/Pasted image 20240613195204.png new file mode 100644 index 00000000..b7d111cb Binary files /dev/null and b/meta/files/images/Pasted image 20240613195204.png differ diff --git a/meta/files/images/Pasted image 20240712083105.png b/meta/files/images/Pasted image 20240712083105.png new file mode 100644 index 00000000..055b549a Binary files /dev/null and b/meta/files/images/Pasted image 20240712083105.png differ diff --git a/meta/zero/00 HighLoad.md b/meta/zero/00 HighLoad.md index 882fef81..0ddd2e1c 100644 --- a/meta/zero/00 HighLoad.md +++ b/meta/zero/00 HighLoad.md @@ -32,16 +32,19 @@ aliases: - [Сервис-ориентированная архитектура](Service%20Oreinted%20Architecture.md) - [Вертикальное масштабирование](../../dev/architecture/highload/Вертикальное%20масштабирование.md) - [Горизонтальное масштабирование](../../dev/architecture/highload/Горизонтальное%20масштабирование.md) + - [Репликация](../../dev/architecture/highload/Репликация.md) + - [[../../dev/architecture/highload/Репликация БД|Репликация БД]] + - [[../../dev/database/postgresql/Репликация в PostgreSQL|Репликация в PostgreSQL]] + - [[../../dev/database/postgresql/Репликация в PostgreSQL|Репликация в PostgreSQL]] - Отложенные вычисления - Асинхронная обработка - Конвейерная обработка - Использование толстого клиента - [Кэширование](../../dev/architecture/Кэширование.md) - [Функциональное разделение](Функциональное%20разделение.md) -- [Шардинг](Шардирование%20в%20БД.md) +- [Шардинг](../../../../_inbox/Шардирование%20БД.md) - Виртуальные шарды - Центральный диспетчер -- [Репликация](_inbox/Репликация.md) - Партиционирование - Кластеризация - Денормализация diff --git a/meta/zero/00 MySQL.md b/meta/zero/00 MySQL.md new file mode 100644 index 00000000..8d526ff2 --- /dev/null +++ b/meta/zero/00 MySQL.md @@ -0,0 +1,33 @@ +--- +aliases: + - MySQL +tags: + - type/zero-link +zero-link: + - "[[00 Базы Данных]]" +title: MySQL +--- +- [[../../dev/database/mysql/Архитектура MySQL|Архитектура MySQL]] +- [Репликация в MySQL](../../dev/database/mysql/Репликация%20в%20MySQL.md) +- [libslave](libslave.md) +- [Бекап в MySQL](Бекап%20в%20MySQL.md) +- [Индексы в MySQL](Индексы%20в%20MySQL.md) +- [Журналы в MySQL](../../dev/database/mysql/Журналы%20в%20MySQL.md) +- [Explain в MySQL](Explain%20в%20MySQL.md) +## Идентификация транзакций +До версии 5.5 идентифицировать транзакцию можно было только по имени файла и позиции в этом файле. Потом появились GTID, но надо явно включить gtid_mode =ON. C 5.6.5 GTID используется по умолчанию. + +binary log position: +- Пример: mysql-bin.00078:44 +- Локальный для сервера +- Обязательно сломается + +GTID: +- Пример: 7F33BC78-56CA-44B3-5E33-B34CC7689333:44 +- Глобален, генерируется автоматически при коммите +- Бесплатная трассировка +- Простой slave promotion +- ==Используйте его== + +## Заметки +- MySQL пишет на диск в три места – хранилище (tablespace), журнал (undo/redo log), и Binary Log \ No newline at end of file diff --git a/meta/zero/00 PostgreSQL.md b/meta/zero/00 PostgreSQL.md new file mode 100644 index 00000000..8c5c9a78 --- /dev/null +++ b/meta/zero/00 PostgreSQL.md @@ -0,0 +1,23 @@ +--- +aliases: + - PostgreSQL +tags: + - type/zero-link +zero-link: + - "[[00 Базы Данных]]" +title: PostgreSQL +--- +- Устройство PostgreSQL + - Журнал: [Write-Ahead Log](../../dev/database/postgresql/Write-Ahead%20Log.md) +- [Индекс в PostgreSQL](Индекс%20в%20PostgreSQL.md) +- [Репликация в PostgreSQL](../../dev/database/postgresql/Репликация%20в%20PostgreSQL.md) +- [Бэкап в PostgreSQL](Бэкап%20в%20PostgreSQL.md) +- [Профилирование запросов в PostgreSQL](Профилирование%20запросов%20в%20PostgreSQL.md) + - [Explain в PostgreSQL](Explain%20в%20PostgreSQL.md) + +## Заметки +- PostgreSQL пишет на диск в два места – в хранилище данных и в журнал. +- Если транзакции нужно выполнить операцию с данными, с которыми работает другая транзакция, то она может встать в очередь. + +## Дополнительные материалы +- [pg_utils](pg_utils.md) \ No newline at end of file diff --git a/meta/zero/00 Архитектура ИС.md b/meta/zero/00 Архитектура ИС.md index 48c8ce0a..885772ca 100644 --- a/meta/zero/00 Архитектура ИС.md +++ b/meta/zero/00 Архитектура ИС.md @@ -5,6 +5,9 @@ parents: - "[[00 Разработка]]" title: Архитектура ПО --- +- [[../../../../_inbox/Architecture Significant Requirement|Architecture Significant Requirement]] + + - [[../../dev/architecture/CAP теорема|CAP теорема]] - [Трёхзвенная структура](../../dev/architecture/Трёхзвенная%20структура.md) - [Монолитная архитектура](Монолитная%20архитектура.md) diff --git a/meta/zero/00 Базы Данных.md b/meta/zero/00 Базы Данных.md new file mode 100644 index 00000000..2be06669 --- /dev/null +++ b/meta/zero/00 Базы Данных.md @@ -0,0 +1,39 @@ +--- +tags: + - type/zero-link +parents: + - "[[00 Разработка]]" +aliases: + - база данных + - базу данных +linked: + - "[[../../../../_inbox/00 In-memory СуБД|00 In-memory СуБД]]" +--- +- [Журнал БД](../../dev/database/Журнал%20БД.md) +- [Репликация БД](../../dev/architecture/highload/Репликация%20БД.md) +- [Резервные копии БД](Резервные%20копии%20БД.md) +- [Транзакция БД](Транзакция%20БД.md) + +СуБД: +- [PostgreSQL](00%20PostgreSQL.md) +- [MySQL](00%20MySQL.md) +## Улучшение производительности +- [Репликация БД](../../dev/architecture/highload/Репликация%20БД.md) +- [Шардирование БД](../../../../_inbox/Шардирование%20БД.md) + +- Выбирать правильный тип для колонки +- Денормализация +- Меньше индексов - лучше +- Меньше джойнов - лучше + +Приложение работает неограниченное количество времени, с каждым днем количество данных в БД увеличивается. При возрастании объема запросы начинают отрабатывать медленнее, в таком случае возникает необходимость в применении [партиционирования](Партиционирование%20в%20БД.md) и [шардирования](../../../../_inbox/Шардирование%20БД.md). + +- [Производительность SQL запросов](_inbox/Производительность%20SQL%20запросов.md) + +## Заметки + - Классические СУБД хранят данные в двух местах: на диске и в памяти. + - [[../../dev/fundamental/Страница|Страница]] модифицируется сначала в оперативной памяти, потом попадает на диск. +  - ![](Pasted%20image%2020240531082744.png) + - Часто думают, что реляционная таблица — это массив. Некоторые даже думают, что это двумерный массив. На самом деле, это гораздо более сложная штука. Это мультимножество – набор определенного сорта кортежей, над которым не задано порядка. В SQL-таблице нет порядка. Это важно. И, как результат, когда вы делаете SELECT* из БД (просканировать все записи), результат выполнения запроса может меняться – строчки могут быть в одном порядке, а могут и в другом. Про это нужно помнить. + - Профиль нагрузки на реляционную базу данных выглядит следующим образом: 80% запросов это чтение, 20% запросов это запись. Если запросов на запись больше, то возможно реляционная база данных вам не подходит. + diff --git a/meta/zero/00 Криптография.md b/meta/zero/00 Криптография.md index c874f73b..4e1512c0 100644 --- a/meta/zero/00 Криптография.md +++ b/meta/zero/00 Криптография.md @@ -6,5 +6,5 @@ date: parents: title: Криптография --- -- [[../../dev/cryptography/Криптографическая хеш-функция|Криптографическая хеш-функция]] +- [[../../dev/cryptography/Хеш-функция|Хеш-функция]] - [Генерация аппаратного SSH ключа](../../dev/cryptography/Генерация%20аппаратного%20SSH%20ключа.md) \ No newline at end of file diff --git a/meta/zero/00 Сон.md b/meta/zero/00 Сон.md new file mode 100644 index 00000000..793a0b25 --- /dev/null +++ b/meta/zero/00 Сон.md @@ -0,0 +1,53 @@ +--- +tags: + - type/zero-link +aliases: + - сон + - сна + - сне + - сном + - спать +zero-link: + - "[[00 Здоровье|00 Здоровье]]" +--- +- [Качественный сон](Качественный%20сон.md) + - [Как наладить сон?](Как%20наладить%20сон?.md) +- [[../../../../knowledge/health/болезни/Расстройства сна|Расстройства сна]] +- [Как не заснуть?](Как%20не%20заснуть?.md) +- [Сновидения](Сновидения.md) +- [Утреннее пробуждение](knowledge/health/сон/Утреннее%20пробуждение.md) + +Главные компоненты отвечающие за сон: +- [Мелатонин](knowledge/human/гормоны/Мелатонин.md) - гормон "темноты и сна". Вырабатывает [Шишковидная железа](knowledge/human/строение/Шишковидная%20железа.md) +- [Циркадные ритмы](knowledge/human/Циркадные%20ритмы.md) - наши внутренние биологические часы +- [Супрахиазматическое ядро](Супрахиазматическое%20ядро.md) - следит за временем, ориентируясь на свет +- Нейромедиаторы и гормоны: [Кортизол](Кортизол.md), [Адреналин](Адреналин.md), [Норадреналин](Норадреналин.md), [Аденозин](Аденозин.md) +- [Фазы сна](Фазы%20сна.md): [Поверхностный сон](_inbox/Поверхностный%20сон.md), [Глубокая фаза сна](Глубокая%20фаза%20сна.md), [REM](Фаза%20быстрого%20сна.md) +## Зачем нужен сон? +**Сон играет роль уборщика**, [удаляя](https://www.sciencedirect.com/science/article/abs/pii/S2468867319301609#:~:text=The%20discovery%20that,dependence%20on%20glia.) из мозга продукты метаболизма — ненужные белки, которые накапливаются во время бодрствования и приводят к заболеваниям нервной системы. Среди таких белков — бета-амилоид, большая концентрация которого приводит к [гибели](https://med.stanford.edu/news/all-news/2013/09/scientists-reveal-how-beta-amyloid-may-cause-alzheimers.html#:~:text=Scientists%20at%20the%20Stanford%20University%20School%20of%20Medicine%20have%20shown%20how%20a%20protein%20fragment%20known%20as%20beta%2Damyloid%2C%20strongly%20implicated%20in%20Alzheimer%E2%80%99s%20disease%2C%20begins%20destroying%20synapses%20before%20it%20clumps%20into%20plaques%20that%20lead%20to%20nerve%20cell%20death.) нервных клеток и, [вероятно](https://www.medicalnewstoday.com/articles/325493#:~:text=If%20the%20cellular%20system%20became%20overloaded%20or%20slowed%20down%20as%20we%20aged%2C%20metabolic%20garbage%20would%20build%20up%20between%20the%20cells.%20This%20garbage%20includes%20products%20such%20as%20beta%2Damyloid%20%E2%80%94%20the%20protein%20associated%20with%20Alzheimer%E2%80%99s%20disease.), к [[../../../../knowledge/health/болезни/Болезнь Альцгеймера|болезни Альцгеймера]]. Всего одна бессонная ночь значительно [повышает](https://www.pnas.org/doi/10.1073/pnas.1721694115#:~:text=We%20show%20that%20one%20night%20of%20sleep%20deprivation%2C%20relative%20to%20baseline%2C%20resulted%20in%20a%20significant%20increase%20in%20A%CE%B2%20burden%20in%20the%20right%20hippocampus%20and%20thalamus.) объем этого белка в мозге человека. + +**Сон важен для физического самочувствия.** Пока мы спим, [усиливается](https://erj.ersjournals.com/content/38/4/870#:~:text=The%20release%20of%20GH%20is%20greatly%20enhanced%20during%20sleep%2C%20especially%20early%20in%20the%20night) выработка [«гормона роста»](https://ru.wikipedia.org/wiki/%D0%93%D0%BE%D1%80%D0%BC%D0%BE%D0%BD_%D1%80%D0%BE%D1%81%D1%82%D0%B0), который [восстанавливает](https://www.healthline.com/health/hgh-side-effects#:~:text=HGH%20helps%20to%20maintain%2C%20build%2C%20and%20repair%20healthy%20tissue%20in%20the%20brain%20and%20other%20organs.%20This%20hormone%20can%20help%20to%20speed%20up%20healing%20after%20an%20injury%20and%20repair%20muscle%20tissue%20after%20exercise.%20This%20helps%20to%20build%20muscle%20mass%2C%20boost%20metabolism%2C%20and%20burn%20fat.) мышцы после нагрузок и травм. Нехватка этого гормона [приводит](https://academic.oup.com/jcem/article/83/2/382/2865179?login=false#:~:text=1.%20Lean%20Body%20Mass%20(LBM).%20Reduced%20LBM%20is%20an%20important%20feature%20of%20AO%20GH%20deficiency.%20Initial%20studies%20demonstrated%20a%20mean%20reduction%20in%20LBM%20of%207%E2%80%938%25%2C%20corresponding%20to%20approximately%204%20kg%20lean%20tissue%20(6).%20Subsequent%20studies%20have%20confirmed%20these%20results%20(12%2C%2014%E2%80%9316).) к тому, что мышцы атрофируются. Также сон помогает нормализовать артериальное давление. + +**Сон нужен иммунной системе.** Во сне наше дыхание замедляется, а мышцы почти неподвижны, поэтому энергия в организме может [пойти](https://www.sleepfoundation.org/physical-health/how-sleep-affects-immunity#:~:text=During%20sleep%2C%20breathing%20and%20muscle%20activity%20slows%20down%2C%20freeing%20up%20energy%20for%20the%20immune%20system%20to%20perform%20these%20critical%20tasks.) на важные иммунные задачи. Например, [активируются](https://www.sleepfoundation.org/physical-health/how-sleep-affects-immunity#:~:text=Sleep%20is%20an,off%20an%20infection.) воспалительные процессы, помогающие заживлять раны и бороться с инфекциями. [[../../../../knowledge/health/болезни/Недосып|Недосып]] же имеет обратный эффект: те, кто спят меньше семи часов, [простужаются](https://pubmed.ncbi.nlm.nih.gov/19139325/#:~:text=There%20was%20a%20graded%20association%20with%20average%20sleep%20duration%3A%20participants%20with%20less%20than%207%20hours%20of%20sleep%20were%202.94%20times%20(95%25%20confidence%20interval%20%5BCI%5D%2C%201.18%2D7.30)%20more%20likely%20to%20develop%20a%20cold%20than%20those%20with%208%20hours%20or%20more%20of%20sleep.) почти в три раза чаще, чем спящие по восемь часов. + +**Сон [формирует](https://www.pnas.org/doi/10.1073/pnas.2201795119) и закрепляет воспоминания**. Этот процесс называется [консолидация памяти](Консолидация%20памяти.md). Это подтверждается экспериментами: одна группа людей училась утром, а другая вечером. Контрольный тест показал, что чем ближе обучение ко сну, тем лучше усваивается информация. + +Еще во сне мы [продолжаем](https://now.tufts.edu/2021/02/18/new-theory-why-we-dream#:~:text=In%20essence%2C%20that%E2%80%99s,need%20of%20disruption.) искать решение проблем, которые волновали нас днем. +## Как возникает сон +![](Циркадные%20ритмы.md#^a1a364) +![](Мелатонин.md#^381eb3) +![](Шишковидная%20железа.md#^31ebf3) + +- [Фазы сна](Фазы%20сна.md) +## Что влияет на сон +- [Стресс](Стресс.md) +- Хронические заболевания +- Кофеин +- Возраст +- Принимаемые препараты +- [[../../../../knowledge/health/Физическая нагрузка|Физическая нагрузка]]. +## Заметки +- В одном эксперементе добровольцы спали не больше шести часов. Итог - время реакции на внешние факторы увеличилось в 2 раза, внимательность ухудшилась в 5 раз. + +## Дополнительные материалы +- [[../../../../_inbox/Сказки для сна|Сказки для сна]] \ No newline at end of file