董昭通,李小勇
(上海交通大學(xué) 網(wǎng)絡(luò)空間安全學(xué)院,上海 200240)
大數(shù)據(jù)處理平臺(tái)主要由上層的分布式計(jì)算組件和底層的分布式存儲(chǔ)系統(tǒng)兩層構(gòu)成。存儲(chǔ)層的熱門(mén)產(chǎn)品主要有HDFS[1]、Ceph[2]及OpenStack Swift[3]等,計(jì)算層的熱門(mén)產(chǎn)品主要有MapReduce[4]和Spark[5]等。以大數(shù)據(jù)熱門(mén)項(xiàng)目Hadoop為例,存儲(chǔ)組件為HDFS,計(jì)算組件是MapReduce或Spark。它的大致工作流程為:HDFS存儲(chǔ)海量的數(shù)據(jù)信息,計(jì)算組件啟動(dòng)job作業(yè)從HDFS中下載數(shù)據(jù)后進(jìn)行數(shù)據(jù)計(jì)算與分析;如果job2需要job1運(yùn)算后的數(shù)據(jù),需要job1將中間結(jié)果寫(xiě)入HDFS的block中,此時(shí)會(huì)產(chǎn)生硬盤(pán)甚至跨網(wǎng)絡(luò)的讀寫(xiě),同時(shí)HDFS默認(rèn)的三副本策略需要將數(shù)據(jù)鏈?zhǔn)酵扑偷饺齻€(gè)存儲(chǔ)節(jié)點(diǎn),從而進(jìn)一步造成性能的損失。若將計(jì)算節(jié)點(diǎn)一側(cè)的DRAM/SSD設(shè)備作為底層存儲(chǔ)系統(tǒng)的讀寫(xiě)緩存,一方面DRAM/SSD設(shè)備的讀寫(xiě)性能要遠(yuǎn)遠(yuǎn)高于機(jī)械硬盤(pán),另一方面緩存層與計(jì)算節(jié)點(diǎn)的網(wǎng)絡(luò)距離更加接近,所以可以減輕底層存儲(chǔ)系統(tǒng)對(duì)于上層計(jì)算應(yīng)用的性能制約,從而大幅提高大數(shù)據(jù)處理的生產(chǎn)力?;谝陨显?,研究分布式緩存系統(tǒng)具有極高價(jià)值。
目前成熟的開(kāi)源分布式緩存系統(tǒng)主要有Memcached[6]、Redis[7]及 Alluxio[8]等。
Memcached通過(guò)一致性哈希算法完成數(shù)據(jù)定位,但Memcached并不是嚴(yán)格意義上的分布式。一方面沒(méi)有完善的容錯(cuò)機(jī)制;另一方面Memcached沒(méi)有持久化機(jī)制,故存在斷電丟失數(shù)據(jù)的風(fēng)險(xiǎn)。相比之下,Redis有著比較完善的分布式機(jī)制,支持?jǐn)?shù)據(jù)備份,即master-slave主從模式的數(shù)據(jù)備份,當(dāng)服務(wù)器斷電重啟后可以通過(guò)RDB機(jī)制或AOF機(jī)制進(jìn)行數(shù)據(jù)重放而恢復(fù)數(shù)據(jù)。Alluxio是基于內(nèi)存的分布式文件系統(tǒng)。相較于Memcached和Redis,Alluxio提供文件接口,存儲(chǔ)并維護(hù)文件元數(shù)據(jù)。元數(shù)據(jù)主要記錄文件的block信息和block所處的緩存服務(wù)器信息等。Alluxio異構(gòu)管理后端大數(shù)據(jù)文件存儲(chǔ),并統(tǒng)一向大數(shù)據(jù)計(jì)算框架和平臺(tái)提供數(shù)據(jù)存儲(chǔ)服務(wù)。
對(duì)于以上解決方案,Memcached并未提供完善的容錯(cuò)機(jī)制和高可用機(jī)制,且和Redis一樣,均未向上層應(yīng)用提供文件接口。Alluxio的缺陷在于:一方面所有元數(shù)據(jù)存放于主備master節(jié)點(diǎn)的JVM中,那么在海量小文件的存儲(chǔ)場(chǎng)景下,同一namespace下元數(shù)據(jù)規(guī)模量存在瓶頸,無(wú)法達(dá)到十億或百億級(jí);另一方面,Alluxio不支持隨機(jī)讀寫(xiě),故作為分布式存儲(chǔ)系統(tǒng)的緩存子系統(tǒng)而言,無(wú)法支持更多的應(yīng)用場(chǎng)景。此外,以上三種解決方案均未很好地針對(duì)DRAM+SSD的混合緩存存儲(chǔ)進(jìn)行設(shè)計(jì)與優(yōu)化。
基于以上分析,本系統(tǒng)建立在BlueOcean Storage System(BOSS)底層存儲(chǔ)的基礎(chǔ)上,設(shè)計(jì)并實(shí)現(xiàn)了面向大數(shù)據(jù)應(yīng)用的分布式緩存子系統(tǒng)?;贒RAM+SSD混合存儲(chǔ)場(chǎng)景,支持全面的讀寫(xiě)類(lèi)型,通過(guò)優(yōu)良的設(shè)計(jì)大幅提升了底層存儲(chǔ)系統(tǒng)的讀寫(xiě)性能。
本文設(shè)計(jì)并實(shí)現(xiàn)的分布式緩存系統(tǒng)的各模塊組件與BoSS系統(tǒng)各組件之間的集成框架,如圖1所示。
圖1 緩存系統(tǒng)各組件集成框架
整個(gè)系統(tǒng)共存在3種角色,分別為緩存客戶(hù)端、緩存服務(wù)器以及元數(shù)據(jù)服務(wù)器。
2.1.1 緩存客戶(hù)端(CacheClient)
在生產(chǎn)環(huán)境下的大數(shù)據(jù)平臺(tái)中,緩存客戶(hù)端作為BoSS Client庫(kù)的一部分部署在計(jì)算節(jié)點(diǎn)上。上層計(jì)算應(yīng)用通過(guò)調(diào)用BoSS Client庫(kù)訪問(wèn)BoSS系統(tǒng),BoSS Client庫(kù)通過(guò)調(diào)用CacheClient模塊來(lái)訪問(wèn)緩存,CacheClient根據(jù)文件/對(duì)象名請(qǐng)求元數(shù)據(jù)服務(wù)器查找緩存是否命中以及該文件/對(duì)象的緩存所在位置,并請(qǐng)求對(duì)應(yīng)的緩存服務(wù)器。
2.1.2 緩存服務(wù)器(CacheServer)
緩存服務(wù)器與BoSS Client并置部署在計(jì)算節(jié)點(diǎn)上,以daemon的方式持續(xù)監(jiān)聽(tīng)特定的端口,接收Cache Client的數(shù)據(jù)訪問(wèn)請(qǐng)求。此外,管理本節(jié)點(diǎn)上的節(jié)點(diǎn)級(jí)元數(shù)據(jù)。每個(gè)CacheServer管理本地的DRAM易失性存儲(chǔ)設(shè)備和SSD持久化存儲(chǔ)設(shè)備。CacheServer接收到CacheClient的數(shù)據(jù)訪問(wèn)請(qǐng)求后,根據(jù)文件/對(duì)象名查找本機(jī)內(nèi)存中維護(hù)的元數(shù)據(jù)hashmap得出該文件/對(duì)象在該臺(tái)服務(wù)器的RAMDisk/SSD掛載路徑,從而返回DRAM/SSD中該文件/對(duì)象的數(shù)據(jù)流。
2.1.3 元數(shù)據(jù)服務(wù)器(MetaServer)
緩存系統(tǒng)的元數(shù)據(jù)由MongoDB管理,與BoSS Monitor組件并置部署在3個(gè)及以上的監(jiān)控節(jié)點(diǎn)上。每臺(tái)監(jiān)控節(jié)點(diǎn)上分別部署1個(gè)BoSS Monitor組件和1個(gè)MongoDB服 務(wù)。3個(gè) BoSS Monitor和3個(gè)MongoDB主機(jī)之間均基于raft協(xié)議實(shí)現(xiàn)primary節(jié)點(diǎn)選舉操作。緩存元數(shù)據(jù)存放在名為object_cache的collection中,每條元數(shù)據(jù)document的信息為文件/對(duì)象名到對(duì)應(yīng)的緩存服務(wù)器節(jié)點(diǎn)的映射信息。元數(shù)據(jù)的添加和刪除操作由CacheClient模塊控制。
當(dāng)CacheClient發(fā)起寫(xiě)請(qǐng)求時(shí),整體流程如下。
(1)CacheClient請(qǐng)求元數(shù)據(jù)服務(wù)器上的cache_server集合,得出當(dāng)前所有的CacheServer信息,并計(jì)算出最佳的CacheServer:
式(1)涉及到的變量的釋義如下。
①latency為CacheClient到當(dāng)前CacheServer的網(wǎng)絡(luò)延遲,若兩者在同一主機(jī),則該latency值為0。該值的獲?。好颗_(tái)CacheServer主機(jī)啟動(dòng)時(shí),會(huì)向當(dāng)前所有CacheServer發(fā)起Ping命令,分別得出所有CacheServer的平均網(wǎng)絡(luò)延遲從而建立map,latency的值則是通過(guò)查詢(xún)?cè)搈ap所得。
②weight為每臺(tái)CacheServer加入集群時(shí)寫(xiě)入MongoDB的cache_server集合中的權(quán)重值,由用戶(hù)配置文件中定義,或調(diào)用CacheClient的SetServer Weight方法設(shè)定。
③freeCap為當(dāng)前CacheServer上所管理的所有存儲(chǔ)設(shè)備的剩余空間,通過(guò)讀取MongoDB的cache_server集合得出。
(2)根據(jù)式(1)所選的最佳CacheServer,更新MongoDB中該文件/對(duì)象的全局元數(shù)據(jù)。
(3)CacheClient向該 CacheServer發(fā)起寫(xiě)請(qǐng)求,給出寫(xiě)類(lèi)型和文件/對(duì)象數(shù)據(jù)流。若寫(xiě)類(lèi)型為隨機(jī)寫(xiě),由于SSD設(shè)備存在擦寫(xiě)次數(shù)限制,故將文件/對(duì)象寫(xiě)入DRAM,并通過(guò)預(yù)先定義的同步寫(xiě)/異步寫(xiě)策略,將文件/對(duì)象數(shù)據(jù)持久化到BoSS DataServer中。如果使用異步寫(xiě)策略,則無(wú)法保證在持久化過(guò)程中該服務(wù)器突然宕機(jī)而丟失數(shù)據(jù)的問(wèn)題。若寫(xiě)類(lèi)型為順序?qū)?,則將文件/對(duì)象數(shù)據(jù)寫(xiě)入SSD中,向CacheClient返回寫(xiě)入成功的響應(yīng)后,異步將文件/對(duì)象數(shù)據(jù)更新到底層BoSS DataServer中。
當(dāng)CacheClient發(fā)起讀請(qǐng)求時(shí),CacheClient訪問(wèn)MongoDB得出該文件/對(duì)象所在的CacheServer地址后,向該CacheServer發(fā)起數(shù)據(jù)讀寫(xiě)請(qǐng)求。
根據(jù)緩存數(shù)據(jù)命中情況將有如下流程:
(1)緩存命中本地CacheServer:此時(shí)將進(jìn)行短路讀取,繞開(kāi)socket接口直接讀取本地文件系統(tǒng);
(2)緩存命中遠(yuǎn)程CacheServer:CacheClient調(diào)用socket接口,CacheServer將文件/對(duì)象數(shù)據(jù)流通過(guò)網(wǎng)絡(luò)傳輸給CacheClient節(jié)點(diǎn),數(shù)據(jù)拷貝過(guò)程通過(guò)sendfile()系統(tǒng)調(diào)用+DMA的方式進(jìn)行零拷貝網(wǎng)絡(luò)傳輸;
(3)緩存未命中:CacheClient向相應(yīng)的BoSS DataServer發(fā)起socket連接,從底層進(jìn)行讀取。緩存未命中通常發(fā)生在第一次從底層BoSS DataServer中加載或者CacheServer將該文件/對(duì)象進(jìn)行緩存替換的情況。
在計(jì)算任務(wù)較重的情況下,系統(tǒng)會(huì)產(chǎn)生大量的隨機(jī)讀寫(xiě),則緩存系統(tǒng)需要能夠承受短時(shí)間內(nèi)的高并發(fā)量請(qǐng)求,這是提高性能的關(guān)鍵。程序并發(fā)模型的解決方案通常有多進(jìn)程、多線程、線程池及I/O事件驅(qū)動(dòng)模型等。
本文設(shè)計(jì)的分布式緩存系統(tǒng)采用的是事件驅(qū)動(dòng)并發(fā)模型,基于Go語(yǔ)言編寫(xiě)實(shí)現(xiàn)。該處理模塊遵循Reactor的設(shè)計(jì)模式,將I/O協(xié)程與事件處理協(xié)程相分離。I/O協(xié)程采用epoll統(tǒng)一處理所有socket事件和設(shè)備I/O事件,事件處理協(xié)程采用協(xié)程池處理I/O協(xié)程解析好的事件消息。這樣的設(shè)計(jì)框架將使得CPU每個(gè)核心、存儲(chǔ)設(shè)備及網(wǎng)卡設(shè)備等達(dá)到最大程度的并行狀態(tài),最大程度地減少系統(tǒng)中的阻塞。
事件處理協(xié)程池的結(jié)構(gòu)體定義如下:
協(xié)程池初始化時(shí)創(chuàng)建workerNum個(gè)協(xié)程,每個(gè)協(xié)程監(jiān)聽(tīng)taskQueue channel獲取任務(wù),從而處理已準(zhǔn)備好的文件描述符。協(xié)程池通過(guò)done channel結(jié)束協(xié)程池中所有協(xié)程。添加或刪除任務(wù)到taskQueue前都需要使用mutex來(lái)鎖定隊(duì)列,以避免資源競(jìng)爭(zhēng)造成錯(cuò)誤。
對(duì)于設(shè)備I/O,采用libaio庫(kù)來(lái)完成異步I/O操作,而異步I/O操作會(huì)阻塞于libaio的io_getevent(),故socket的高并發(fā)性能將受制于設(shè)備I/O的阻塞。因此,本文設(shè)計(jì)的分布式緩存子系統(tǒng)的I/O處理協(xié)程采用epoll統(tǒng)一處理所有socket事件和設(shè)備I/O事件。對(duì)于異步I/O操作,通過(guò)Linux 2.6.22及以上版本中的eventfd,可將libaio和epoll事件處理很好地結(jié)合,具體處理流程為:
(1)創(chuàng)建一個(gè)iocb結(jié)構(gòu)體,用于處理本次異步I/O請(qǐng)求;
(2)創(chuàng)建一個(gè)eventfd,并將此eventfd設(shè)置到iocb結(jié)構(gòu)中;
(3)調(diào)用io_submit()系統(tǒng)調(diào)用提交aio請(qǐng)求;
(4)調(diào)用epoll_ctl()系統(tǒng)調(diào)用將eventfd添加到epoll中;
(5)當(dāng)eventfd可讀/可寫(xiě)時(shí),從eventfd讀出完成I/O請(qǐng)求的事件數(shù)量,并調(diào)用io_getevents()獲取到這些I/O事件。
對(duì)于異步I/O和網(wǎng)絡(luò)socket事件的統(tǒng)一處理,事件類(lèi)型也將通過(guò)eventfd的信息來(lái)判斷。I/O協(xié)程將在空閑時(shí)間段阻塞在epoll_wait()上,等待事件的完成。當(dāng)某個(gè)事件完成后,通過(guò)文件描述符判斷是否與aio事件的文件描述符相同。如果不同則為socket事件,正常處理網(wǎng)絡(luò)數(shù)據(jù)讀寫(xiě)流程;如果相同則為aio事件,調(diào)用io_getevent()獲取完成的aio請(qǐng)求,并將其回調(diào)函數(shù)添加到協(xié)程池中進(jìn)行事件的處理。
在實(shí)際的應(yīng)用場(chǎng)景中,大數(shù)據(jù)平臺(tái)將會(huì)產(chǎn)生海量的小文件,故元數(shù)據(jù)模塊的設(shè)計(jì)應(yīng)滿足至少十億級(jí)海量小文件的場(chǎng)景。若采用類(lèi)似于HDFS的master-worker結(jié)構(gòu),所有元數(shù)據(jù)信息存儲(chǔ)在主備master上,當(dāng)元數(shù)據(jù)量較大時(shí),master節(jié)點(diǎn)的內(nèi)存將會(huì)成為容量瓶頸。若采用一致性哈希算法,當(dāng)增加或移除節(jié)點(diǎn)時(shí),會(huì)有相當(dāng)一部分緩存數(shù)據(jù)需進(jìn)行遷移,那么數(shù)據(jù)遷移產(chǎn)生的I/O將會(huì)對(duì)正常業(yè)務(wù)I/O造成影響。因此,本文設(shè)計(jì)的分布式緩存系統(tǒng)的元數(shù)據(jù)模塊基于MongoDB實(shí)現(xiàn)。MongoDB可以在數(shù)據(jù)規(guī)模和性能之間取得很好的平衡,從而滿足業(yè)務(wù)需要。
本文設(shè)計(jì)的緩存子系統(tǒng)主要為兩級(jí)元數(shù)據(jù)模型,由全局元數(shù)據(jù)和節(jié)點(diǎn)級(jí)元數(shù)據(jù)組成。全局元數(shù)據(jù)存放于MongoDB中,記錄每個(gè)文件/對(duì)象映射到每個(gè)緩存數(shù)據(jù)副本所在CacheServer的信息。在選擇CacheServer時(shí),同樣根據(jù)公式選擇最佳的CacheServer。CacheServer上存放節(jié)點(diǎn)級(jí)元數(shù)據(jù),在/dev/shm中用一個(gè)hashmap存放所有文件/對(duì)象到DRAM/SSD設(shè)備掛載目錄的映射。
在寫(xiě)數(shù)據(jù)時(shí),流程為:
(1)CacheClient根據(jù)式(1)計(jì)算最佳的CacheServerIp;
(2)CacheClient將文件/對(duì)象與相應(yīng)的Cache Server的映射信息作為document插入到MongoDB中;
(3)CacheClient更新該CacheServer上的節(jié)點(diǎn)級(jí)元數(shù)據(jù)的hashmap。
上述3個(gè)過(guò)程在CacheClient通過(guò)事務(wù)保證。若失敗則進(jìn)行回滾;若在事務(wù)過(guò)程中出錯(cuò),則在之后的讀取過(guò)程中或者CacheServer的維護(hù)協(xié)程中定期清除此元數(shù)據(jù)。
執(zhí)行此事務(wù)過(guò)程中的錯(cuò)誤主要分為兩種情況。
(1)CacheClient寫(xiě)入MongoDB后發(fā)生錯(cuò)誤。此時(shí),MongoDB存在全局元數(shù)據(jù)而相應(yīng)CacheServer不存在節(jié)點(diǎn)級(jí)元數(shù)據(jù),之后讀取該文件/對(duì)象時(shí),CacheServer查詢(xún)自身節(jié)點(diǎn)級(jí)元數(shù)據(jù)時(shí)未找到該緩存數(shù)據(jù),說(shuō)明之前將該文件/對(duì)象全局元數(shù)據(jù)寫(xiě)入MongoDB后CacheClient發(fā)生了宕機(jī)或者網(wǎng)絡(luò)錯(cuò)誤,CacheServer則將MongoDB中該文件/對(duì)象的全局元數(shù)據(jù)刪除。
(2)CacheClient節(jié)點(diǎn)級(jí)元數(shù)據(jù)更新完成后文件/對(duì)象流推送過(guò)程中失敗。每臺(tái)CacheServer在啟動(dòng)時(shí)都會(huì)根據(jù)實(shí)際的緩存數(shù)據(jù)信息建立自身的節(jié)點(diǎn)元數(shù)據(jù)hashmap,因此可以保證實(shí)際的數(shù)據(jù)讀寫(xiě)不會(huì)出現(xiàn)差錯(cuò)。此外,在CacheServer運(yùn)行過(guò)程中會(huì)啟動(dòng)定期維護(hù)的子協(xié)程,對(duì)節(jié)點(diǎn)元數(shù)據(jù)和實(shí)際緩存數(shù)據(jù)進(jìn)行check,以消除長(zhǎng)時(shí)間運(yùn)行導(dǎo)致的錯(cuò)誤累積現(xiàn)象。
讀數(shù)據(jù)時(shí),流程為:
(1)根據(jù)文件/對(duì)象名和文件/對(duì)象哈希值為組合條件查詢(xún)MongoDB,得出該文件/對(duì)象所在CacheServer的IP地址;
(2)向該節(jié)點(diǎn)的CacheServer守護(hù)進(jìn)程發(fā)送讀取請(qǐng)求;
(3)CacheServer根據(jù)自身節(jié)點(diǎn)級(jí)元數(shù)據(jù),查詢(xún)hashmap得出該文件/對(duì)象所在的RAMDisk路徑或者SSD設(shè)備掛載路徑;
(4)CacheServer返回文件/對(duì)象數(shù)據(jù)流。
本文設(shè)計(jì)并實(shí)現(xiàn)的分布式緩存系統(tǒng)相關(guān)的部署集群有計(jì)算集群、存儲(chǔ)集群和MongoDB元數(shù)據(jù)集群。
3.1.1 硬件方面
每個(gè)集群內(nèi)由3臺(tái)服務(wù)器主機(jī)組成,CPU為Intel i9-9900X,主頻為 3.5 GHz,10 Cores。內(nèi)存為DDR3,1 600 MHz,容量為16 GB。網(wǎng)卡為Intel萬(wàn)兆以太網(wǎng)卡,各主機(jī)之間通過(guò)萬(wàn)兆光纖寬帶相連。計(jì)算集群內(nèi)均配備SAMSUNG 500GB SSD設(shè)備,采用NVMe協(xié)議。
3.1.2 軟件方面
計(jì)算集群內(nèi)的主機(jī)上部署CacheServer進(jìn)程,DRAM設(shè)備建立RAMDisk進(jìn)行數(shù)據(jù)讀寫(xiě)。存儲(chǔ)集群內(nèi)的服務(wù)器主機(jī)作為BoSS DataServer管理本機(jī)上的HDD。元數(shù)據(jù)集群內(nèi)的服務(wù)器主機(jī)上分別部署B(yǎng)oSS Monitor監(jiān)控進(jìn)程和MongoDB的守護(hù)進(jìn)程。
本文在計(jì)算集群內(nèi)的主機(jī)上使用fio工具調(diào)用BoSS CLient庫(kù)進(jìn)行讀寫(xiě)測(cè)試,模擬I/O負(fù)載。限于篇幅,本文的測(cè)試方案主要側(cè)重于系統(tǒng)的性能,故選用讀寫(xiě)類(lèi)型為順序讀、順序?qū)?、隨機(jī)讀和隨機(jī)寫(xiě)共4種場(chǎng)景,使用fio工具模擬不同的線程數(shù),分別對(duì)使用緩存和不使用緩存時(shí)的吞吐率變化情況或者IOPS變化情況進(jìn)行測(cè)試與分析。
圖2為順序?qū)憟?chǎng)景下帶緩存和無(wú)緩存的吞吐率變化情況,帶緩存的讀寫(xiě)性能略低于無(wú)緩存。這是由于無(wú)緩存時(shí),I/O負(fù)載直接寫(xiě)入BoSS數(shù)據(jù)服務(wù)器節(jié)點(diǎn)的HDD上。加上緩存后的寫(xiě)入流程為寫(xiě)入CacheServer的DRAM并持久化到BoSS數(shù)據(jù)服務(wù)器上。因此,并發(fā)數(shù)較低時(shí),吞吐率略低于無(wú)緩存情況。但是,當(dāng)并發(fā)數(shù)較大時(shí),由于緩存子系統(tǒng)的epoll+workerpoll的事件驅(qū)動(dòng)框架,使得CPU、硬盤(pán)、網(wǎng)卡達(dá)到了最大程度的并行狀態(tài)。因此,在并發(fā)線程數(shù)較大時(shí),有緩存的情況可以降低性能抖動(dòng)。
圖2 緩存子系統(tǒng)順序?qū)懶阅?/p>
圖3為隨機(jī)寫(xiě)場(chǎng)景下帶緩存和無(wú)緩存的IOPS變化情況。在隨機(jī)寫(xiě)場(chǎng)景下,I/O負(fù)載直接寫(xiě)入DRAM,之后在固定的時(shí)間點(diǎn)將RAMDisk中數(shù)據(jù)持久化到硬盤(pán)上。這個(gè)過(guò)程相當(dāng)于對(duì)I/O序列進(jìn)行合并排序后寫(xiě)入HDD,故節(jié)省了HDD的往返尋道時(shí)間。而HDD的性能瓶頸在于磁頭尋道,故將I/O合并排序后相當(dāng)于順序讀寫(xiě)。磁頭只需要按照同一個(gè)方向轉(zhuǎn)動(dòng),所以IOPS將會(huì)大幅增加。同時(shí),在并發(fā)度較大時(shí),帶有緩存的隨機(jī)寫(xiě)場(chǎng)景下,性能抖動(dòng)要比無(wú)緩存時(shí)好得多。
圖3 緩存子系統(tǒng)隨機(jī)寫(xiě)性能
圖4為順序讀場(chǎng)景下帶緩存和無(wú)緩存的吞吐率變化情況,圖5為隨機(jī)讀場(chǎng)景下帶緩存和無(wú)緩存時(shí)的IOPS變化情況。當(dāng)無(wú)緩存時(shí),BoSS系統(tǒng)的順序讀和隨機(jī)讀均是讀取HDD。而開(kāi)啟緩存時(shí),讀I/O將在BoSS Client側(cè)訪問(wèn)RAMDisk中的緩存;若緩存不存在或者被替換,則對(duì)BoSS DataServer側(cè)的HDD進(jìn)行讀取。若緩存命中且緩存位置在同一計(jì)算集群內(nèi)其他BoSS Client節(jié)點(diǎn),萬(wàn)兆以太網(wǎng)和RAMDisk的讀取環(huán)境也要比讀取BoSS DataServer側(cè)的HDD設(shè)備讀取性能高。上述測(cè)試場(chǎng)景排除了第一次加載冷數(shù)據(jù)的情況和緩存替換的情況,故帶緩存的I/O讀寫(xiě)要遠(yuǎn)比無(wú)緩存的I/O讀寫(xiě)的性能高。
圖4 緩存子系統(tǒng)順序讀性能
圖5 緩存子系統(tǒng)隨機(jī)讀性能
本文設(shè)計(jì)的面向大數(shù)據(jù)應(yīng)用的分布式緩存子系統(tǒng)的創(chuàng)新之處在于:(1)NoSQL全局元數(shù)據(jù)和CacheServer節(jié)點(diǎn)級(jí)元數(shù)據(jù)組成的兩級(jí)元數(shù)據(jù)模型很好地達(dá)到了元數(shù)據(jù)規(guī)模和性能之間的平衡,更加適用于海量小文件的應(yīng)用場(chǎng)景;(2)I/O事件驅(qū)動(dòng)模型采用epoll協(xié)程+workerpool的架構(gòu),epoll協(xié)程統(tǒng)一管理socket事件和異步I/O事件,workerpool處理請(qǐng)求完成后的回調(diào)函數(shù),這種架構(gòu)使得CPU、網(wǎng)卡、硬盤(pán)達(dá)到最大程度的并行狀態(tài),因此存儲(chǔ)系統(tǒng)在高并發(fā)情況下依舊能夠維持較高的吞吐量,性能平穩(wěn),波動(dòng)較小。
本系統(tǒng)的不足在于未完善緩存數(shù)據(jù)持久化過(guò)程的異步機(jī)制和持久化過(guò)程中主機(jī)斷電可能造成的數(shù)據(jù)丟失問(wèn)題。在后續(xù)工作中,將對(duì)異步持久化機(jī)制進(jìn)行完善,使本緩存系統(tǒng)成為更加穩(wěn)定、可靠、高性能的系統(tǒng)。