ADBPGGreenplum成本优化之磁盘水位管理
簡介:本文我們將通過一個實際的磁盤空間優(yōu)化案例來說明,如何幫助客戶做成本優(yōu)化。
作者 | 玉翮
來源 | 阿里技術(shù)公眾號
一 背景描述
目前,企業(yè)的核心數(shù)據(jù)一般都以二維表的方式存儲在數(shù)據(jù)庫中。在核心技術(shù)自主可控的大環(huán)境下,政企行業(yè)客戶都在紛紛嘗試使用國產(chǎn)數(shù)據(jù)庫或開源數(shù)據(jù)庫,尤其在數(shù)據(jù)倉庫OLAP領(lǐng)域的步伐更快,Greenplum的應(yīng)用越來越廣泛,阿里云ADB PG的市場機會也越來越多。另外,隨著近年來數(shù)據(jù)中臺的價值被廣泛認可,企業(yè)建設(shè)數(shù)據(jù)中臺的需求也非常迫切,數(shù)據(jù)中臺的很多場景都會用到Greenplum或ADB PG。因此,今年阿里云使用ADB PG幫助很多客戶升級了核心數(shù)倉。我們發(fā)現(xiàn),客戶往往比較關(guān)注使用云原生數(shù)倉的成本。究竟如何幫助客戶節(jié)約成本,便值得我們?nèi)ヌ剿骱吐涞亍?/p>
ADB PG全稱云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版,它是一款大規(guī)模并行處理(MPP)架構(gòu)的數(shù)據(jù)庫,是阿里云基于開源Greenplum優(yōu)化后的云原生數(shù)據(jù)倉庫,因此本文探討的成本優(yōu)化方法也適用于Greenplum開源版。圖1是ADB PG的架構(gòu)示意圖(Greenplum亦如此),Master負責(zé)接受連接請求,SQL解析、優(yōu)化、事務(wù)等處理,并分發(fā)任務(wù)到Segment執(zhí)行;并協(xié)調(diào)每一個Segment返回的結(jié)果以及把最終結(jié)果呈現(xiàn)給客戶端程序。Segment是一個獨立的PostgreSQL數(shù)據(jù)庫,負責(zé)業(yè)務(wù)數(shù)據(jù)的存儲和計算,每個Segment位于不同的獨立物理機上,存儲業(yè)務(wù)數(shù)據(jù)的不同部分,多個Segment組成計算集群;集群支持橫向擴展。從架構(gòu)上很清楚,節(jié)約Greenplum的成本,最重要的是要盡可能節(jié)約Segment的服務(wù)器數(shù),但既要保證整體MPP的算力,也要能滿足數(shù)據(jù)對存儲空間的需求。通常,數(shù)據(jù)倉庫中的數(shù)據(jù)是從企業(yè)各個領(lǐng)域的上游生產(chǎn)系統(tǒng)同步而來,這些數(shù)據(jù)在分析領(lǐng)域有生命周期,很多數(shù)據(jù)需要反應(yīng)歷史變化,因此數(shù)據(jù)倉庫中數(shù)據(jù)的特點是來源多、歷史數(shù)據(jù)多、數(shù)據(jù)量比較大。數(shù)據(jù)量大,必然消耗存儲空間,在MPP架構(gòu)下就是消耗服務(wù)器成本。幫客戶優(yōu)化成本,節(jié)約存儲空間是首當其沖的。
圖1:ADB PG的架構(gòu)示意圖
下面,我們將通過一個實際的磁盤空間優(yōu)化案例來說明,如何幫助客戶做成本優(yōu)化。
二 ADB PG & Greenplum的磁盤管理簡介
1 ADB PG磁盤管理的關(guān)鍵技術(shù)點
ADB PG是基于Greenplum(簡稱“GP”)內(nèi)核修改的MPP數(shù)據(jù)庫,對于磁盤空間管理來講,有幾個技術(shù)點與Greenplum是通用的:
(1)業(yè)務(wù)數(shù)據(jù)主要分布在Segment節(jié)點;
(2)Segment有Primary和Mirror節(jié)點,因此,業(yè)務(wù)可用空間是服務(wù)器總空間的1/2;
(3)Greenplum的MVCC機制,導(dǎo)致表數(shù)據(jù)發(fā)生DML后產(chǎn)生垃圾數(shù)據(jù)dead tuples;
(4)復(fù)制表(全分布表)會在每個Segment上存儲相同的數(shù)據(jù)拷貝;分布表會根據(jù)分布鍵打散存儲數(shù)據(jù)到各個Segment。
(5)Greenplum有Append Only類型的表,支持壓縮存儲,可以節(jié)約空間;當然用戶訪問時,解壓縮需要時間,所以需要在性能和空間之間取得平衡。
云原生數(shù)據(jù)庫的特點是不再單獨提供數(shù)據(jù)庫存儲和計算的內(nèi)核,也會配套運維管理平臺,簡稱“數(shù)據(jù)庫管控”。搞清楚ADB PG磁盤管理原理后,我們需要了解數(shù)據(jù)庫管控在磁盤水位管理方面的設(shè)計。
2 數(shù)據(jù)庫管控的磁盤預(yù)留機制
我們看下某數(shù)倉實驗環(huán)境的各個Segment節(jié)點的磁盤占用示意圖。
圖2:Segment維度的磁盤占用示意圖
上圖第一個百分比是Segment所在物理機的磁盤使用百分比;第二個百分比是數(shù)據(jù)庫管控的磁盤使用百分比。管控的數(shù)據(jù)為啥要跟服務(wù)器實際占用不一致呢?其實就是水位管理中第一個很重要的預(yù)防性措施:空間預(yù)留。即,ADB的管控在創(chuàng)建Segment實例時,根據(jù)服務(wù)器的空間,進行了一定的預(yù)留,占比大概是12%,即20T的服務(wù)器,管控認為業(yè)務(wù)最大可用17.6T,這個邏輯會通知監(jiān)控系統(tǒng)。所以計算磁盤占比時,監(jiān)控系統(tǒng)的分母不是20T,而是17.6T。這是第一級保護措施。
預(yù)留空間,還有重要的一點原因是數(shù)據(jù)庫本身有WAL事務(wù)日志、錯誤日志等也占用空間。因此,磁盤的空間有一部分需要給日志使用,客戶的業(yè)務(wù)數(shù)據(jù)無法使用100%的服務(wù)器空間,這就是為何圖2中,會顯示兩個空間百分比的原因。
3 數(shù)據(jù)庫管控的“鎖定寫” 保護機制
第二級保護措施是“磁盤滿鎖定寫”。在17.6T的基礎(chǔ)上,管控并不讓業(yè)務(wù)完全寫滿,寫滿容易造成數(shù)據(jù)文件損壞,帶來數(shù)據(jù)庫宕機及無法恢復(fù)的災(zāi)難。因此,這里有第二個閾值,即當磁盤寫到90%時,數(shù)據(jù)庫管控的自動巡檢任務(wù)會啟動“鎖定寫”的操作,此時所有請求ADB的DML都會失敗。這是一個重要的保護機制。如下圖3所示,如果達到閾值,會提示“need to lock”。 閾值可以配置,如果磁盤空間緊張,可以根據(jù)實際情況適當調(diào)大閾值。
圖3:數(shù)據(jù)庫管控的自動化鎖盤日志示例
以上數(shù)據(jù)庫管控的兩個機制可以有效保障磁盤在安全水位下運行。這些設(shè)計,是我們做成本優(yōu)化的基礎(chǔ),磁盤的成本優(yōu)化意味著服務(wù)器的磁盤盡可能物盡其用。節(jié)約磁盤空間,就必須要在相對較高的磁盤水位運行(這里是指數(shù)據(jù)量確實很大的情況),因此,磁盤有效管理,及時的問題監(jiān)控發(fā)現(xiàn)的機制非常重要。
三 磁盤空間優(yōu)化方案
下面我們以某客戶的案例來說明磁盤空間優(yōu)化方法。該客戶數(shù)據(jù)倉庫中的數(shù)據(jù)(含索引)大于1.5PB,但客戶一期為ADB數(shù)倉采購了40臺機器,約800T總?cè)萘俊?蛻裘鞔_要求阿里云需要配合業(yè)務(wù)方做好數(shù)倉設(shè)計,幫其節(jié)約成本。客戶把成本優(yōu)化的KPI已經(jīng)定好了,需要阿里云通過技術(shù)去落實。我們協(xié)同業(yè)務(wù)方在設(shè)計階段做了一些預(yù)案,技術(shù)上主要從表壓縮和冷熱數(shù)據(jù)分離的角度去做考慮;業(yè)務(wù)上,讓開發(fā)商從設(shè)計上,盡量縮減在ADB中的存量數(shù)據(jù)。最終,開發(fā)商預(yù)估大概有360T左右的熱數(shù)據(jù)從舊的數(shù)倉遷移到ADB。上線前,開發(fā)商需要把必要的基礎(chǔ)業(yè)務(wù)數(shù)據(jù)(比如貼源層,中間層),從DB2遷移到ADB PG。遷移完成,業(yè)務(wù)進行試運行期,我們發(fā)現(xiàn)空間幾乎占滿(如圖2)。空間優(yōu)化迫在眉睫,于是我們發(fā)起了磁盤空間優(yōu)化治理。圖4是磁盤空間治理優(yōu)化的框架。
圖4:磁盤水位優(yōu)化框架
接下來,我們展開做一下說明。
1 表的存儲格式及壓縮
表的壓縮存儲可以有效保障客戶節(jié)約存儲空間。Greenplum支持行存、Append-only行存、Append-only列存等存儲格式。若希望節(jié)約存儲空間,Append-only列存表是較好的選擇,它較好的支持數(shù)據(jù)壓縮,可以在建表時指定壓縮算法和壓縮級別。合適的壓縮算法和級別,可以節(jié)約數(shù)倍存儲空間。建表示例語句如下:
CREATE TABLE bar (id integer, name text)WITH(appendonly=true, orientation=column, COMPRESSTYPE=zstd, COMPRESSLEVEL=5)DISTRIBUTED BY (id);列存表必須是Append-only類型,創(chuàng)建列存表時,用戶可以通過指定COMPRESSTYPE字段來指定壓縮的類型,如不指定則數(shù)據(jù)不會進行壓縮。目前支持三種壓縮類型:
zstd、zlib和lz4,zstd算法在壓縮速度、解壓縮度和壓縮率三個維度上比較均衡,實踐上推薦優(yōu)先考慮采用zstd算法。zlib算法主要是為了兼容一些已有的數(shù)據(jù),一般新建的表不采用zlib算法。lz4算法的壓縮速度和壓縮率不如zstd,但是解壓速度明顯優(yōu)于zstd算法,因此對于查詢性能要求嚴格的場景,推薦采用lz4算法。
用戶可以通過指定COMPRESSLEVEL字段來決定壓縮等級,數(shù)值越大壓縮率越高,取值范圍為1-19,具體壓縮等級并不是數(shù)字越大越好,如上文所述,解壓縮也消耗時間,壓縮率高,則解壓縮會相對更慢。因此,需要根據(jù)業(yè)務(wù)實際測試來選定,一般5-9都是有實際生產(chǎn)實踐的壓縮級別。
2 冷熱數(shù)據(jù)分層存儲
在大型企業(yè)的數(shù)據(jù)倉庫設(shè)計中,MPP數(shù)據(jù)庫(ADB屬于MPP)只是其中一種數(shù)據(jù)存儲,而且是偏批處理、聯(lián)機查詢、adHoc查詢的場景使用較多;還有很多冷數(shù)據(jù)、歸檔數(shù)據(jù),其實一般都會規(guī)劃類似Hadoop、MaxCompute甚至OSS進行存儲;另外,近年來興起的流數(shù)據(jù)的計算和存儲,需求也非常強烈,可以通過Kafka、Blink、Storm來解決。因此,當MPP數(shù)據(jù)庫空間告急時,我們也可以做冷熱數(shù)據(jù)分級存儲的方案。ADB PG的分級存儲方案,大致有兩種:1是業(yè)務(wù)方自己管理冷數(shù)據(jù)和熱數(shù)據(jù);2是利用ADB PG冷熱數(shù)據(jù)分層存儲和轉(zhuǎn)換功能。
業(yè)務(wù)方通過PXF外表訪問HDFS冷數(shù)據(jù)
業(yè)務(wù)方把部分冷數(shù)據(jù)以文件的方式存到HDFS或Hive,可以在ADB創(chuàng)建PXF外部表進行訪問;外部表不占用ADB PG的磁盤空間。PXF作為Greenplum與Hadoop集群數(shù)據(jù)交互的并行通道框架,在Greenplum中通過PXF可以并行加載和卸載Hadoop平臺數(shù)據(jù)。具體使用方法如下:
(1)控制臺開通PXF服務(wù)
· 登錄ADB管控臺,訪問ADB PG實例外部表頁面,點擊開通新服務(wù)
圖5:PXF外表服務(wù)
填寫詳細的Hadoop的服務(wù)信息后(涉及kerberos認證,非此文重點),PXF服務(wù)會啟動,啟動成功后如上圖。
(2)創(chuàng)建PXF擴展
-- 管理員執(zhí)行create extension pxf_fdw;(3)創(chuàng)建PXF外表
CREATE EXTERNAL TABLE pxf_hdfs_textsimple(location text, month text, num_orders int, total_sales float8)LOCATION ('pxf://data/pxf_examples/pxf_hdfs_simple.txt?PROFILE=hdfs:text&SERVER=23')FORMAT 'TEXT' (delimiter=E',');說明:Location是hdfs源文件信息,/data/pxf_examples/pxf_hdfs_simple.txt,即業(yè)務(wù)訪問的外部冷數(shù)據(jù)文件;SERVER=23指明了Hadoop外表的地址信息,其中23是集群地址信息的存放目錄,在圖8中可以根據(jù)PXF服務(wù)查到。
(4)訪問外部表
訪問外部表就和訪問普通表沒有區(qū)別
圖6:外部表訪問示例
ADB PG冷熱數(shù)據(jù)分層存儲方案
上面的pxf外表訪問,有一個弊端,是如果冷數(shù)據(jù)(外表)要和熱數(shù)據(jù)join,效率較差,原因是數(shù)據(jù)要從HDFS加載到ADB,再和ADB的表進行Join,徒增大量IO。因此,ADB PG在Greenplum的PXF外表的基礎(chǔ)上,提供了冷熱數(shù)據(jù)轉(zhuǎn)換的功能,業(yè)務(wù)方可以在需要Join外表和普通表分析時,把外部表先轉(zhuǎn)換為ADB的普通表數(shù)據(jù),再做業(yè)務(wù)查詢,整體方案稱為冷熱數(shù)據(jù)分層存儲。由于都是利用PXF外表服務(wù),3.4.1中的第1和第2步驟可以復(fù)用。額外的配置方法如下:
(1) 配置分層存儲默認使用剛才的Foreign Server
用超級管理員執(zhí)行
ALTER DATABASE postgres SET RDS_DEF_OPT_COLD_STORAGE TO 'server "23",resource "/cold_data", format "text",delimiter ","';注意,這里需要將postgres替換為實際的數(shù)據(jù)庫名,并將/cold_data替換為實際在HDFS上需要用來存儲冷數(shù)據(jù)的路徑。
(2) 重啟數(shù)據(jù)庫實例后執(zhí)行檢查
SHOW RDS_DEF_OPT_COLD_STORAGE;驗證是否配置成功。
(3) 創(chuàng)建測試表,并插入少量測試數(shù)據(jù)
create table t1(a serial) distributed by (a);insert into t1 select nextval('t1_a_seq') from generate_series(1,100);postgres=# select sum(a) from t1;sum------5050(1 row)此時,t1表的數(shù)據(jù)是存在ADB的本地存儲中的,屬于熱數(shù)據(jù)。
(4) 將表數(shù)據(jù)遷移到冷存HDFS
alter table t1 set (storagepolicy=cold);圖7:轉(zhuǎn)換數(shù)據(jù)為冷數(shù)據(jù)
注意這個NOTICE在當前版本中是正常的,因為在冷存上是不存在所謂分布信息的,或者說分布信息是外部存儲(HDFS)決定。
(5) 驗證冷數(shù)據(jù)表的使用
首先,通過查看表的定義,驗證表已經(jīng)遷移到冷存
圖8:冷存表的定義
然后正常查詢表數(shù)據(jù);
postgres=# select sum(a) from t1;sum------5050(1 row)(6) 將數(shù)據(jù)遷回?zé)岽?/p> alter table t1 set (storagepolicy=hot);
圖9:數(shù)據(jù)遷回?zé)岽?/p>
注意:遷移回?zé)岽婧?#xff0c;distributed信息丟失了,這是當前版本的限制。如果表有索引,則索引在遷移后會丟失,需要補建索引。以上兩個方案,都能一定程度上把冷數(shù)據(jù)從ADB PG中遷移到外部存儲,節(jié)約ADB PG的空間。
方案1,Join效率低,不支持冷熱數(shù)據(jù)轉(zhuǎn)換,但不再占用ADB的空間;
方案2,Join效率高,支持冷熱數(shù)據(jù)轉(zhuǎn)換,部分時間需要占用ADB的空間。
兩個方案各有利弊,實際上項目中,根據(jù)業(yè)務(wù)應(yīng)用來定。在該客戶案例中,冷熱數(shù)據(jù)分層存儲方案,為整體ADB節(jié)約了數(shù)百T空間,這數(shù)百T空間中,大部分是設(shè)計階段解決的,少部分是試運行期間進一步優(yōu)化的。
3 垃圾數(shù)據(jù)vacuum
由于GP內(nèi)核的MVCC管理機制,一個表的DML(t2時刻)提交后的數(shù)據(jù)元組,實際上并沒有立即刪除,而是一直與該表的正常元組存儲在一起,被標記為dead tuples;這會導(dǎo)致表膨脹而占用額外空間。垃圾數(shù)據(jù)回收有兩個方法:內(nèi)核自動清理、SQL手動清理。自動清理的機制是:表的dead tuples累積到一定百分比,且所有查詢該表的事務(wù)(t1時刻<t2時刻)都已經(jīng)結(jié)束,內(nèi)核會自動auto vacuum垃圾數(shù)據(jù)。這個機制,本身沒有問題,但是在大庫和大表場景下有一定問題,一個大表上T,數(shù)據(jù)變化10G才1%,多個大表一起變化,就會累計給整體空間帶來問題,因此必須輔以手動回收。
手動回收方法
(1)統(tǒng)計出系統(tǒng)的top大表;
select *,pg_size_pretty(size) from (select oid,relname,pg_relation_size(oid) as size from pg_class where relkind = 'r' order by 3 desc limit 100)t;-- limit 100表示top100(2)查詢大表的dead tuple占比和空間;
-- 根據(jù)統(tǒng)計信息查詢膨脹率大于20%的表
SELECT ((btdrelpages/btdexppages)-1)*100||'%', b.relname FROM gp_toolkit.gp_bloat_expected_pages a join pg_class b on a.btdrelid=b.oid where btdrelpages/btdexppages>1.2;(3)使用pg_cron定時任務(wù)幫助業(yè)務(wù)回收垃圾數(shù)據(jù)
vacuum tablename;或
vacuum analyze tablename;-- 先執(zhí)行一個VACUUM 然后是給每個選定的表執(zhí)行一個ANALYZE或
vacuum full tablename;這里需要與業(yè)務(wù)溝通清楚執(zhí)行時間,具體vacuum時,雖然不影響讀寫,但還是有額外的IO消耗。vacuum full tablename要慎重使用,兩者的區(qū)別要重點說明一下:簡單的VACUUM(沒有FULL)只是回收表的空間并且令原表可以再次使用。這種形式的命令和表的普通讀寫可以并發(fā)操作,因為沒有請求排他鎖。然而,額外的空間并不返回給操作系統(tǒng);僅保持在相同的表中可用。VACUUM FULL將表的全部內(nèi)容重寫到一個沒有任何垃圾數(shù)據(jù)的新文件中(占用新的磁盤空間,然后刪除舊表的文件釋放空間),相當于把未使用的空間返回到操作系統(tǒng)中。這種形式要慢許多并且在處理的時候需要在表上施加一個排它鎖。因此影響業(yè)務(wù)使用該表。
(4)vacuum加入業(yè)務(wù)代碼的恰當環(huán)節(jié)進行回收
如果某些表,更新頻繁,每日都會膨脹,則可以加入到業(yè)務(wù)的代碼中進行vacuum,在每次做完頻繁DML變更后,立即回收垃圾數(shù)據(jù)。
系統(tǒng)表也需要回收
這是一個極其容易忽視的點。特別是在某些數(shù)據(jù)倉庫需要頻繁建表、改表(臨時表也算)的場景下,很多存儲元數(shù)據(jù)的系統(tǒng)表也存在膨脹的情況,而且膨脹率跟DDL頻繁度正相關(guān)。某客戶出現(xiàn)過pg_attribute膨脹到幾百GB,pg_class膨脹到20倍的情況。以下表,是根據(jù)實際總結(jié)出來比較容易膨脹的pg系統(tǒng)表。
pg_attribute -- 存儲表字段詳情pg_attribute_encoding -- 表字段的擴展信息pg_class -- 存儲pg的所有對象pg_statistic -- 存儲pg的數(shù)據(jù)庫內(nèi)容的統(tǒng)計數(shù)圖10:pg_class膨脹率示例
手動Vacuum的限制
手動做vacuum有一定的限制,也要注意。
(1)不要在IO使用率高的期間執(zhí)行vacuum;
(2)vacuum full需要額外的磁盤空間才能完成。
如果磁盤水位高,剩余空間少,可能不夠vacuum full大表;可以采取先刪除一些歷史表,騰出磁盤空間,再vacuum full目標table。
(3)必須先結(jié)束目標table上的大事務(wù)
有一次例行大表維護時,一個表做了一次vacuum,膨脹的空間并沒有回收,仔細一查pg_stat_activity,發(fā)現(xiàn)這個表上有一個大事務(wù)(啟動時間比手動vacuum啟動更早)還沒結(jié)束,這個時候,內(nèi)核認為舊的數(shù)據(jù)還可能被使用,因此還不能回收,手動也不能。
4 冗余索引清理
索引本身也占用空間,尤其大表的索引。索引是數(shù)據(jù)庫提高查詢效率比較常用又基礎(chǔ)的方式,用好索引不等于盡可能多的創(chuàng)建索引,尤其在大庫的大表上。空間緊張,可以試著查一下是否有冗余索引可以清理。
排查思路
(1)是否有包含“異常多”字段的復(fù)合索引;
(2)是否有存在前綴字段相同的多個復(fù)合索引;
(3)是否存在優(yōu)化器從來不走的索引。
排查方法與例子
首先,我們從第1個思路開始,查詢索引包含字段大于等于4個列的表。SQL如下:
with t as (select indrelid, indkey,count(distinct unnest_idx) as unnest_idx_count from pg_catalog.pg_index, unnest(indkey) as unnest_idx group by 1,2 having count(distinct unnest_idx)>=4 order by 3 desc)select relname tablename,t.unnest_idx_count idx_cnt from pg_class c ,t where c.oid=t.indrelid;某個客戶,就建了很多10個字段以上的復(fù)合索引,如下圖所示:
圖11:按索引列數(shù)排序的復(fù)合索引
一般超過6個字段的復(fù)合索引,在生產(chǎn)上都很少見,因此我們初步判斷是建表時,業(yè)務(wù)方創(chuàng)建了冗余的索引;接下來,可以按照索引的大小排序后輸出冗余索引列表。SQL如下:
with t as (select indrelid,indexrelid, indkey,count(distinct unnest_idx) as unnest_idx_count from pg_catalog.pg_index, unnest(indkey) as unnest_idx group by 1,2,3 having count(distinct unnest_idx)>=3 order by 3 desc)select relname tablename,(pg_relation_size(indexrelid))/1024/1024/1024 indexsize,t.unnest_idx_count idx_cnt from pg_class c ,t where c.oid=t.indrelid order by 2 desc;圖12:按大小排序的復(fù)合索引
這里,我們很清楚發(fā)現(xiàn),部分索引的大小都在500G以上,有10多個索引的size超過1TB,看到這些信息時,我們震驚又開心,開心的是應(yīng)該可以回收很多空間。接下來,需要跟業(yè)務(wù)方去溝通,經(jīng)過業(yè)務(wù)方確認不需要再刪除。
在這個客戶案例中,我們刪除了200多個冗余索引,大小達24T,直接釋放了7%的業(yè)務(wù)空間!非常可觀的空間優(yōu)化效果。這次優(yōu)化也非常及時,我記得優(yōu)化在11月底完成;接著正好12月初高峰來臨,業(yè)務(wù)方又寫入了20TB新數(shù)據(jù),如果沒有這次索引優(yōu)化,毫不夸張:12月初該客戶的ADB集群撐不住了!
第(2)個思路(是否有存在前綴字段相同的多個復(fù)合索引),排查SQL如下。最好把索引及包含的字段元數(shù)據(jù)導(dǎo)出到其他GP庫去分析,因為涉及到索引數(shù)據(jù)的分析對比(涉及向量轉(zhuǎn)字符數(shù)組,以及子集與超集的計算),比較消耗性能;
select idx1.indrelid::regclass,idx1.indexrelid::regclass, string_to_array(idx1.indkey::text, ' ') as multi_index1,string_to_array(idx2.indkey::text, ' ') as multi_index2,idx2.indexrelid::regclass from pg_index idx1 , pg_index idx2 where idx1.indrelid= idx2.indrelid and idx1.indexrelid!=idx2.indexrelid and idx1.indnatts > 1and string_to_array(idx1.indkey::text, ' ') <@ string_to_array(idx2.indkey::text, ' ');以下是排查例子user_t上復(fù)合第2個問題的索引,如下:
以下是查詢結(jié)果
以上例子結(jié)果解釋:multi_index1是multi_index2的子集,前者的索引列已經(jīng)在后者中做了索引,因此,multi_index1屬于冗余索引。
第(3)個思路:是否存在優(yōu)化器從來不走的索引,排查的SQL如下:
SELECTPSUI.indexrelid::regclass AS IndexName,PSUI.relid::regclass AS TableNameFROM pg_stat_user_indexes AS PSUI JOIN pg_index AS PI ON PSUI.IndexRelid = PI.IndexRelidWHERE PSUI.idx_scan = 0 AND PI.indisunique IS FALSE;下面以一個測試表,講述排查例子
執(zhí)行SQL可以查到idx_scan=0的索引idx_b
另外,有一個很重要的知識點,Append-Only列存表上的索引掃描只支持bitmap scan方式,如果Greenplum關(guān)閉了bitmap scan的索引掃描方式,那么所有AO列存表的訪問都會全表掃描,即理論上AO列存表上的所有非唯一索引都無法使用,可以全部drop掉。當然,這個操作風(fēng)險很高,要求整個database里使用AO列存表的業(yè)務(wù)幾乎都只做批處理,不存在點查或范圍查找的業(yè)務(wù)。綜上,刪除冗余索引,可以幫助客戶節(jié)約磁盤空間。
5 復(fù)制表修改為分布表
眾所周知,ADB PG的表分布策略有DISTRIBUTED BY(哈希分布),DISTRIBUTED RANDOMLY(隨機分布),或DISTRIBUTED REPLICATED(全分布或復(fù)制表)。前兩種的表會根據(jù)指定的分布鍵,把數(shù)據(jù)按照hash算法,打散分布到各個Segment上;復(fù)制表,則會在每個Segment上存放完整的數(shù)據(jù)拷貝。復(fù)制表分布策略(DISTRIBUTED REPLICATED)應(yīng)該在小表上使用。將大表數(shù)據(jù)復(fù)制到每個節(jié)點上無論在存儲還是維護上都是有很高代價的。查詢?nèi)植急淼腟QL如下:
select n.nspname AS "schemaname",c.relname AS "tablename",case when p.policytype='p' then 'parted' when p.policytype='r' then 'replicated' else 'normal' end as "distrb_type", pg_size_pretty(pg_relation_size(c.oid))from pg_class cleft join gp_distribution_policy p on c.oid=p.localoidleft join pg_namespace n on c.relnamespace=n.oidwhere n.nspname='public'and c.relkind='r'and p.policytype='r'order by 4 desc;查詢結(jié)果如下圖,找到了大概10TB的全分布表,前3個表較大可以修改為哈希分布表,大概可以節(jié)約7T空間。
圖13:業(yè)務(wù)庫中的復(fù)制表
6 臨時表空間獨立存放
我們知道,Greenplum的默認表空間有兩個
如果建表不指定表空間,默認會放到pg_default表空間,包含堆表、AO表、列存表、臨時表等。具體到Segment的文件目錄,則是每個Segment服務(wù)器上的~/data/Segment/${Segment_id}/base/${database_oid}目錄下。同時,Greenplum在多種場景都會產(chǎn)生臨時表,如:
(1)sql中order by、group by等操作;
(2)GP引擎由于數(shù)據(jù)讀取或shuffle的需要,創(chuàng)建的臨時表;
(3)業(yè)務(wù)方在ETL任務(wù)中創(chuàng)建的臨時表。
這樣存在一個問題,就是業(yè)務(wù)運行產(chǎn)生的臨時表也會占用空間,但這部分不是業(yè)務(wù)表的數(shù)據(jù)占用,不方便精確管理大庫的磁盤空間;因此我們把臨時表的表空間獨立出來,在服務(wù)器文件層面也獨立出來,方便與業(yè)務(wù)數(shù)據(jù)進行分別精細化管理。好處還有:我們可以分別監(jiān)控臨時表空間、數(shù)據(jù)表空間、wal日志、錯誤日志,知道各個部分占用情況,如果磁盤空間告警,可以針對性采取措施。Greenplum創(chuàng)建臨時表空間的方法,比較標準,如下:
#查看臨時表的表空間現(xiàn)狀,發(fā)現(xiàn)都在base目錄下,即與數(shù)據(jù)目錄共用postgres=# select * from pg_relation_filepath('tmp_jc');pg_relation_filepath----------------------base/13333/t_845345#查詢實例的Segment的所有hosts,用于創(chuàng)建臨時表空間目錄psql -d postgres -c 'select distinct address from gp_Segment_configuration order by 1' -t > sheng_seg_hosts#創(chuàng)建臨時表空間的文件目錄gpssh -f sheng_seg_hosts -e "ls -l /home/adbpgadmin/tmptblspace"gpssh -f sheng_seg_hosts -e "mkdir -p /home/adbpgadmin/tmptblspace"~$ gpssh -f dg_seg_hosts -e "ls -l /home/adbpgadmin/tmptblspace"# 創(chuàng)建臨時表空間postgres=# create tablespace tmp_tblspace location '/home/adbpgadmin/tmptblspace';postgres=# select * from pg_tablespace;spcname | spcowner | spcacl | spcoptions--------------+----------+--------+------------pg_default | 10 | |pg_global | 10 | |tmp_tblspace | 10 | |(3 rows)#修改角色的臨時表空間postgres=# alter role all set temp_tablespaces='tmp_tblspace';#退出psql,然后重新登錄#創(chuàng)建臨時表進行驗證create temp table tmp_jc2(id int);insert into tmp_jc2 select generate_series(1,10000);#查看表的filepath,發(fā)現(xiàn)臨時表空間的文件路徑不是base目錄了select * from pg_relation_filepath('tmp_jc2');---------------------------------------------------pg_tblspc/2014382/GPDB_6_301908232/13333/t_845369表空間獨立后,監(jiān)控可以區(qū)分臨時表空間、數(shù)據(jù)表空間、WAL日志、錯誤日志進行獨立監(jiān)控和告警,以下是監(jiān)控采集輸出的樣例:
~$ sh check_disk_data_size.shusage: sh check_disk_data_size.sh param1 param2, param1 is file recording Segment hosts; param2 data, xlog, log or temp監(jiān)控輸出的效果如下
圖14:監(jiān)控采集輸出示意圖
這樣可以很清楚的了解業(yè)務(wù)數(shù)據(jù)或臨時表數(shù)據(jù)在每個節(jié)點上的實際size,以及是否存在數(shù)據(jù)傾斜情況(超過平均值的10%)單獨提醒,非常實用。
7 其他優(yōu)化方案
除了上面詳述的優(yōu)化方案,一般來講,Greenplum還有一些通用的處理方法:擴容Segment計算節(jié)點、業(yè)務(wù)數(shù)據(jù)裁剪、備份文件清理。計算節(jié)點擴容是最有效的。一般來講,不管是阿里自己的業(yè)務(wù),還是外部客戶的業(yè)務(wù),數(shù)據(jù)庫的磁盤占用達到60%,考慮業(yè)務(wù)增量便會規(guī)劃擴容,這些“基本實踐”我們需要告訴客戶。
業(yè)務(wù)數(shù)據(jù)裁剪,除了冷數(shù)據(jù)外,有一些中間表和歷史表,我們也可以推動業(yè)務(wù)方做好數(shù)據(jù)生命周期管理,及時刪除或轉(zhuǎn)存歸檔。另外,對于臨時運維操作,留下的備份文件,在操作完后需要及時進行清理,這個簡單的習(xí)慣是非常容易忽略的,需要注意。在大庫的磁盤管理中,任何小問題都會放大。
四 優(yōu)化收益
1 為客戶節(jié)約服務(wù)器成本
本案例,客戶原DB2的數(shù)據(jù)量大于1PB,而我們通過上述方法綜合優(yōu)化,在ADB中只保存了300多T的數(shù)據(jù),就讓整體業(yè)務(wù)完整的運行起來。為客戶節(jié)約了大概100臺服務(wù)器及相關(guān)軟件license費用,約合金額千萬級別。
2 避免磁盤水位過高造成次生災(zāi)害
磁盤水位高會帶來很多問題,通過磁盤空間優(yōu)化方案,可以避免這些問題的發(fā)生。包括:
1.業(yè)務(wù)稍微增長,可能導(dǎo)致磁盤占滿,發(fā)生“寫鎖定”,數(shù)據(jù)庫臨時罷工;
2.磁盤空間不足時,運維人員定位問題無法創(chuàng)建臨時表;
3.ADB的大表維護,例如vacuum full,無空余磁盤空間使用。
以上磁盤空間優(yōu)化方法不一定非常全面,希望對讀者有所幫助。如果文中有疏漏或讀者有補充,歡迎多多交流,一起探討上云成本優(yōu)化。
名詞解釋
業(yè)務(wù)方:指使用Greenplum做業(yè)務(wù)開發(fā)或數(shù)據(jù)分析的用戶,通常是客戶或客戶的開發(fā)商。
OLAP:指聯(lián)機分析處理型系統(tǒng),是數(shù)據(jù)倉庫系統(tǒng)最主要的應(yīng)用,專門設(shè)計用于支持復(fù)雜的大數(shù)據(jù)量的分析查詢處理,并快速返回直觀易懂的結(jié)果。
DML:指增加、刪除、修改、合并表數(shù)據(jù)的SQL,在數(shù)據(jù)庫領(lǐng)域叫DML型SQL。
PB:1PB=1024TB=1024 * 1024 GB
原文鏈接
本文為阿里云原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。?
總結(jié)
以上是生活随笔為你收集整理的ADBPGGreenplum成本优化之磁盘水位管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ICBU可控文本生成技术详解
- 下一篇: 璀璨智行:V2X车路协同智慧交通