Подтвердить что ты не робот

Каковы были бы правильные шаги для горизонтального разбиения в Postgresql?

У нас есть портал электронной коммерции с базой данных Postgresql 9.1. Одна очень важная таблица имеет в настоящий момент 32 миллиона записей. Если мы хотим доставить все предметы, эта таблица будет расти до 320 миллионов записей, в основном дат. Который был бы тяжелым.

Итак, мы думаем о горизонтальном разбиении/очертании. Мы можем разделить элементы в этой таблице на 12 штук по горизонтали (1 в месяц). Какими были бы лучшие шаги и техника для этого? Будет ли горизонтальное разбиение в базе данных достаточно хорошим или мы должны начать думать о том, чтобы оштрафовать?

4b9b3361

Ответ 1

В то время как 320 миллионов не являются маленькими, это также не огромно.

В основном это зависит от запросов, которые вы запускаете на столе. Если вы всегда включаете ключ раздела в свои запросы, то, вероятно, будет работать "регулярное" разбиение на разделы.

Пример для этого можно найти в вики-странице PostgreSQL:
http://wiki.postgresql.org/wiki/Month_based_partitioning

В руководстве также объясняются некоторые предостережения о разделении:
http://www.postgresql.org/docs/current/interactive/ddl-partitioning.html

Если вы задумываетесь о том, как скроллировать, вы можете прочитать, как Instagram (который работает от PostgreSQL) реализовал это:

http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram

Если у вас есть в основном запросы на чтение, другой вариант может заключаться в использовании потоковой репликации для настройки нескольких серверов и распространения запросов на чтение, подключаясь к горячим резервам для доступа на чтение и подключения к мастеру для доступа на запись. Я думаю, pg-pool II может сделать это (несколько) автоматически. Это можно объединить с разбиением на разделы для дальнейшего сокращения времени выполнения запросов.

Если вы предприимчивы и не нуждаетесь в немедленных действиях, вы можете также рассмотреть Postgres-XC, который promises поддерживает прозрачное горизонтальное масштабирование:
http://postgres-xc.sourceforge.net/

Пока нет окончательного релиза, но похоже, что это не слишком долго

Ответ 2

Вот мой пример кода для разбиения: t_master - это представление для выбора/вставки/обновления/удаления в приложении t_1 и t_2 являются базовыми таблицами, фактически хранящими данные.

create or replace view t_master(id, col1)
as 
select id, col1 from t_1
union all
select id, col1 from t_2


CREATE TABLE t_1
(
  id bigint PRIMARY KEY,
  col1 text
);

CREATE TABLE t_2
(
  id bigint PRIMARY KEY,
  col1 text
);



CREATE OR REPLACE FUNCTION t_insert_partition_function()
returns TRIGGER AS $$
begin
raise notice '%s', 'hello';
    execute 'insert into t_'
        || ( mod(NEW.id, 2)+ 1 )
        || ' values ( $1, $2 )' USING NEW.id, NEW.col1 ;
    RETURN NULL;
end;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION t_update_partition_function()
returns TRIGGER AS $$
begin
    raise notice '%s', 'hello';
    execute 'update t_'
        || ( mod(NEW.id, 2)+ 1 )
        || ' set id = $1, col1 = $2 where id = $1' 
        USING NEW.id, NEW.col1 ;
    RETURN NULL;
end;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION t_delete_partition_function()
returns TRIGGER AS $$
begin
    raise notice '%s', 'hello';
    execute 'delete from t_'
        || ( mod(OLD.id, 2)+ 1 )
        || ' where id = $1' 
        USING OLD.id;
    RETURN NULL;
end;
$$
LANGUAGE plpgsql;



CREATE TRIGGER t_insert_partition_trigger instead of INSERT
ON t_master FOR each row 
execute procedure t_insert_partition_function();

CREATE TRIGGER t_update_partition_trigger instead of update
ON t_master FOR each row 
execute procedure t_update_partition_function();

CREATE TRIGGER t_delete_partition_trigger instead of delete
ON t_master FOR each row 
execute procedure t_delete_partition_function();

Ответ 3

Если вы не возражаете перейти на PostgreSQL 9.4, вы можете использовать расширение pg_shard, которое позволяет прозрачно отображать таблицу PostgreSQL через многие машины. Каждый осколок хранится как обычная таблица PostgreSQL на другом сервере PostgreSQL и реплицируется на другие серверы. Он использует хэш-разбиение, чтобы решить, какие осколки использовать для данного запроса. pg_shard будет работать хорошо, если ваши запросы имеют естественный размер раздела (например, идентификатор клиента).

Дополнительная информация: https://github.com/citusdata/pg_shard