2012-04-21 41 views
13

我們有一個帶有Postgresql 9.1數據庫的電子商務門戶。目前有一張非常重要的表格有3200萬條記錄。如果我們想要交付所有物品,這個表格將增長到3.2億條記錄,大部分是日期。這將是沉重的。Postgresql中水平分區的正確步驟是什麼?

所以我們正在考慮水平分區/分片。我們可以將此表中的項目分成12個水平(每月1個)。最好的步驟和技術是什麼?數據庫中的水平分區會不夠好,還是我們不得不開始考慮分片?

回答

24

雖然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/

沒有最終版本還沒有,但它看起來像這不是花太長的時間

+1

非常感謝您的寶貴意見! – Brambo76 2012-04-21 07:24:27

+0

+1非常豐富! – 2012-04-21 13:16:20

+5

就像數據點一樣,我們的商店在我們訪問量最大的表格中有超過3億行,沒有分區或分片,並且工作正常。重申一些上述內容,使分區有價值的關鍵因素是有一個分區鍵,通常用於限制查詢中感興趣的行,並希望定期刪除整個分區。 (刪除分區要比刪除1/12行更快。) – kgrittn 2012-04-21 14:29:52

1

這裏是我的示例代碼分區: 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(); 
1

如果你不介意升級到PostgreSQL 9.4,那麼你可以使用pg_shard extension,它可以讓你透明多臺機器一個分片表的PostgreSQL。每個分片都作爲普通PostgreSQL表存儲在另一臺PostgreSQL服務器上,並複製到其他服務器上。它使用散列分區來決定給定查詢使用哪個分片。如果您的查詢具有自然分區維度(例如客戶ID),則pg_shard可以很好地工作。

更多信息:https://github.com/citusdata/pg_shard