This repository has been archived by the owner on May 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 71
/
postgresql_clustering.tex
52 lines (35 loc) · 6.94 KB
/
postgresql_clustering.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
\chapter{Шардинг}
\begin{epigraphs}
\qitem{Если ешь слона, не пытайся запихать его в рот целиком}{Народная мудрость}
\end{epigraphs}
\section{Введение}
Шардинг~--- разделение данных на уровне ресурсов. Концепция шардинга заключается в логическом разделении данных по различным ресурсам, исходя из требований к нагрузке.
Рассмотрим пример. Пусть у нас есть приложение с регистрацией пользователей, которое позволяет писать друг другу личные сообщения. Допустим оно очень популярно, и много людей им пользуются ежедневно. Естественно, что таблица с личными сообщениями будет намного больше всех остальных таблиц в базе (скажем, будет занимать 90\% всех ресурсов). Зная это, мы можем подготовить для этой (только одной!) таблицы выделенный сервер помощнее, а остальные оставить на другом (послабее). Теперь мы можем идеально подстроить сервер для работы с одной специфической таблицей, постараться уместить ее в память, возможно, дополнительно партиционировать ее и~т.~д. Такое распределение называется вертикальным шардингом.
Что делать, если наша таблица с сообщениями стала настолько большой, что даже выделенный сервер под нее одну уже не спасает? Необходимо делать горизонтальный шардинг~--- т.~е. разделение одной таблицы по разным ресурсам. Как это выглядит на практике? На разных серверах у нас будет таблица с одинаковой структурой, но разными данными. Для нашего случая с сообщениями, мы можем хранить первые 10 миллионов сообщений на одном сервере, вторые 10 - на втором и~т.~д. Т.~е. необходимо иметь критерий шардинга~--- какой-то параметр, который позволит определить, на каком именно сервере лежат те или иные данные.
Обычно, в качестве параметра шардинга выбирают ID пользователя (\lstinline!user_id!)~--- это позволяет делить данные по серверам равномерно и просто. Т.о. при получении личных сообщений пользователей алгоритм работы будет такой:
\begin{itemize}
\item Определить, на каком сервере БД лежат сообщения пользователя, исходя из \lstinline!user_id!;
\item Инициализировать соединение с этим сервером;
\item Выбрать сообщения;
\end{itemize}
Задачу определения конкретного сервера можно решать двумя путями:
\begin{itemize}
\item Хранить в одном месте хеш-таблицу с соответствиями <<пользователь=сервер>>. Тогда, при определении сервера, нужно будет выбрать сервер из этой таблицы. В этом случае узкое место~--- это большая таблица соответствия, которую нужно хранить в одном месте. Для таких целей очень хорошо подходят базы данных <<ключ=значение>>;
\item Определять имя сервера с помощью числового (буквенного) преобразования. Например, можно вычислять номер сервера, как остаток от деления на определенное число (количество серверов, между которыми Вы делите таблицу). В этом случае узкое место~--- это проблема добавления новых серверов~--- придется делать перераспределение данных между новым количеством серверов;
\end{itemize}
Естественно, делая горизонтальный шардинг, Вы ограничиваете себя в возможности выборок, которые требуют пересмотра всей таблицы (например, последние посты в блогах людей будет достать невозможно, если таблица постов шардится). Такие задачи придется решать другими подходами. Например, для описанного примера, можно при появлении нового поста, заносить его ID в общий стек, размером в 100 элементом.
Горизонтальный шардинг имеет одно явное преимущество~--- он бесконечно масштабируем. Для создания шардинга PostgreSQL существует несколько решений:
\begin{itemize}
\item \href{http://postgres-xc.sourceforge.net/}{Postgres-XC}
\item \href{http://www.greenplum.com/products/greenplum-database}{Greenplum Database}
\item \href{https://github.com/citusdata/citus}{Citus}
\item \href{http://plproxy.projects.postgresql.org/doc/tutorial.html}{PL/Proxy}
\item \href{https://launchpad.net/stado}{Stado (sequel to GridSQL)}
\end{itemize}
\input{clustering/plproxy}
\input{clustering/postgres_x2}
\input{clustering/postgres_xl}
\input{clustering/citus}
\input{clustering/greenplum}
\section{Заключение}
В данной главе рассмотрены лишь базовые настройки кластеров БД. Про кластеры PostgreSQL потребуется написать отдельную книгу, чтобы рассмотреть все шаги с установкой, настройкой и работой кластеров. Надеюсь, что несмотря на это, информация будет полезна многим читателям.