數據模型
Greenplum數據庫是一種shared nothing的分析型MPP數據庫。這種模型與高度規范化的/事務型的SMP數據庫有顯著區別。Greenplum數據庫使用非規范化的模式設計會工作得最好,非規范化的模式適合於MPP分析型處理,例如帶有大型事實表和較小維度表的星形模式或者雪花模式。
對表中用於連接的列使用相同的數據類型。
堆存儲 vs. 追加優化存儲
對將會接收迭代批量或者單一UPDATE、DELETE以及INSERT操作的表和分區使用堆存儲。
對將會接收並發UPDATE、DELETE以及INSERT操作的表和分區使用堆存儲。
對於在初始裝載后很少更新並且只會在大型批處理操作中進行后續插入的表和分區,使用追加優化存儲。
絕不在追加優化表上執行單個INSERT、UPDATE或者DELETE操作。
絕不在追加優化表上執行並發的批量UPDATE或DELETE操作。可以執行並發的批量INSERT操作。
行存 vs. 列存
如果負載中有要求更新並且頻繁執行插入的迭代事務,則對這種負載使用行存。
在對寬表選擇時使用行存。
為一般目的或混合負載使用行存。
選擇面很窄(很少的列)和在少量列上計算數據聚集時使用列存。
如果表中有單個列定期被更新而不修改行中的其他列,則對這種表使用列存。
壓縮
在大型追加優化和分區表上使用壓縮以改進系統范圍的I/O。
在數據位於的級別上設置列壓縮設置。
在較高的壓縮級別和壓縮解壓數據所需的時間和CPU周期之間做出平衡。
分布
為所有的表顯式定義一個列分布或者隨機分布。不要使用默認值。
使用將在所有Segment間均勻分布的單列。
不要在查詢的WHERE子句中用到的列上進行分布。
不要在日期或時間戳上分布。
不要在同一列上分布並且分區表。
在常被連接起來的大型表的相同列上進行分布以顯著地改進本地連接。
在初始裝載數據以及增量裝載數據之后驗證數據被均勻分布。
根本上確保沒有數據傾斜!
內存管理
把vm.overcommit_memory設置為2。
不要配置OS使用大頁。
使用gp_vmem_protect_limit設置實例可以為每個Segment數據庫中執行的所有工作分配的最大內存。
通過下面的計算為gp_vmem_protect_limit設置值:
gp_vmem – Greenplum數據庫可用的總內存
其中 SWAP是該主機的交換空間(以GB為單位),RAM是該主機的RAM(以GB為單位)
max_acting_primary_segments – 當鏡像Segment由於主機或者Segment失效而被激活時,能在一台主機上運行的最主Segment的最大數量
gp_vmem_protect_limit
轉換成MB來設置配置參數的值。
在有大量工作文件被生成的場景下用下面的公式計算將工作文件考慮在內的gp_vmem因子:
絕不將gp_vmem_protect_limit設置得過高或者比系統上的物理RAM大。
使用計算出的gp_vmem值來計算操作系統參數vm.overcommit_ratio的設置:
使用statement_mem來分配每個Segment數據庫中用於一個查詢的內存。
使用資源隊列設置活動查詢的數目(ACTIVE_STATEMENTS)以及隊列中查詢所能利用的內存量(MEMORY_LIMIT)。
把所有的用戶都與一個資源隊列關聯。不要使用默認的隊列。
設置PRIORITY以匹配用於負載以及實際情況的隊列的實際需要。
確保資源隊列的內存分配不會超過gp_vmem_protect_limit的設置。
動態更新資源隊列設置以匹配日常操作流。
分區
只對大型表分區。不要分區小表。
只有能基於查詢條件實現分區消除(分區剪枝)時才使用分區。
選擇范圍分區而舍棄列表分區。
基於查詢謂詞對表分區。
不要在同一列上對表進行分布和分區。
不要使用默認分區。
不要使用多級分區,創建較少的分區讓每個分區中有更多數據。
通過檢查查詢的EXPLAIN計划驗證查詢有選擇地掃描分區表(分區被消除)。
不要用列存儲創建太多分區,因為每個Segment上的物理文件總數:物理文件數 = Segment數 x 列數 x 分區數
索引
通常在Greenplum數據庫中無需索引。
對高基數的表在列式表的單列上創建索引用於鑽透目的要求查詢具有較高的選擇度。
不要索引被頻繁更新的列。
總是在裝載數據到表之前刪除索引。在裝載后,重新為該表創建索引。
創建具有選擇性的B-樹索引。
不要在被更新的列上創建位圖索引。
不要為唯一列、基數非常高或者非常低的數據使用位圖索引。
不要為事務性負載使用位圖索引。
通常不要索引分區表。如果需要索引,索引列必須與分區列不同。
資源隊列
使用資源隊列來管理集群上的負載。
將所有的角色都與一個用戶定義的資源隊列關聯。
使用ACTIVE_STATEMENTS參數限制特定隊列的成員能並發運行的活動查詢數量。
使用MEMORY_LIMIT參數控制通過隊列運行的查詢所能利用的總內存量。
不要把所有隊列都設置為MEDIUM,因為這實際上沒有對負載進行管理。
動態修改資源隊列以匹配負載以及現狀。
監控和維護
實現Greenplum數據庫管理員指南中的"推薦的監控和維護任務"。
安裝時運行gpcheckperf並且在之后定期運行該工具,保存其輸出用來比較系統性能隨時間的變化。
使用手頭的所有工具來理解系統在不同負載下的表現。
檢查任何異常事件以判斷成因。
通過定期運行解釋計划監控查詢活動以確保查詢被以最優的方式運行。
檢查計划以判斷索引是否被使用以及分區消除是否按照預期發生。
了解系統日志文件的位置和內容並且定期監控它們,而不是只在問題出現時才去檢查日志。
ANALYZE
不要在整個數據庫上運行ANALYZE。需要時,有選擇地在表級別上運行ANALYZE。
在裝載后總是運行ANALYZE。
在顯著改變底層數據的INSERT、UPDATE以及DELETE操作之后總是運行ANALYZE。
在CREATE INDEX操作之后總是運行ANALYZE。
如果在非常大的表上運行ANALYZE需要太長時間,可以只在用於連接條件、WHERE子句、SORT子句、GROUP BY子句或者HAVING子句的列上運行ANALYZE。
清掃
在大型UPDATE和DELETE操作后運行VACUUM。
不要運行VACUUM FULL。而是運行一個CREATE TABLE...AS操作,然后重命名並且刪掉原始表。
頻繁地在系統目錄上運行VACUUM以避免目錄膨脹以及在目錄上運行VACUUM FULL的需要。
絕不要殺掉目錄表上的VACUUM。
不要運行VACUUM ANALYZE。
裝載
使用gpfdist在Greenplum數據庫中裝載或者卸載數據。
隨着Segment數目增加最大化並行性。
在盡可能多的ETL節點上均勻散布數據。
把非常大型的數據文件分割成相等的部分,並且把數據散布在盡可能多的文件系統上。
每個文件系統運行兩個gpfdist實例。
在盡可能多的接口上運行gpfdist。
使用gp_external_max_segs以控制每個gpfdist服務的Segment數量。
總是保持gp_external_max_segs和gpfdist進程的數量為偶因子。
在裝載到現有表之前總是刪除索引並且在裝載之后重建索引。
總是在對表裝載之后運行ANALYZE。
在裝載期間通過設置gp_autostats_mode為NONE禁用自動統計信息收集。
在裝載錯誤之后運行VACUUM以重新獲得空間。
gptransfer
為了最快的傳輸率,使用gptransfer傳輸數據到尺寸相同或者更大的目標數據庫。
避免使用--full或--schema-only選項。而是使用不同的方法將模式復制到目標數據庫中,然后傳輸表數據。
在傳輸表之前刪除索引並且在傳輸完成后重建它們。
使用SQL的COPY命令傳輸較小的表到目標數據庫。
使用gptransfer批量傳輸較大的表。
在執行生產遷移之前,先測試運行gptransfer。用--batch-size和--sub-batch-size選項進行實驗以得到最大並行性。為迭代運行gptransfer確定合適的表批次。
只使用完全限定的表名稱。表名中的點號(.)、空格、引號(')和雙引號(")都可能造成問題。
如果使用--validation選項在傳輸后驗證數據,確定也使用-x選項在源表上放置排他鎖。
確保在目標數據庫上創建每一個角色、函數和資源隊列。當使用gptransfer -t選項時,這些對象不會被會傳輸。
將postgres.conf和pg_hba.conf配置文件從源集群拷貝到目標集群。
在目標數據庫中用gppkg安裝所需的擴展。
安全性
保護gpadmin用戶ID並且只允許對它進行必需的系統管理員訪問。
在執行特定的系統維護任務(例如升級或者擴張)時,管理員只應作為gpadmin登入到Greenplum。
限制具有SUPERUSER角色屬性的用戶。成為超級用戶的角色能繞過Greenplum數據庫中的所有訪問特權檢查以及資源隊列。只有系統管理員應該被給予超級用戶的權力。請見Greenplum數據庫管理員指南中的“修改角色屬性”。
數據庫用戶絕不應該以gpadmin登錄,且ETL或者生產負載也絕不應該以gpadmin運行。
為每個登入的用戶分派一個不同的角色。
對於應用或者Web服務,考慮為每個應用或服務創建一個不同的角色。
使用組管理訪問特權。
保護root口令。
為操作系統口令強制一種強口令策略。
確保重要的操作系統文件受到保護。
加密
加密和解密數據需要性能作為代價,只加密需要加密的數據。
在生產系統中實現任何加密方案之前,先執行性能測試。
生產Greenplum數據庫系統中的服務器證書應該由一個數字證書認證機構(CA)簽發,這樣客戶端可以認證該服務器。如果客戶端都是機構中的本地客戶端,CA可以是本地的。
只要客戶端到Greenplum數據庫的連接會通過不安全的鏈接,就應該對其使用SSL加密。
對稱加密方案(加密和解密使用同樣的密鑰)具有比非對稱方案更好的性能,因此在密鑰能被安全共享時應當使用對稱加密方案。
使用pgcrypto包中的函數來加密磁盤上的數據。數據在數據庫進程中被加密和解密,因此有必要用SSL保護客戶端連接以避免傳輸未加密數據。
在ETL數據被裝載到數據庫中或者從數據庫中卸載時,是用gpfdists協議加密它。
高可用性
使用帶有8至24個磁盤的硬件RAID存儲方案。
使用RAID 1、5或6,這樣磁盤陣列能容忍一個失效的磁盤。
在磁盤陣列中配置一個熱后備以允許在檢測到磁盤失效時自動開始重建。
通過鏡像RAID卷防止重建時整個磁盤陣列失效和退化。
定期監控磁盤使用並且在需要時增加額外的空間。
監控Segment傾斜以確保數據被平均地分布並且在所有Segment上存儲被平均地消耗。
設置一個后備Master以便在主Master失效后接管。
規划當失效發生時,如何把客戶端切換到新的Master實例,例如,通過更新DNS中的Master地址。
設置監控機制以便在主Master失效時在系統監控應用中或者通過email發出通知。
為所有的Segment設置鏡像。
將主Segment和它們的鏡像放置在不同的主機上以預防主機失效。
設置監控機制以便在主Segment失效時在系統監控應用中或者通過email發出通知。
迅速地使用gprecoverseg工具失效的Segment,以便恢復冗余並且讓系統回到最佳平衡。
配置Greenplum數據庫發送SNMP通知給網絡監控器。
在$MASTER_DATA_DIRECTORY/postgresql.conf配置文件中設置email通知,這樣Greenplum系統可以在檢測到嚴重問題時用email通知管理員。
考慮雙集群配置以提供額外層次上的冗余以及額外的查詢處理吞吐。
除非數據庫可以很容易地從來源恢復,定期備份Greenplum數據庫。
如果堆表相對較小並且兩次備份之間只有很少的追加優化或列存分區被修改,使用增量備份。
如果備份被保存到本地集群存儲上,在備份完成后將這些文件移動到一個安全的、不在集群上的位置。
如果備份被保存到NFS掛載點,使用例如Dell EMC Isilon之類的橫向擴展NFS方案以避免IO瓶頸。
考慮使用Greenplum集成將備份流式傳送給Dell EMC Data Domain或者 Veritas NetBackup企業級備份平台。
---恢復內容結束---
數據模型
Greenplum數據庫是一種shared nothing的分析型MPP數據庫。這種模型與高度規范化的/事務型的SMP數據庫有顯著區別。Greenplum數據庫使用非規范化的模式設計會工作得最好,非規范化的模式適合於MPP分析型處理,例如帶有大型事實表和較小維度表的星形模式或者雪花模式。
對表中用於連接的列使用相同的數據類型。
堆存儲 vs. 追加優化存儲
對將會接收迭代批量或者單一UPDATE、DELETE以及INSERT操作的表和分區使用堆存儲。
對將會接收並發UPDATE、DELETE以及INSERT操作的表和分區使用堆存儲。
對於在初始裝載后很少更新並且只會在大型批處理操作中進行后續插入的表和分區,使用追加優化存儲。
絕不在追加優化表上執行單個INSERT、UPDATE或者DELETE操作。
絕不在追加優化表上執行並發的批量UPDATE或DELETE操作。可以執行並發的批量INSERT操作。
行存 vs. 列存
如果負載中有要求更新並且頻繁執行插入的迭代事務,則對這種負載使用行存。
在對寬表選擇時使用行存。
為一般目的或混合負載使用行存。
選擇面很窄(很少的列)和在少量列上計算數據聚集時使用列存。
如果表中有單個列定期被更新而不修改行中的其他列,則對這種表使用列存。
壓縮
在大型追加優化和分區表上使用壓縮以改進系統范圍的I/O。
在數據位於的級別上設置列壓縮設置。
在較高的壓縮級別和壓縮解壓數據所需的時間和CPU周期之間做出平衡。
分布
為所有的表顯式定義一個列分布或者隨機分布。不要使用默認值。
使用將在所有Segment間均勻分布的單列。
不要在查詢的WHERE子句中用到的列上進行分布。
不要在日期或時間戳上分布。
不要在同一列上分布並且分區表。
在常被連接起來的大型表的相同列上進行分布以顯著地改進本地連接。
在初始裝載數據以及增量裝載數據之后驗證數據被均勻分布。
根本上確保沒有數據傾斜!
內存管理
把vm.overcommit_memory設置為2。
不要配置OS使用大頁。
使用gp_vmem_protect_limit設置實例可以為每個Segment數據庫中執行的所有工作分配的最大內存。
通過下面的計算為gp_vmem_protect_limit設置值:
gp_vmem – Greenplum數據庫可用的總內存
其中 SWAP是該主機的交換空間(以GB為單位),RAM是該主機的RAM(以GB為單位)
max_acting_primary_segments – 當鏡像Segment由於主機或者Segment失效而被激活時,能在一台主機上運行的最主Segment的最大數量
gp_vmem_protect_limit
轉換成MB來設置配置參數的值。
在有大量工作文件被生成的場景下用下面的公式計算將工作文件考慮在內的gp_vmem因子:
絕不將gp_vmem_protect_limit設置得過高或者比系統上的物理RAM大。
使用計算出的gp_vmem值來計算操作系統參數vm.overcommit_ratio的設置:
使用statement_mem來分配每個Segment數據庫中用於一個查詢的內存。
使用資源隊列設置活動查詢的數目(ACTIVE_STATEMENTS)以及隊列中查詢所能利用的內存量(MEMORY_LIMIT)。
把所有的用戶都與一個資源隊列關聯。不要使用默認的隊列。
設置PRIORITY以匹配用於負載以及實際情況的隊列的實際需要。
確保資源隊列的內存分配不會超過gp_vmem_protect_limit的設置。
動態更新資源隊列設置以匹配日常操作流。
分區
只對大型表分區。不要分區小表。
只有能基於查詢條件實現分區消除(分區剪枝)時才使用分區。
選擇范圍分區而舍棄列表分區。
基於查詢謂詞對表分區。
不要在同一列上對表進行分布和分區。
不要使用默認分區。
不要使用多級分區,創建較少的分區讓每個分區中有更多數據。
通過檢查查詢的EXPLAIN計划驗證查詢有選擇地掃描分區表(分區被消除)。
不要用列存儲創建太多分區,因為每個Segment上的物理文件總數:物理文件數 = Segment數 x 列數 x 分區數
索引
通常在Greenplum數據庫中無需索引。
對高基數的表在列式表的單列上創建索引用於鑽透目的要求查詢具有較高的選擇度。
不要索引被頻繁更新的列。
總是在裝載數據到表之前刪除索引。在裝載后,重新為該表創建索引。
創建具有選擇性的B-樹索引。
不要在被更新的列上創建位圖索引。
不要為唯一列、基數非常高或者非常低的數據使用位圖索引。
不要為事務性負載使用位圖索引。
通常不要索引分區表。如果需要索引,索引列必須與分區列不同。
資源隊列
使用資源隊列來管理集群上的負載。
將所有的角色都與一個用戶定義的資源隊列關聯。
使用ACTIVE_STATEMENTS參數限制特定隊列的成員能並發運行的活動查詢數量。
使用MEMORY_LIMIT參數控制通過隊列運行的查詢所能利用的總內存量。
不要把所有隊列都設置為MEDIUM,因為這實際上沒有對負載進行管理。
動態修改資源隊列以匹配負載以及現狀。
監控和維護
實現Greenplum數據庫管理員指南中的"推薦的監控和維護任務"。
安裝時運行gpcheckperf並且在之后定期運行該工具,保存其輸出用來比較系統性能隨時間的變化。
使用手頭的所有工具來理解系統在不同負載下的表現。
檢查任何異常事件以判斷成因。
通過定期運行解釋計划監控查詢活動以確保查詢被以最優的方式運行。
檢查計划以判斷索引是否被使用以及分區消除是否按照預期發生。
了解系統日志文件的位置和內容並且定期監控它們,而不是只在問題出現時才去檢查日志。
ANALYZE
不要在整個數據庫上運行ANALYZE。需要時,有選擇地在表級別上運行ANALYZE。
在裝載后總是運行ANALYZE。
在顯著改變底層數據的INSERT、UPDATE以及DELETE操作之后總是運行ANALYZE。
在CREATE INDEX操作之后總是運行ANALYZE。
如果在非常大的表上運行ANALYZE需要太長時間,可以只在用於連接條件、WHERE子句、SORT子句、GROUP BY子句或者HAVING子句的列上運行ANALYZE。
清掃
在大型UPDATE和DELETE操作后運行VACUUM。
不要運行VACUUM FULL。而是運行一個CREATE TABLE...AS操作,然后重命名並且刪掉原始表。
頻繁地在系統目錄上運行VACUUM以避免目錄膨脹以及在目錄上運行VACUUM FULL的需要。
絕不要殺掉目錄表上的VACUUM。
不要運行VACUUM ANALYZE。
裝載
使用gpfdist在Greenplum數據庫中裝載或者卸載數據。
隨着Segment數目增加最大化並行性。
在盡可能多的ETL節點上均勻散布數據。
把非常大型的數據文件分割成相等的部分,並且把數據散布在盡可能多的文件系統上。
每個文件系統運行兩個gpfdist實例。
在盡可能多的接口上運行gpfdist。
使用gp_external_max_segs以控制每個gpfdist服務的Segment數量。
總是保持gp_external_max_segs和gpfdist進程的數量為偶因子。
在裝載到現有表之前總是刪除索引並且在裝載之后重建索引。
總是在對表裝載之后運行ANALYZE。
在裝載期間通過設置gp_autostats_mode為NONE禁用自動統計信息收集。
在裝載錯誤之后運行VACUUM以重新獲得空間。
gptransfer
為了最快的傳輸率,使用gptransfer傳輸數據到尺寸相同或者更大的目標數據庫。
避免使用--full或--schema-only選項。而是使用不同的方法將模式復制到目標數據庫中,然后傳輸表數據。
在傳輸表之前刪除索引並且在傳輸完成后重建它們。
使用SQL的COPY命令傳輸較小的表到目標數據庫。
使用gptransfer批量傳輸較大的表。
在執行生產遷移之前,先測試運行gptransfer。用--batch-size和--sub-batch-size選項進行實驗以得到最大並行性。為迭代運行gptransfer確定合適的表批次。
只使用完全限定的表名稱。表名中的點號(.)、空格、引號(')和雙引號(")都可能造成問題。
如果使用--validation選項在傳輸后驗證數據,確定也使用-x選項在源表上放置排他鎖。
確保在目標數據庫上創建每一個角色、函數和資源隊列。當使用gptransfer -t選項時,這些對象不會被會傳輸。
將postgres.conf和pg_hba.conf配置文件從源集群拷貝到目標集群。
在目標數據庫中用gppkg安裝所需的擴展。
安全性
保護gpadmin用戶ID並且只允許對它進行必需的系統管理員訪問。
在執行特定的系統維護任務(例如升級或者擴張)時,管理員只應作為gpadmin登入到Greenplum。
限制具有SUPERUSER角色屬性的用戶。成為超級用戶的角色能繞過Greenplum數據庫中的所有訪問特權檢查以及資源隊列。只有系統管理員應該被給予超級用戶的權力。請見Greenplum數據庫管理員指南中的“修改角色屬性”。
數據庫用戶絕不應該以gpadmin登錄,且ETL或者生產負載也絕不應該以gpadmin運行。
為每個登入的用戶分派一個不同的角色。
對於應用或者Web服務,考慮為每個應用或服務創建一個不同的角色。
使用組管理訪問特權。
保護root口令。
為操作系統口令強制一種強口令策略。
確保重要的操作系統文件受到保護。
加密
加密和解密數據需要性能作為代價,只加密需要加密的數據。
在生產系統中實現任何加密方案之前,先執行性能測試。
生產Greenplum數據庫系統中的服務器證書應該由一個數字證書認證機構(CA)簽發,這樣客戶端可以認證該服務器。如果客戶端都是機構中的本地客戶端,CA可以是本地的。
只要客戶端到Greenplum數據庫的連接會通過不安全的鏈接,就應該對其使用SSL加密。
對稱加密方案(加密和解密使用同樣的密鑰)具有比非對稱方案更好的性能,因此在密鑰能被安全共享時應當使用對稱加密方案。
使用pgcrypto包中的函數來加密磁盤上的數據。數據在數據庫進程中被加密和解密,因此有必要用SSL保護客戶端連接以避免傳輸未加密數據。
在ETL數據被裝載到數據庫中或者從數據庫中卸載時,是用gpfdists協議加密它。
高可用性
使用帶有8至24個磁盤的硬件RAID存儲方案。
使用RAID 1、5或6,這樣磁盤陣列能容忍一個失效的磁盤。
在磁盤陣列中配置一個熱后備以允許在檢測到磁盤失效時自動開始重建。
通過鏡像RAID卷防止重建時整個磁盤陣列失效和退化。
定期監控磁盤使用並且在需要時增加額外的空間。
監控Segment傾斜以確保數據被平均地分布並且在所有Segment上存儲被平均地消耗。
設置一個后備Master以便在主Master失效后接管。
規划當失效發生時,如何把客戶端切換到新的Master實例,例如,通過更新DNS中的Master地址。
設置監控機制以便在主Master失效時在系統監控應用中或者通過email發出通知。
為所有的Segment設置鏡像。
將主Segment和它們的鏡像放置在不同的主機上以預防主機失效。
設置監控機制以便在主Segment失效時在系統監控應用中或者通過email發出通知。
迅速地使用gprecoverseg工具失效的Segment,以便恢復冗余並且讓系統回到最佳平衡。
配置Greenplum數據庫發送SNMP通知給網絡監控器。
在$MASTER_DATA_DIRECTORY/postgresql.conf配置文件中設置email通知,這樣Greenplum系統可以在檢測到嚴重問題時用email通知管理員。
考慮雙集群配置以提供額外層次上的冗余以及額外的查詢處理吞吐。
除非數據庫可以很容易地從來源恢復,定期備份Greenplum數據庫。
如果堆表相對較小並且兩次備份之間只有很少的追加優化或列存分區被修改,使用增量備份。
如果備份被保存到本地集群存儲上,在備份完成后將這些文件移動到一個安全的、不在集群上的位置。
如果備份被保存到NFS掛載點,使用例如Dell EMC Isilon之類的橫向擴展NFS方案以避免IO瓶頸。
考慮使用Greenplum集成將備份流式傳送給Dell EMC Data Domain或者 Veritas NetBackup企業級備份平台。