google 程序员 开源 wordpress Firefox php 云计算 Windows Android 编程 mysql Python apache 微软 java centos linux shell nginx Ubuntu

數據庫與存儲系統

20151023044307114.jpg

 

   10月13日,由文武信息技術創始人朱賢文在“DBA+福州群”進行了一次關於數據庫與存儲系統的線上主題分享。小編特別整理出其中精華內容,供大家學習交流。   

嘉賓簡介  

朱賢文,超過17年IT經驗,曾為 SYMANTEC/VERITAS, ORACLE, IBM 和 HP 工作,精通PostgreSQL,Oracle/RAC/ASM, VERITAS Storage Foundation(VCS,SFRAC etc)。擁有廣泛的行業經驗,包括銀行,電信,保險及政府行業。目前在創業,專註於提供PostgreSQL數據庫服務和配套解決方案,推動PostgreSQL數據庫在中國的普及與應用。

演講實錄  

根據與許多客戶的溝通,客戶往往最容易忽略掉的環節就是存儲系統,而存儲系統裏面,文件系統被關註是最少的。

本次技術分享的關註點就是存放數據庫的文件系統,將簡單描述文件系統及其緩存大概的架構,基本的工作原理,使用文件系統需要註意的事項,在設計和使用不同的數據庫的存儲子系統的時候有更全面的考慮。

本圖片涉及到的原理圖只為示意,不是工作原理的精確表達,請見諒。

本次演講主要分為四個部分:1、通用文件系統基本結構;2、專用文件系統 (asm);3、裸設備;4、就運行數據庫來說,哪一種存儲是最好的選載。 

1、通用文件系統基本結構

 

 

20151022095602304.png

 

这个页面粗略地描述了文件系统跟存储的架构,文件系统,卷,跟存储在操作系统中的位置。

 

操作系统里面的内存分为两个基本的部分:用户空间和内核空间,内核空间主要存放操作系统自身的软件代码和数据,如驱动程序,任务调度,内存分配和管理的程序。

 

用户空间用以存放用户自己的应用程序;数据库系统对于操作系统来说是一个比较大的应用程序,所以数据库的进程以及这些进程涉及到的内存空间都被分配到了用户空间;所以像oracle的sga;PostgreSQL的shared_buffers等内存使用的空间都被安排在用户空间。

 

数据库需要将数据永久的保存起来,所以它就需要跟下层的存储系统打交道;存放数据的存储系统大概分为几类,裸设备,通用文件系统,专用文件系统等。

 

在访问文件系统的时候,经过的路径大概是:user space à vfs à fs à vm à storage media。在很多层面,都有自己的缓存管理机制;比如用户空间内,应用程序有自己的缓存管理机制,oracle:sga;postgresql:shared_buffers/xxxx ; 文件系统自己有自己的数据老化算法;如ext4,jfs,ntfs等;再往下面走,就是卷管里程序,比如vxvm,lvm等,它也有自己的缓存管理机制,再往下就是存储介质,比如sata磁盘;磁盘阵列划分到主机上的lun。磁盘有自己的磁盘缓存,lun的后端也有很大的缓存。

 

20151022095610651.png


介紹完文件系統和存儲的基本架構後,接下來討論一下數據庫的塊跟文件系統的對應關系。數據庫跟文件系統一樣,最小的存儲物理單位是一個block,根據不一樣的數據庫,這個block的大小不同;informix默認的塊大小是4k,oracle的默認塊大小是8k,postgresql也是一樣,默認情況下是8k。

但是在文件系統層面,絕大多數文件系統支持4k,(除了vxfs和zfs)。vxfs支持最大64k,可以設置成512byte,1k,2k,4k,8k,16k,32k,64k。

zfs是一個特殊的怪物;數據塊是動態的,也就是說寫入多少數據,zfs上那塊存放數據的塊就有那麽大。傳統上是支持動態的512byte到128k。

oracle的Solaris版本的zfs支持512byte~4M動態分配塊的大小。去年我在社區裏面跟matt一起做了最新的zfs的特性,可以動態支持塊的大小為512byte~16M。

對於數據庫應用來說,需要清楚的知道每個數據庫塊所對應的文件系統塊的大小。

這一點非常重要,在pg早期的時候,沒有一個參數來控制寫對其,會導致潛在的data corruption,就是因為這個原因導致wal在寫入的時候沒有要求full page write(8k)導致的數據存壞。因為wal不做這個限制,比如寫入4k到文件系統,在文件系統的角度來看是一個完整的4k;這時候發生意外,需要做恢復,那麽文件系統的層面可以恢復最後寫入的4k數據,但是對於pg來說,最後的那個8k是壞的;因為它每次讀取的數據至少是8k,而實際上文件系統只能提供4k數據,部分能提供完整的8k數據。所以pg就會認為那塊數據是順壞的。

如果使用oracle,這些細節已經在oracle裏面處理好了,所以dba是感受不到的。但是如果使用其它數據庫,比如mysql,好像是16k每個塊,就應該要註意這個塊的問題。

 

20151022095726674.png

 

这个图是一个数据查找的路径,说明double cache的原理。

 

当cpu需要获取数据库的数据的时候,那么它会先到数据库的缓存里面去查找,就是我们的sga/shared_buffers(pg),其他数据库也有类似的缓存区;

如果在该缓存去查找到了数据,那么数据会被装载入cpu,进行运算;如果数不在缓冲区,那么数据库就会向存储系统系统(实际上是文件系统)发出获取数据的请求;文件系统也有自己的缓存,所以类似的操作,文件系统要先看看被查找的数据是否在缓存里面,如果在缓存里面,那么就向数据库返回该数据,如果不在文件系统的缓存内,那么文件系统就要向卷管理程序发出请求,要求提供该数据;在卷管理程序也会做类似的操作。

 

所以在这个路径上面,就会经过很多层面的缓存,这个现象叫double cache;double cache对于数据库应用来说典型的就是使查找效率降低,同时使得cpu用量提高。所以在数据库应用中需要避免double cache。

 

20151022095735934.png

 

这个图描述了写入数据的路径。正常情况下,我们希望写入的数据能够可靠正确地写入存储介质,同时要求尽快的相应/返回;但是因为文件系统有很多选项,就决定了写入的很多行为。

 

第一种就是回写,就是数据库将脏数据写给文件系统,文件系统正确的接收到,并且将写入的数据缓存在文件系统的缓存里面,就向数据库返回写入成功,实际上这些数据还在文件系统的缓存里面,还没有可靠的写入存储介质。

 

第二种就是透写,就是数据库将脏数据写入文件系统,文件系统收到数据库立即向存储介质写入数据,当文件系统得到存储介质报告完全写入成功后,才认为本次写入成功,所以才向数据库返回。

 

这两种写入方式对于数据库来说,一种方式能够提供非常高的写入性能,一种是提供非常高的可靠性。所以需要了解其基本的原理。

 

在存储介质这个层面,还有一层缓存,比如磁盘有一颗32M或者64M的缓存,对于上层应的写入,写入到这个缓存,上层的应用就认为写入永久存储介质了,而实际上这个数据还没有完全写入到磁盘的盘片,我们的真正的介质上去;如果这个时候发生突然掉电,那么一样会发生数据丢失;所以当使用磁盘直接存放数据的时候也需要注意这个问题。

 

当对每个层面的缓存了解后,根据数据库的情况,可以灵活地控制如何使用这些缓存,需要高性能?还是高可靠性?可以灵活的控制。

 

20151022095745138.png

 

这个图对于有自己缓存系统的应用程序,比如数据库有自己的缓存管理系统,那么我们应该尽量避免double cache的出现;对于文件系统,理想的配合数据库使用的文件系统,我们希望它的缓存只限制于文件系统自身的meta data的管理和缓存,不去缓存用户数据。

 

 

对于像数据库这种有自己的内存区和内存管理的应用程序。应该避免double引起的性能衰减;同时用户的数据尽量要避免缓存到文件系统上。

 

20151022095753648.png

 

数据库内,一个表分布在多个segment上;而组成segment的单位是我们的extend。Segment在文件系统层面来看就是一个数据文件。

 

数据库在操作一个表的时候,有很多情况下,活着说发生这样的几率;不同的数据库进程需要操作的数据块在同一个文件里面,但是在文件的不同位置(extend),由于文件系统需要保证自己的acid;所以这些进程需要通过锁的机制来决定谁先操作,谁后操作。

 

如图所示,当这些进程操作数据时,只有抢到x锁(排他锁)的进程才能对自己要操作的数据块进行操作,当完成后,将x锁释放;其它进程再抢x锁;如此进行。也就是说只能串行写入,影响性能。而实际情况是,数据库已经保证了acid,这些数据本身没有冲突;这些进程之间的操作可以同时进行而不相互影响。

 

20151022095802224.png

 

 

所以对于数据库来说,它希望向左边这个图这样工作,而实际情况是右边这种情况(使用文件系统存放数据库)。在示意图上,左边是数据库应用,我们希望的操作数据的行为,即使在同一个文件里面,因为数据库已尽保证了acid这些东西,不会在下层的存储层面冲突。所以希望只要不在相同的数据块上面,这些数据操作都可以并行进行。

 

右面是使用一般的文件系统的行为,具体情况以及在上一页描述过了,进程之间不得不去抢文件的x锁,更新完成之后将所释放,流给后面的进程做同样的事情。从而引起本来可以避免的性能问题。

 

2、专用文件系统(asm)

 

20151022095809293.png
 

为了解决前三页的这些问题,业界就数据库应用开发了专用的文件系统,比如oracle的asm(只能运行oracle数据库),veritas的vxfs,vxfs文件系统有非常高级和强大的功能,同时提供各种应用场合强大的性能特性;支持oracle,db2, Informix, Sybase, postgresql等数据库。

 

在asm和vxfs里面,能做到高性能的根本原因就是允许对同一个文件并行写入。(传统的文件系统只允许对同一个文件同时读取,但是不允许并行写入),写入的(用户)数据的一致性完全由数据库控制和保障,存储层面只需要保证meta data一致。

 

存储的缓存只负责缓存最基本的元数据meta data,用户数据不会被缓存起来,这样又能有效避免double cache引起的副作用。

 

所以运行数据库,比较理想的文件系统应该是:运行对一个文件并行写入,同时不缓存用户的数据。现在市场上可选的只有asm跟vxfs文件系统是比较好的选择。当然还有ZFS,绝对的利器。

 

3、裸设备

 

20151022095817366.png
 

接下来就会说裸设备,很多人接触和使用过裸设备,也有很多数据库页支持裸设备,但是oracle最近的版本将不建议使用裸设备,后面的版本就直接不支持了其原因就在于:

 

裸设备,因为是裸设备,所以没有繁琐的缓存机制,那么用户写入的数据就直接写入到介质上;同时避免了double cache;裸设备不仅不缓存用户数据,也不缓存基本的metadata;因为使用裸设备的高性能,曾经一度比较流行使用裸设备。

 

由于裸设备的性质决定了它不能提供任何缓存,也不对数据做任何保证,对数据的安全要全权由用户跟数据库管理系统来保证,所以当使用裸设备发生断电的时候,最容易造成数据库崩溃,数据损坏等不可控的情况出现。所以裸设备正在被遭到抛弃,ORACLE数据库最近几个版本已经不再支持罗设备了。

 

我们也不建议使用裸设备,因为不安全,不可靠。

 

4、应该用哪种存储介质

 

20151022095825194.png

 

这张表,以时钟频率为3.3G的cpu为例,说明cpu这个角度来看时间跨度。

 

如果将cpu的时间看成是我们生活中的1秒;cpu在一级缓存取一次数据的时间需要3秒;在内存里面去一次数据需要的时间是6分钟;在PCIe SSD里面去一次数据的时间大概是两天半,如果在本级磁盘存储一次数据,需要的时间跨度就非常大,如果按照5毫秒计算,对于cpu来说就花了半年多时间;如果稍微慢一点,变成10毫秒,对于cpu来说就花费了1年多时间。

 

这个表的目的就是要理解cpu的时间跨度,在设计存储子系统的时候有个参考。有了这个基本的概念,我们再继续聊下面的内容。

 

20151022095837379.png


這張圖比較粗略地描述了數據庫服務器跟存儲之間的連接關系和數據流向。

一個專業的存儲,可以抽象地看作是一個掛載了非常多磁盤的計算機,這部特殊的計算機,要麽通過網絡將自己的存儲資源共享,一般是nas;要麽通過光纖共享,一般是san。也可以在自己的計算機上掛在磁盤。

數據庫應用如果采用專門的存儲,查找數據的流程如示意圖所示,先要在本機查找,本機沒有找到數據的情況下,向存儲服務器查找,如果數據在存儲的緩存裏面,那麽可以很快的返回,如果數據不在存儲的緩存裏面,還需要走類似的流程到存儲自己的硬盤上面去取數據,然後再將數據送回。

如果數據在存儲的緩存裏面,一般需要5毫秒左右;在我們看來,這個時間延遲非常滿意,但是在計算機的看來,以及等了半年了。

如果因為存儲響應不及時,或者它還要到自己的磁盤上面去取數據;那麽一年半載的很容易就過去了。

這個流程大家都知道,也能夠理解。但是站在cpu的角度來看時間的跨度,可能很少有人這樣來思考這個問題,而這一點恰好是我們需要關註的。

作為數據庫應用來說,應當是IOPS,也就是響應時間要越短越好,而存儲往往是這個環節的主要矛盾。所以大家在設計數據庫應用的時候,要多關註存儲部分的響應時間。

20151022095847805.png

 

如何正確的使用存儲,尤其是正確的使用文件系統。首先要正確地選擇存儲介質,san? 本地ssd? nas?要看自己的需求是帶寬還是iops。

然後就是要規劃好存儲,比如對齊,文件系統跟卷;卷跟下層的磁盤/LUN;隨機數據/順序數據;永久數據/零時數據。需要將不同的io通過存儲字系統的設計進行隔離。

其次是要正確地利用好緩存,不是緩存越多越好;要根據數據庫裏面經常被訪問到的熱點數據而確定緩存的大小。

最後就是要確保所有的數據要安全可靠地寫入永久存儲介質。

Q&A精選  

[問題1]有沒有試過通過設置oracle數據庫的IO方面的參數來繞過文件系統的緩存?

答:oracle如果使用文件系統,可以有兩種最基本方式,我記得有一個是directxxx的控制文件讀寫的參數;我最近幾年很少碰oracle了,記不清參數準確的名字;另外像asm已近做成了不緩存userdata,只緩存metadata。如果用vxfs,可以在文件系統裏面使用odm庫提供的功能,也可以使用cio的方式。如果是其它的文件系統,可能就只能通過一些mount的參數來控制,比如direct io。 

[問題2]oltp系統和oltp系統在選擇存儲上是有區別的,那麽應該如何區別呢?

答:很明顯oltp跟olap的應用,在io行為上是明顯不同的。對於存儲的選擇;因為olap是帶寬需求型,對iops的消耗很小。所以olap的應用,如果帶寬足夠寬,那麽nas(eg: over 10GB)也是可以考慮的。設計的目的就是需要將帶寬耗盡,也就是說要盡最大可能向應用提供最大的帶寬。

如果用文件系統,我會建議ZFS,因為一個IO可以給你4M數據(oracle)或者16M數據(我們的版本)。對於OLAP,主要目的就是要盡量提高吞吐量,降低IO的開銷。

oltp的情況,如果用oracle,我會推薦asm或者vxfs,因為vxfs能提供非常高的性能。pg跟mysql ,如果在Linux平臺上面,ext4根xfs都是 比較好的選擇。但是要註意一些mount參數,數據庫裏面寫數據的方式,一定要full_page_write,並且要fsync的方式寫盤,保證數據是寫入到存儲介質了;如果使用sata,要確保sata的緩存是關閉的,目的就是要確保數據被可靠地寫入到存儲介質上了。

 

【問題3】vxfs比asm好在哪些地方?

答:vxfs是跨平臺的,數據存放不用care大端小端。用oracle,有可能遇到在aix上面的數據,需要倒入solaris(sparc)。或者其它硬件平臺。oracle給的解決方式是一個命令在數據庫裏面轉換;如果用vxfs(需要vxvm配合),只需要export出來,倒入到另一個平臺就可以了。 

【問題4】mha的日誌分支問題一般有什麽好的解決方法?

答:理論上有4種處理方式。比如第一種假設應用都往主節點寫入數據;從節點變成主節點後。沒有收到寫入請求,這個時候可以選擇重建。第二種,如果從節點在分裂後,接收了一些寫入;那麽就需要將這部分數據提取出來放到正常的主節點;然後重建。 

【問題5】請問我們有套文檔管理系統,存放實體文件的服務器上的文件很大,但是都是很多很小的文件組成的,這樣的話怎麽選存儲合適?

答:這種應用,建議采用zfs,或者vxfs,ext4也是可以考慮的。我會強烈推薦用zfs (可以下載我們的操作系統自帶的原生的zfs http://pan.baidu.com/s/1eQznX8e#path=%252FXianOS.Install.Image)。

 

【問題6】請問同一個陣列,采用asm結構,擴展一個102G的數據文件用時約15分鐘。改成vxfs文件系統後,擴展同樣大小的數據文件用時約50分鐘。性能為什麽會下降這麽厲害?

答:asm裏面的cross grain默認是1M; 默認的extend很小,應該采用默認設置。試一下將vxvm的extend設置成64M試一下,不會比asm差。 

【問題7】我們這邊使用的服務器大部分都自動十幾塊4T硬盤,這樣的服務器是不是影響存儲性能和數據庫的性能?

答:要看數據庫真實的iops需求是多少,你這些磁盤是如何布局的,文件系統是如何設置的。 

【問題8】Oracle rac集群在企業生產上除了使用ASM,企業使用的還有哪些?

答:rac除了用asm,在生產環境裏面,cfs是非常多的,也是非常穩定的。 

【問題9】asm是文件系統嗎?

答:asm是專門為oracle數據庫設計的一個存儲管理系統,可以簡單的理解成一個特殊的文件系統。 

【問題10】共享文件系統有哪些?哪個比較穩定?

答:真正意義上的共享文件系統有IBM的GPFS,VERITAS的cfs;GPFS在某些場合下不適用,比如高並發條件下的小塊數據訪問。我推薦用CFS 。

 

【問題11】對於DBA來說需要掌握的外圍知識逐漸增多,當然包括今天討論的話題,那麽,我們對存儲了解到什麽深度能滿足DBA工作的需要?另外有什麽好的書可推薦麽?

答:我覺得這些知識需要慢慢積累,需要理論書籍跟實踐結合。存儲的知識可以看看《storage explian》,這是一本專業的講存儲的書籍,講的比較透徹,不是西瓜哥和冬瓜個那樣娛樂化的零散片面的講。 

【問題12】數據庫本身提供了一些可擴展的方案,但很多廠家都還在做自己的分布式訪問中間件或分布式DB,請問您怎麽看這兩者後續的發展?

答:我覺得這個問題是仁者見仁智者見智,沒有固定答案的。數據庫支持提供一個數據集的組織,查找和存儲的功能,具體還是要看應用程序的需求。如果能夠滿足應用程序的需求,那麽就是好的;如果不能很好地滿足需求,功能在強大,最終的結果可能是然並卵。

延伸阅读

    评论