編者按
在數字政府領域,許多項目中都有各種類型的檔案,它們有不同的大小、不同的用途,甚至編碼方式都會千差萬别。我們希望通過OSS來将這些檔案按照一定的規則存儲起來,在我們需要的時候,能很快的取出來,并且應用到目前的項目中,甚至能和其他的應用系統內建起來,形成一整套的基于OSS存儲的生态系統。百分點基于實踐探索自主研發出了OSS,可以将海量的網頁内容、圖檔、音視訊等非結構化資料,在高并發的場景下被快速、準确的存儲及友善的下載下傳。

對象存儲服務(Object Storage Service,簡稱OSS),是百分點對外提供的海量、安全、低成本、高可靠的對象存儲服務。使用者可以通過簡單的REST接口,進行資料的上傳和下載下傳。同時,OSS提供Java語言的SDK,簡化使用者的程式設計。基于OSS,使用者可以搭建出各種個人和企業資料備份、業務資料應用等基于大規模資料存儲的服務。同時OSS還可以與其他元件搭配使用,廣泛應用于海量資料存儲與備份,資料加工與處理,内容加速分發,業務資料挖掘等多種業務場景。
1.架構設計
基于對OSS的要求,我們設計的架構如下圖所示:
我們采用了HBase+Ceph來進行底層存儲,對于小于1MB的資料進入HBase,對于大于1MB的資料進入Ceph,同時資料通過Tomcat提供對外服務。基于上面的架構,我們的OSS可以實作以下的性能目标。
1.1 高吞吐性
OSS的底層存儲充分利用各元件的性能優勢,來使整個叢集可以達到較高的吞吐量。
HBase(Hadoop Database),是一個高可靠性、高性能、面向列、可伸縮的分布式存儲系統,利用HBase技術可在廉價PCServer上搭建起大規模結構化存儲叢集。對于小于1MB的檔案寫入HBase是一個很棒的設計。
那麼大于1MB的檔案,我們存入哪裡呢?有這麼幾種方案可供我們選擇,比如Hadoop,FastDFS,Ceph等元件。我們最終選擇了Ceph做大檔案存儲。
Ceph是一種為優秀的性能、可靠性和可擴充性而設計的統一的、分布式檔案系統。Ceph的開發目标可以簡單定義為以下三項:
- 可輕松擴充到數PB容量
- 支援多種工作負載的高性能
- 高可靠性
1.2 高可用性
高可用性對檔案存儲系統是極為重要的,因為資料是極為寶貴的,如果資料在OSS中很容易丢失或者不可靠,那麼它的存在意義就不大了。
對于OSS的高可用,我們早就做了深思熟慮的思考。HBase的資料最終存儲HDFS中,而HDFS是指被設計成适合運作在通用硬體(commodity hardware)上的分布式檔案系統(DistributedFile System)。我們可以通過定義它的多副本機制來達到它的高可用性。
和HBase類似,Ceph也可以通過多副本機制來實作它的高可用性。
同時,我們可以定義存儲的檔案的過期時間來避免存儲的檔案無限增長,在我們的應用中,預設設定為90天。
1.3 可擴充性
當系統的吞吐量越來越大,或者存儲容量以及快達到OSS所能承受的流量瓶頸時,我們可以通過橫向擴充相關元件來應對流量的變化。
對于直接對外提供Rest接口的Tomcat服務,如果當Tomcat伺服器達到性能瓶頸時,我們可以增加Tomcat伺服器來進行橫向擴充,同時為了對外提供統一的網關,我們增加了LVS+Keepalived這一層來實作,如下圖所示:
正常情況下,LVS使用DR模式代理若幹台Tomcat伺服器,keepalived是實作LVS的高可用的。當其中一台LVS出現故障下線後,keepalived通過虛拟IP技術快速切換到另外一台可用的LVS上。
另外對于HBase和Ceph的擴充性是簡單易于實作的,隻需要增加待擴充的機器,進行相關配置,即可快速加入叢集,相應的資料也會進行rebalance。
1.4 限流算法
在上面的功能概覽中簡單的說明了在某些場景中我們需要進行流量限制,那麼這裡将詳細介紹限流的原理。
在OSS中,我們使用Guava的RateLimiter作為限流的元件。Guava的RateLimiter的限流方式有兩種:漏桶算法和令牌桶算法。我們采用的是令牌桶算法。
對于很多應用場景來說,除了要求能夠限制資料的平均傳輸速率外,還要求允許某種程度的突發傳輸。這時候漏桶算法可能就不合适了,令牌桶算法更為适合。如圖所示,令牌桶算法的原理是系統會以一個恒定的速度往桶裡放入令牌,而如果請求需要被處理,則需要先從桶裡擷取一個令牌,當桶裡沒有令牌可取時,則拒絕服務。
我們的OSS就是采用令牌桶的方式來對流量進行限制的,當用戶端以某一穩定的速率來向OSS寫入的時候,系統是穩定的并且大多數的時候是這樣的。但是我們有時需要應對流量峰值,這個時候超過我們規定的流量就會被限制。現在問題來了,被限制的流量如果直接丢棄,那麼可能重要的檔案被丢棄,這樣顯然不符合我們對OSS定位為高可用存儲系統的要求。于是在限流的邏輯中我們加入了以下處理流程:當流量達到系統的瓶頸時,我們将被限流的流量寫入kafka,等到系統負載降低的時候,再從kafka中讀取這部分流量重放至OSS,這樣既保證了OSS的穩定性,又解決因限流帶來的資料丢失問題。
2.功能概覽
2.1 檔案上傳
用戶端以RESTFul接口方式向OSS伺服器發送上傳檔案的請求,OSS将檔案存儲到HBase或Ceph中,然後向用戶端傳回存儲的狀态。
我們将檔案名作為存儲的唯一辨別,這樣設計的好處有兩點,第一,我們不需要傳回使用者檔案在OSS伺服器的存儲路徑;第二,也可以避免同名檔案反複上傳。
2.2 檔案下載下傳
用戶端以RESTFul接口方式帶上需要查詢的檔案名請求OSS伺服器,OSS根據檔案名查詢對應的檔案,傳回請求用戶端。
2.3 流量限制
流量限制是以一種被動的方式來對流量進行控制的方式。我們可以通過壓力測試來粗略估計OSS所能承受的最大壓力,然後在配置檔案中配置限流的數值。這裡要注意的是,需要根據業務的特點對限制的流量進行處理,其一,可以完全丢棄掉被限制的流量;其二,也可以對限制的流量進行相應的處理。
3.場景分析
現以公司某項目做講解來進一步說明OSS在項目中的實際應用以及最佳實踐。
3.1 項目的現狀
3.1.1 流量情況
以中期某城市傳遞為基準:每秒約120Gb流量,每天1.5億個檔案,每秒大概1800個檔案。
其它各分中心的資料均為上述城市的倍數,比如A中心的比例系數為33.33,那麼它每秒的流量約4000Gb,每天約34億個檔案,每秒大概6萬個檔案,以此類推。
3.1.2 單機性能
目前單機Tomcat能支撐最大12000TPS,對于各中心每秒的資料量,單機顯然不能支撐這麼大的資料量,我們需要采用Tomcat叢集來支撐這麼大的資料流量。
3.1.3 流量峰值
在進行機器數以及相關硬體進行評估時,需要考慮流量峰值的情況,我們一般以正常流量的2到3倍來進行規劃,比如,某個分中心的流量為每秒1300Gb,那麼我們設計時就需要考慮峰值的情況,也就是最大能支撐每秒3900的流量。
3.2 叢集的設計目标
基于上面描述的項目現狀,經過分析,我們的整個OSS叢集需要實作以下設計目标:
- 各中心采用Tomcat叢集來支撐資料流量
- 各中心的流量均衡達到每台Tomcat伺服器
- 負載均衡裝置的高可用
- 存儲服務的穩定性
3.3 最佳實踐
3.3.1 如何保證Tomcat單機的性能最優
我們主要從以下幾個方面來優化Tomcat的性能:
1)JVM記憶體大小
2)最大線程數(maxThreads)
3)最大連接配接數(maxConnections)
4)全連接配接隊列長度(acceptCount)
我們選用單台機器來測試Tomcat的性能,硬體配置如下:
Tomcat的版本選用8.5.43。
測試的目标:
- 單台Tomcat支援的最大并發數
- 單台Tomcat支援的最大TPS
- NIO模型和APR模型的性能對比
測試工具使用:ApacheBench。
我們使用對比測試的方法,分别測試在上傳1KB,10KB,100KB,1M,10M,100M的時候,Tomcat各項名額的數值。
Tomcat配置:maxThreads=100,minSpareThreads=10,acceptCount=102400,maxConnections=1000000,acceptorThreadCount=2
JVM配置:-Xmx16384m -Xms16384m
-Xmn1024m -XX:+UseConcMarkSweepGC
-XX:MaxPermSize=256m
1、使用NIO模型的測試結果如下:
根據以上測試結果可得出以下結論:
1)在上傳相同檔案大小的情況下,随着并發數的增大,會出現一定的丢包情況;
2)在相同并發量的情況下,随着上傳檔案大小增大,吞吐量會随之下降。
2、使用APR模型的測試結果如下:
根據以上測試結果以及對比NIO模型的測試結果,我們可以得出以下結論:
1)小檔案上傳APR模式不如NIO模式,大檔案上傳APR模式要好于NIO模式;
2)随着并發的增加,TPS先增加後減少,平均響應時間不斷增加;
3)小檔案應該關注TPS,大檔案應該關注平均響應時間;
4)小檔案TPS大概在2萬到3萬之間,能接受的并發在300到500之間。
3.3.2 如何保證HBase存儲的穩定性
HBase以高吞吐著稱,那麼我們應該如何在保證高吞吐的情況下,能保證穩定的存儲。主要應該關注兩個點:
1)GC的次數以及停頓時間;
2)HBase的compaction機制。
3.3.2.1 GC調優
由于HBase是使用Java編寫的,是以垃圾收集(GC)對HBase的影響也是很大的,我們需要适當調整GC相關的參數,使得HBase能達到較好的性能和穩定的運作。在JVM中,有很多種垃圾收集器,我們在項目中使用的是CMS GC,下面首先介紹CMS GC的工作原理,再詳細說明調優的相關細節。
3.3.2.2 GC調優目标
在介紹具體的調優技巧之前,有必要先來看看GC調優的最終目标和基本原則:
1)平均Minor GC時間盡可能短;
2)CMS GC次數越少越好。
3.3.2.3 HBase 場景記憶體分析
一般來講,每種應用都會有自己的記憶體對象特性,分類來說無非就兩種:一種是對象的生存期較短的工程,比如大多數的HTTP請求處理工程,這類的對象可能占到所有對象的70%左右;另一種是對象生存期居多的工程,比如類似于HBase,Flink等這類大記憶體工程。這裡以HBase為例,來看看具體的記憶體對象:
1)RPC請求對象
2)Memstore對象
3)BlockCache對象
是以可以看到,HBase系統屬于對象生存期居多的工程,因為GC的時候隻需要将RPC這類對象生存期較短的Young區淘汰掉就可以達到最好的GC效果。
在HBase優化中比較關鍵的兩個GC的參數。
1)年輕代Young區的大小;
2)年輕代Young區中的Survivor區的大小以及進入老年代的門檻值。
3.3.2.4 生産環境中的GC配置
假設我們機器的實體記憶體是80G,是以根據上面的分析,我們可以對相關的參數做如下配置:
1)緩存模式采用BucketCache政策Offheap模式
2)記憶體我們采用如下配置:
-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 如何保證大流量情況下系統穩定運作
流量限制是以一種被動的方式來對流量進行控制的方式。我們可以通過壓力測試來粗略估計OSS所能承受的最大壓力,然後在配置檔案中配置限流的數值。這裡要注意的是,需要根據業務的特點對限制的流量進行處理,其一,可以完全丢棄掉被限制的流量;其二,也可以對限制的流量進行相應的處理。
4.OSS監控
OSS在運作過程中,我們需要了解相關的監控資訊,比如每種檔案類型在一段時間的占比,或者在一段時間的網絡吞吐量等等,下面就來一一介紹我們是如何來對OSS進行監控的吧。
4.1 以檔案類型劃分的指定時間段内的總存儲占比
該圖表用于統計目前OSS中各檔案類型存儲的占比。
4.2 以檔案類型劃分的指定時間段内的檔案數量占比
該圖表用于統計目前OSS中各檔案類型數量的占比。
4.3 OSS服務指定時間段内的網絡吞吐量
該圖表用于統計OSS的吞吐量。
4.4 OSS服務指定時間段内的每秒并發處理數(TPS)
該圖表用于統計目前OSS的負載情況。
5.結語與展望
我們認為,OSS一定會成為一個集安全性、可靠性于一體的底層存儲服務。基于OSS,在公安領域可以存儲天網中的卡口和視訊資料,并與公安内部的其他應用形成一個基于高可用存儲、多方向應用的解決方案;在社會治理方面,可以存儲網絡上的各種類型的資料,包括文字、音頻以及視訊,通過使用人工智能分析其中的關聯性,為社會提供更安全的保證。