阿里巴巴數據庫架構師張瑞(Jacky)曾在個人網站寫過一篇博文《Oracle Exadata技術淺析》,現轉載于此,供大家學習:
自從Oracle和HP推出Exadata之后,我就很關注這個產品,之前也寫了一篇Oracle database machine介紹它。去年,Oracle和SUN合并后,推出了Oracle Exadata V2,相比較上一代產品有幾個變化:第一,使用SUN的硬件;第二,宣稱支持OLTP應用;第三,Oracle 11g R2提供了更多的新特性。
Exadata Smart Flash Cache
Exadata V2整體架構并沒有太多改變,換用了SUN的硬件,除了采用intel最新的nehalem CPU以外,每臺storage cell更是配置了384GB的flash,這也是為什么V2可以支持OLTP應用的關鍵。
Flash cache完全是自動管理,Oracle會根據數據的訪問情況,決定哪些數據放在flash cache中。所有的數據都是先被寫到普通磁盤上,再根據訪問情況讀入flash cache的,所以如果flash card發生故障,數據不會丟失。當然,Oracle提供了方式,可以讓用戶手動將表或者索引pin在flash cache中。
在自動管理的方式之外,Oracle還允許用戶人工創建flash disks,和普通磁盤一樣,這些flash disks通過ASM輸出給數據庫使用,用戶可以把一些訪問非常頻繁的數據文件放在上面。這些flash disks不僅僅是cache了,所以ASM會在cell和cell之間做鏡像。如果某塊卡發生故障,那么整個storage cell上的flash disks會offline,保證數據不會丟失。
Smart scan
Smart scan是Exadata最重要的一個功能,它的作用就是把SQL放在每個cell上去運行,然后每個cell只返回符合條件的數據給數據庫,這樣就極大的降低了數據庫服務器的負載和網絡流量,并充分利用了cell的計算資源和IO資源。
傳統方式:所有的數據都需要返回給數據庫服務器,網絡帶寬要求高,所有的計算在數據庫服務器上完成。
Smart scan:只返回符合條件的數據,減少網絡帶寬,并充分利用了cell上的計算和IO資源。
這里有一點要注意,在使用smart scan時,每個cell返回給DB server的是結果集,而不再是傳統的block,DB server完成結果集的處理,并返回給客戶端。
Smart scan如何處理join?是我一直想要搞清楚的問題。事實上,smart scan只能處理join filtering,而真正join的工作必須在DB Server上完成,而且smart scan僅適合于處理DSS環境的復雜join,對于OLTP類型的簡單join,smart scan并不能發揮其優勢。設想下面的查詢:
select e.ename,d.dname from emp e, dept d where and e.ename=’Jacky’ and e.deptno=d.deptno;
假設采用nested loops join,smart scan只能完成e.ename=’Jacky’這個條件的過濾,然后將符合條件的emp表的數據返回到DB server,然后由DB Server完成join的工作,逐條查詢dept表(e.deptno=d.deptno)的數據。所以smart scan并不適合nested loop join(我認為smart scan只有在適合的條件下才會啟用),只有DSS環境的大數據量復雜join才會發揮出優勢。而且smart scan只能完成filtering的工作,而不能真正完成join的工作,這個與Greenplum數據庫是不同的(有興趣可以看我的文章,Greenplum技術淺析)。設想下面的查詢(emp和dept都是大表):
select e.ename,d.dname from emp e, dept d where e.deptno=d.deptno;
假設采用hash join,由于沒有任何過濾條件,smart scan只能把兩個表的數據全部返回到DB Server上進行join操作,不過smart scan也不是一點用都沒有,至少還可以進行column的過濾,只返回需要的字段就可以了。
Oracle的文檔中,曾經提到對于一個大表和小表join時,smart scan會采用bloom filter來快速定位(可以看我以前的文章,有趣的bloom filter)。方法是把小表build成為bloom filter,然后在每個storage cell上對大表做scan,利用bloom filter快速定位符合條件的結果,并返回給DB Server作join。
Storage index
存儲索引,顧名思義是在存儲級別建立的索引,簡單的說就是為表中的每一列數據建立一個索引,每個index entry記錄一段數據區間的最大值,最小值以及它們的物理位置,文檔上說1MB數據對應一條index entry,見下圖:
如果我們查詢B<2,或者B>8的數據,根據存儲索引,我們就可以跳過這些不在min和max之間的數據塊,極大的提高了掃描的速度,這就是存儲索引的意義。
Hybrid Columnar Compressed
首先我們要搞清楚,什么是行壓縮,什么叫列壓縮。我們熟悉的數據庫,如Oracle,MySQL等都是基于行的數據庫,就是行的不同字段物理上存放在一起,還有一種是基于列的數據庫,就是每個字段的不同行物理上存放在一起。他們的優缺點同樣突出:
基于行的數據庫,訪問一行非常方便,但是由于同一列的數據是分開存放的,如果要針對某一列進行查詢時,幾乎要掃描整個表才能得到結果。基于行數據庫的壓縮,稱為行壓縮。
基于列的數據庫,因為同一列的數據物理上放在一起,所以訪問一列非常方便,也就是說如果針對某一列進行查詢時,不需要掃描整個表,只需要掃描這一列的數據就可以了,但是訪問一行的全部字段非常不方便(又是廢話)。基于列數據庫的壓縮,稱為列壓縮。
Oracle通常說的compress功能(包括11g R2的Advanced compress),都是行壓縮,因為Oracle是個基于行的數據庫。大概的方法就是在block頭部存放一個symbol table,然后將相同的值放在那里,每行上相同的數據指向symbol table,以此來達到壓縮的目的。行壓縮的效果通常不好,因為我們知道行與行之間,其實相同的數據并不多。但是列壓縮則不同,因為相同列的數據類型相同,很容易達到很好的壓縮效果。
行壓縮和列壓縮都有其優缺點,而Oracle的混合列壓縮技術,實際上是融合了列壓縮的高壓縮比和行數據庫的訪問特性,將兩者的優點結合起來。Oracle提出了CU的概念(compress unit),在一個CU內,是一個基于列的存儲方式,采用列壓縮,但是一個CU內保存了行的所有字段信息,所以在CU與CU之間,Oracle還是一個基于行的數據庫,訪問某一行,總是只在一個CU內。每個CU由一些連續的block組成,CU header中記錄了每一行的各個列在CU中的分布情況,在混合列壓縮模式下,一行通常是跨多個block的。
所以說混合列壓縮,結合了列壓縮和行訪問的特點,即可以提供非常高的壓縮率,又很好的保證了基于行類型的訪問。
Exadata的另一個重要功能是IO resource management,如果我們在一個Exadata上部署了很多個數據庫,可以用它來管理IO資源,這里就不作闡述了。
目前,我還沒有了解到在國內有Exadata的應用,而且資料也是比較少的。希望有機會可以真實的測試一下它的性能,我不懷疑他在DSS環境下的表現,但是對于OLTP類型的應用,是否真的象Oracle說的那么強勁,還有待于驗證。
-- 學海無涯