對(duì)象存儲(chǔ)服務(wù)(Object Storage Service,簡(jiǎn)稱OSS),是百分點(diǎn)對(duì)外提供的海量、安全、低成本、高可靠的對(duì)象存儲(chǔ)服務(wù)。用戶可以通過簡(jiǎn)單的REST接口,進(jìn)行數(shù)據(jù)的上傳和下載。同時(shí),OSS提供Java語言的SDK,簡(jiǎn)化用戶的編程?;贠SS,用戶可以搭建出各種個(gè)人和企業(yè)數(shù)據(jù)備份、業(yè)務(wù)數(shù)據(jù)應(yīng)用等基于大規(guī)模數(shù)據(jù)存儲(chǔ)的服務(wù)。同時(shí)OSS還可以與其他組件搭配使用,廣泛應(yīng)用于海量數(shù)據(jù)存儲(chǔ)與備份,數(shù)據(jù)加工與處理,內(nèi)容加速分發(fā),業(yè)務(wù)數(shù)據(jù)挖掘等多種業(yè)務(wù)場(chǎng)景。
1.架構(gòu)設(shè)計(jì)
基于對(duì)OSS的要求,我們?cè)O(shè)計(jì)的架構(gòu)如下圖所示:
我們采用了HBase+Ceph來進(jìn)行底層存儲(chǔ),對(duì)于小于1MB的數(shù)據(jù)進(jìn)入HBase,對(duì)于大于1MB的數(shù)據(jù)進(jìn)入Ceph,同時(shí)數(shù)據(jù)通過Tomcat提供對(duì)外服務(wù)?;谏厦娴募軜?gòu),我們的OSS可以實(shí)現(xiàn)以下的性能目標(biāo)。
1.1 高吞吐性
OSS的底層存儲(chǔ)充分利用各組件的性能優(yōu)勢(shì),來使整個(gè)集群可以達(dá)到較高的吞吐量。
HBase(Hadoop Database),是一個(gè)高可靠性、高性能、面向列、可伸縮的分布式存儲(chǔ)系統(tǒng),利用HBase技術(shù)可在廉價(jià)PCServer上搭建起大規(guī)模結(jié)構(gòu)化存儲(chǔ)集群。對(duì)于小于1MB的文件寫入HBase是一個(gè)很棒的設(shè)計(jì)。
那么大于1MB的文件,我們存入哪里呢?有這么幾種方案可供我們選擇,比如Hadoop,F(xiàn)astDFS,Ceph等組件。我們最終選擇了Ceph做大文件存儲(chǔ)。
Ceph是一種為優(yōu)秀的性能、可靠性和可擴(kuò)展性而設(shè)計(jì)的統(tǒng)一的、分布式文件系統(tǒng)。Ceph的開發(fā)目標(biāo)可以簡(jiǎn)單定義為以下三項(xiàng):
1.2 高可用性
高可用性對(duì)文件存儲(chǔ)系統(tǒng)是極為重要的,因?yàn)閿?shù)據(jù)是極為寶貴的,如果數(shù)據(jù)在OSS中很容易丟失或者不可靠,那么它的存在意義就不大了。
對(duì)于OSS的高可用,我們?cè)缇妥隽松钏际鞈]的思考。HBase的數(shù)據(jù)最終存儲(chǔ)HDFS中,而HDFS是指被設(shè)計(jì)成適合運(yùn)行在通用硬件(commodity hardware)上的分布式文件系統(tǒng)(DistributedFile System)。我們可以通過定義它的多副本機(jī)制來達(dá)到它的高可用性。
和HBase類似,Ceph也可以通過多副本機(jī)制來實(shí)現(xiàn)它的高可用性。
同時(shí),我們可以定義存儲(chǔ)的文件的過期時(shí)間來避免存儲(chǔ)的文件無限增長,在我們的應(yīng)用中,默認(rèn)設(shè)置為90天。
1.3 可擴(kuò)展性
當(dāng)系統(tǒng)的吞吐量越來越大,或者存儲(chǔ)容量以及快達(dá)到OSS所能承受的流量瓶頸時(shí),我們可以通過橫向擴(kuò)展相關(guān)組件來應(yīng)對(duì)流量的變化。
對(duì)于直接對(duì)外提供Rest接口的Tomcat服務(wù),如果單Tomcat服務(wù)器達(dá)到性能瓶頸時(shí),我們可以增加Tomcat服務(wù)器來進(jìn)行橫向擴(kuò)展,同時(shí)為了對(duì)外提供統(tǒng)一的網(wǎng)關(guān),我們?cè)黾恿薒VS+Keepalived這一層來實(shí)現(xiàn),如下圖所示:
正常情況下,LVS使用DR模式代理若干臺(tái)Tomcat服務(wù)器,keepalived是實(shí)現(xiàn)LVS的高可用的。當(dāng)其中一臺(tái)LVS出現(xiàn)故障下線后,keepalived通過虛擬IP技術(shù)快速切換到另外一臺(tái)可用的LVS上。
另外對(duì)于HBase和Ceph的擴(kuò)展性是簡(jiǎn)單易于實(shí)現(xiàn)的,只需要增加待擴(kuò)展的機(jī)器,進(jìn)行相關(guān)配置,即可快速加入集群,相應(yīng)的數(shù)據(jù)也會(huì)進(jìn)行rebalance。
1.4 限流算法
在上面的功能概覽中簡(jiǎn)單的說明了在某些場(chǎng)景中我們需要進(jìn)行流量限制,那么這里將詳細(xì)介紹限流的原理。
在OSS中,我們使用Guava的RateLimiter作為限流的組件。Guava的RateLimiter的限流方式有兩種:漏桶算法和令牌桶算法。我們采用的是令牌桶算法。
對(duì)于很多應(yīng)用場(chǎng)景來說,除了要求能夠限制數(shù)據(jù)的平均傳輸速率外,還要求允許某種程度的突發(fā)傳輸。這時(shí)候漏桶算法可能就不合適了,令牌桶算法更為適合。如圖所示,令牌桶算法的原理是系統(tǒng)會(huì)以一個(gè)恒定的速度往桶里放入令牌,而如果請(qǐng)求需要被處理,則需要先從桶里獲取一個(gè)令牌,當(dāng)桶里沒有令牌可取時(shí),則拒絕服務(wù)。
我們的OSS就是采用令牌桶的方式來對(duì)流量進(jìn)行限制的,當(dāng)客戶端以某一穩(wěn)定的速率來向OSS寫入的時(shí)候,系統(tǒng)是穩(wěn)定的并且大多數(shù)的時(shí)候是這樣的。但是我們有時(shí)需要應(yīng)對(duì)流量峰值,這個(gè)時(shí)候超過我們規(guī)定的流量就會(huì)被限制?,F(xiàn)在問題來了,被限制的流量如果直接丟棄,那么可能重要的文件被丟棄,這樣顯然不符合我們對(duì)OSS定位為高可用存儲(chǔ)系統(tǒng)的要求。于是在限流的邏輯中我們加入了以下處理流程:當(dāng)流量達(dá)到系統(tǒng)的瓶頸時(shí),我們將被限流的流量寫入kafka,等到系統(tǒng)負(fù)載降低的時(shí)候,再從kafka中讀取這部分流量重放至OSS,這樣既保證了OSS的穩(wěn)定性,又解決因限流帶來的數(shù)據(jù)丟失問題。
2.功能概覽
2.1 文件上傳
客戶端以RESTFul接口方式向OSS服務(wù)器發(fā)送上傳文件的請(qǐng)求,OSS將文件存儲(chǔ)到HBase或Ceph中,然后向客戶端返回存儲(chǔ)的狀態(tài)。
我們將文件名作為存儲(chǔ)的唯一標(biāo)識(shí),這樣設(shè)計(jì)的好處有兩點(diǎn),第一,我們不需要返回用戶文件在OSS服務(wù)器的存儲(chǔ)路徑;第二,也可以避免同名文件反復(fù)上傳。
2.2 文件下載
客戶端以RESTFul接口方式帶上需要查詢的文件名請(qǐng)求OSS服務(wù)器,OSS根據(jù)文件名查詢對(duì)應(yīng)的文件,返回請(qǐng)求客戶端。
2.3 流量限制
流量限制是以一種被動(dòng)的方式來對(duì)流量進(jìn)行控制的方式。我們可以通過壓力測(cè)試來粗略估計(jì)OSS所能承受的最大壓力,然后在配置文件中配置限流的數(shù)值。這里要注意的是,需要根據(jù)業(yè)務(wù)的特點(diǎn)對(duì)限制的流量進(jìn)行處理,其一,可以完全丟棄掉被限制的流量;其二,也可以對(duì)限制的流量進(jìn)行相應(yīng)的處理。
3.場(chǎng)景分析
現(xiàn)以公司某項(xiàng)目做講解來進(jìn)一步說明OSS在項(xiàng)目中的實(shí)際應(yīng)用以及最佳實(shí)踐。
3.1 項(xiàng)目的現(xiàn)狀
3.1.1 流量情況
以中期某城市交付為基準(zhǔn):每秒約120Gb流量,每天1.5億個(gè)文件,每秒大概1800個(gè)文件。
其它各分中心的數(shù)據(jù)均為上述城市的倍數(shù),比如A中心的比例系數(shù)為33.33,那么它每秒的流量約4000Gb,每天約34億個(gè)文件,每秒大概6萬個(gè)文件,以此類推。
3.1.2 單機(jī)性能
目前單機(jī)Tomcat能支撐最大12000TPS,對(duì)于各中心每秒的數(shù)據(jù)量,單機(jī)顯然不能支撐這么大的數(shù)據(jù)量,我們需要采用Tomcat集群來支撐這么大的數(shù)據(jù)流量。
3.1.3 流量峰值
在進(jìn)行機(jī)器數(shù)以及相關(guān)硬件進(jìn)行評(píng)估時(shí),需要考慮流量峰值的情況,我們一般以正常流量的2到3倍來進(jìn)行規(guī)劃,比如,某個(gè)分中心的流量為每秒1300Gb,那么我們?cè)O(shè)計(jì)時(shí)就需要考慮峰值的情況,也就是最大能支撐每秒3900的流量。
3.2 集群的設(shè)計(jì)目標(biāo)
基于上面描述的項(xiàng)目現(xiàn)狀,經(jīng)過分析,我們的整個(gè)OSS集群需要實(shí)現(xiàn)以下設(shè)計(jì)目標(biāo):
3.3 最佳實(shí)踐
3.3.1 如何保證Tomcat單機(jī)的性能最優(yōu)
我們主要從以下幾個(gè)方面來優(yōu)化Tomcat的性能:
1)JVM內(nèi)存大小
2)最大線程數(shù)(maxThreads)
3)最大連接數(shù)(maxConnections)
4)全連接隊(duì)列長度(acceptCount)
我們選用單臺(tái)機(jī)器來測(cè)試Tomcat的性能,硬件配置如下:
Tomcat的版本選用8.5.43。
測(cè)試的目標(biāo):
測(cè)試工具使用:ApacheBench。
我們使用對(duì)比測(cè)試的方法,分別測(cè)試在上傳1KB,10KB,100KB,1M,10M,100M的時(shí)候,Tomcat各項(xiàng)指標(biāo)的數(shù)值。
Tomcat配置:maxThreads=100,minSpareThreads=10,acceptCount=102400,maxConnections=1000000,acceptorThreadCount=2
JVM配置:-Xmx16384m -Xms16384m
-Xmn1024m -XX:+UseConcMarkSweepGC
-XX:MaxPermSize=256m
1、使用NIO模型的測(cè)試結(jié)果如下:
根據(jù)以上測(cè)試結(jié)果可得出以下結(jié)論:
1)在上傳相同文件大小的情況下,隨著并發(fā)數(shù)的增大,會(huì)出現(xiàn)一定的丟包情況;
2)在相同并發(fā)量的情況下,隨著上傳文件大小增大,吞吐量會(huì)隨之下降。
2、使用APR模型的測(cè)試結(jié)果如下:
根據(jù)以上測(cè)試結(jié)果以及對(duì)比NIO模型的測(cè)試結(jié)果,我們可以得出以下結(jié)論:
1)小文件上傳APR模式不如NIO模式,大文件上傳APR模式要好于NIO模式;
2)隨著并發(fā)的增加,TPS先增加后減少,平均響應(yīng)時(shí)間不斷增加;
3)小文件應(yīng)該關(guān)注TPS,大文件應(yīng)該關(guān)注平均響應(yīng)時(shí)間;
4)小文件TPS大概在2萬到3萬之間,能接受的并發(fā)在300到500之間。
3.3.2 如何保證HBase存儲(chǔ)的穩(wěn)定性
HBase以高吞吐著稱,那么我們應(yīng)該如何在保證高吞吐的情況下,能保證穩(wěn)定的存儲(chǔ)。主要應(yīng)該關(guān)注兩個(gè)點(diǎn):
1)GC的次數(shù)以及停頓時(shí)間;
2)HBase的compaction機(jī)制。
3.3.2.1 GC調(diào)優(yōu)
由于HBase是使用Java編寫的,所以垃圾收集(GC)對(duì)HBase的影響也是很大的,我們需要適當(dāng)調(diào)整GC相關(guān)的參數(shù),使得HBase能達(dá)到較好的性能和穩(wěn)定的運(yùn)行。在JVM中,有很多種垃圾收集器,我們?cè)陧?xiàng)目中使用的是CMS GC,下面首先介紹CMS GC的工作原理,再詳細(xì)說明調(diào)優(yōu)的相關(guān)細(xì)節(jié)。
3.3.2.2 GC調(diào)優(yōu)目標(biāo)
在介紹具體的調(diào)優(yōu)技巧之前,有必要先來看看GC調(diào)優(yōu)的最終目標(biāo)和基本原則:
1)平均Minor GC時(shí)間盡可能短;
2)CMS GC次數(shù)越少越好。
3.3.2.3 HBase 場(chǎng)景內(nèi)存分析
一般來講,每種應(yīng)用都會(huì)有自己的內(nèi)存對(duì)象特性,分類來說無非就兩種:一種是對(duì)象的生存期較短的工程,比如大多數(shù)的HTTP請(qǐng)求處理工程,這類的對(duì)象可能占到所有對(duì)象的70%左右;另一種是對(duì)象生存期居多的工程,比如類似于HBase,F(xiàn)link等這類大內(nèi)存工程。這里以HBase為例,來看看具體的內(nèi)存對(duì)象:
1)RPC請(qǐng)求對(duì)象
2)Memstore對(duì)象
3)BlockCache對(duì)象
因此可以看到,HBase系統(tǒng)屬于對(duì)象生存期居多的工程,因?yàn)镚C的時(shí)候只需要將RPC這類對(duì)象生存期較短的Young區(qū)淘汰掉就可以達(dá)到最好的GC效果。
在HBase優(yōu)化中比較關(guān)鍵的兩個(gè)GC的參數(shù)。
1)年輕代Young區(qū)的大?。?/p>
2)年輕代Young區(qū)中的Survivor區(qū)的大小以及進(jìn)入老年代的閾值。
3.3.2.4 生產(chǎn)環(huán)境中的GC配置
假設(shè)我們機(jī)器的物理內(nèi)存是80G,所以根據(jù)上面的分析,我們可以對(duì)相關(guān)的參數(shù)做如下配置:
1)緩存模式采用BucketCache策略O(shè)ffheap模式
2)內(nèi)存我們采用如下配置:
-Xmx64g -Xms64g -Xmn4g -Xss256k
-XX:MaxPermSize=512m
-XX:SurvivorRatio=2
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:MaxTenuringThreshold=15
-XX:+UseCMSCompactAtFullCollection
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=75
-XX:-DisableExplicitGC
3.3.3 如何保證大流量情況下系統(tǒng)穩(wěn)定運(yùn)行
流量限制是以一種被動(dòng)的方式來對(duì)流量進(jìn)行控制的方式。我們可以通過壓力測(cè)試來粗略估計(jì)OSS所能承受的最大壓力,然后在配置文件中配置限流的數(shù)值。這里要注意的是,需要根據(jù)業(yè)務(wù)的特點(diǎn)對(duì)限制的流量進(jìn)行處理,其一,可以完全丟棄掉被限制的流量;其二,也可以對(duì)限制的流量進(jìn)行相應(yīng)的處理。
4.OSS監(jiān)控
OSS在運(yùn)行過程中,我們需要了解相關(guān)的監(jiān)控信息,比如每種文件類型在一段時(shí)間的占比,或者在一段時(shí)間的網(wǎng)絡(luò)吞吐量等等,下面就來一一介紹我們是如何來對(duì)OSS進(jìn)行監(jiān)控的吧。
4.1 以文件類型劃分的指定時(shí)間段內(nèi)的總存儲(chǔ)占比
該圖表用于統(tǒng)計(jì)當(dāng)前OSS中各文件類型存儲(chǔ)的占比。
4.2 以文件類型劃分的指定時(shí)間段內(nèi)的文件數(shù)量占比
該圖表用于統(tǒng)計(jì)當(dāng)前OSS中各文件類型數(shù)量的占比。
4.3 OSS服務(wù)指定時(shí)間段內(nèi)的網(wǎng)絡(luò)吞吐量
該圖表用于統(tǒng)計(jì)OSS的吞吐量。
4.4 OSS服務(wù)指定時(shí)間段內(nèi)的每秒并發(fā)處理數(shù)(TPS)
該圖表用于統(tǒng)計(jì)當(dāng)前OSS的負(fù)載情況。
5.結(jié)語與展望
我們認(rèn)為,OSS一定會(huì)成為一個(gè)集安全性、可靠性于一體的底層存儲(chǔ)服務(wù)?;贠SS,在公安領(lǐng)域可以存儲(chǔ)天網(wǎng)中的卡口和視頻數(shù)據(jù),并與公安內(nèi)部的其他應(yīng)用形成一個(gè)基于高可用存儲(chǔ)、多方向應(yīng)用的解決方案;在社會(huì)治理方面,可以存儲(chǔ)網(wǎng)絡(luò)上的各種類型的數(shù)據(jù),包括文字、音頻以及視頻,通過使用人工智能分析其中的關(guān)聯(lián)性,為社會(huì)提供更安全的保證。