我们有一个带有Postgresql 9.1数据库的电子商务门户。目前有一张非常重要的表格有3200万条记录。如果我们想要交付所有物品,这个表格将增长到3.2亿条记录,大部分是日期。这将是沉重的。Postgresql中水平分区的正确步骤是什么?
所以我们正在考虑水平分区/分片。我们可以将此表中的项目分成12个水平(每月1个)。最好的步骤和技术是什么?数据库中的水平分区会不够好,还是我们不得不开始考虑分片?
我们有一个带有Postgresql 9.1数据库的电子商务门户。目前有一张非常重要的表格有3200万条记录。如果我们想要交付所有物品,这个表格将增长到3.2亿条记录,大部分是日期。这将是沉重的。Postgresql中水平分区的正确步骤是什么?
所以我们正在考虑水平分区/分片。我们可以将此表中的项目分成12个水平(每月1个)。最好的步骤和技术是什么?数据库中的水平分区会不够好,还是我们不得不开始考虑分片?
虽然3.2亿不小,但它也不是很大。
它很大程度上取决于您在表格上运行的查询。如果您始终在查询中包含分区键,那么“常规”分区可能会起作用。
http://wiki.postgresql.org/wiki/Month_based_partitioning
该手册还介绍了一些分区的需要注意的地方:
一个这样的例子可以在PostgreSQL的wiki上找到
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这将支持透明水平缩放:
http://postgres-xc.sourceforge.net/
没有最终版本还没有,但它看起来像这不是花太长的时间
这里是我的示例代码分区: 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();
如果你不介意升级到PostgreSQL 9.4,那么你可以使用pg_shard extension,它可以让你透明多台机器一个分片表的PostgreSQL。每个分片都作为普通PostgreSQL表存储在另一台PostgreSQL服务器上,并复制到其他服务器上。它使用散列分区来决定给定查询使用哪个分片。如果您的查询具有自然分区维度(例如客户ID),则pg_shard可以很好地工作。
非常感谢您的宝贵意见! – Brambo76 2012-04-21 07:24:27
+1非常丰富! – 2012-04-21 13:16:20
就像数据点一样,我们的商店在我们访问量最大的表格中有超过3亿行,没有分区或分片,并且工作正常。重申一些上述内容,使分区有价值的关键因素是有一个分区键,通常用于限制查询中感兴趣的行,并希望定期删除整个分区。 (删除分区要比删除1/12行更快。) – kgrittn 2012-04-21 14:29:52