編者按:隨著互聯網、大數據和人工智能等技術的發展,信息資源得到最大程度的共享,但隨之而來的海量文件存取的功能和性能問題也日漸突出。在政務領域解決方案中,對象存儲往往扮演著非常重要的角色,如全國各地的健康寶的頭像和核酸報告文件或圖片的高速并發存取,不同地區應用接口和后端存儲的快速適配等。
百分點科技基于海外多個項目的建設經驗,沉淀出基于HBase和Ceph的混合對象存儲服務,能夠有效解決海量文件高速存儲的問題,并通過寫事件通知,將小文件內容傳輸至Kafka,實現下游系統以順序方式讀取文件,提升系統整體的吞吐性能。
一、背景介紹
百分點科技早期的OSS整體架構如下圖所示,客戶端通過LVS代理向OSS服務上傳文件,OSS服務會根據文件大小路由到不同的存儲服務。
由于數據分布廣,所以OSS服務部署在不同的數據中心,每個中心OSS服務(包含存儲服務)的集群規模從十幾臺到五六十臺服務器不等,共存儲十余PB的文件數據。
雖然老版OSS通過了海量數據的考驗,但針對不同場景仍有不足,具體表現如下:
針對演示環境或中小規模數據場景,HBase和Ceph的混合方案顯得過于笨重,對于這類場景,本地文件系統或單節點的MinIO即可滿足需求;老版架構層面缺乏設計,僅完成特定場景下的基本功能,不同功能的代碼耦合性太強,很難擴展,比如文件類型探測,基于文件元數據的存儲路由等;老版不管文件大小,均使用字節數組存儲所有文件,對內存占用過大。
為提升效益,百分點大數據技術團隊對老版OSS進行了改造升級,新版OSS不僅擁有出色的文件存取能力,而且更加靈活,具體亮點功能如下:
全局插件化設計,擴展能力非常好;高性能的文件類型識別,支持數千種類型,并且支持自定義分類接口;基于元數據的鏈式過濾,如基于文件類型或其它元數據對文件進行過濾;動態限流控制,防止單臺OSS服務節點壓力過大;動態路由控制,如基于元數據動態路由至后端存儲;支持大量的存儲插件,可以基于不同場景進行差異化配置;豐富的事件通知,如讀寫通知,讀寫錯誤通知,讀寫性能通知等;支持Office及PDF等文檔的內容提取;支持自定義文件元數據信息并保存;性能增強,充分展現后端存儲及網絡的IO能力。
二、應用設計
1. 整體設計
針對老版OSS的痛點,并圍繞OSS服務功能本身,百分點科技重新設計了OSS服務,新版OSS的架構如下圖所示:
服務編排
Processor用于編排文件讀寫邏輯,可調用Router、Detector、Filter、Storage和Notification接口。所有用戶API的請求均重定向至Processor,由Processor統一管理。
文件分類
在老版OSS服務中,一大使用痛點是文件類型是不可知的,強依賴客戶端提供的僅僅幾種文件類型信息。因此,在新版設計中,百分點科技引入了文件類型探測的功能,能夠探測出文件的具體類型,比如圖片會識別為image/jpg、image/png等不同的細分類型。
鏈式過濾
在老版OSS服務中,不管文件類型和大小以及來源,上傳文件是全部存儲的,但是在客戶實際使用中,可能只會用到特定部分的數據,所以,百分點科技增加了根據來源,文件類型等的過濾鏈,過濾到用不到的文件。如果之前不需要某種類型文件,現在需要了,修改過濾規則即可。
動態路由
在老版OSS服務中,我們使用HBase+Ceph作為后端的存儲服務,使用文件大小來決定是存入HBase還是Ceph。但這個邏輯的實現代碼耦合性很強,想要增加其他的規則很麻煩。因此,在新服務中將這個功能抽取成路由插件,可以自定義規則實現動態路由。
內容提取
在老版OSS服務中,對于office和PDF類等文檔,在ES中是索引不到文檔內容的,在新服務中,我們在上傳文件時增加了文件類型的探測,如果探測到是office和PDF類等文檔,則通過Tika提取出內容,最終內容存入到ES中就可以檢索了。
2. API接口設計
API層主要設計了如下幾個API:
上傳接口
POST
/upload?file_id=eb42cf02-9865-11ec-b909-0242ac120002&file_name=Meeting.pdf
下載接口
GET /download?file_id=eb42cf02-9865-11ec-b909-0242ac120002
批量下載接口
GET /batchDownload
{"fileIds": "eb42cf02-9865-11ec-b909-0242ac120002, 629fe326-9868-11ec-b909-0242ac120002"}
配額查詢
GET /getAvailableTokens
3. 類接口設計
這樣通過接口的方式實現了各個組件的定義,具體的功能實現在具體組件的實現中實現,具有很大的靈活性和擴展性。
如上面類關系圖所示,存儲可以選擇HBase或者S3協議兼容型的存儲。同時,各個組件的選擇用配置參數的方式配置在配置文件中,這樣切換不同類型存儲或者不同消息通知等組件的時候,修改配置文件就可以實現。
4. 配置設計
服務的配置基于SpringBoot的YML配置文件進行配置,但是為了靈活控制服務各插件的行為和功能,我們使用了SpringBoot動態注入Bean的方式類來生成具體的插件。
具體代碼如下:
public class SizeBasedRouter implements Router {
private String id;
private String smallFileStorageId;
private String largeFileStorageId;
......
}
@Bean(name = "router")
@Scope("singleton")
public Router router() throws Exception {
Map<string, object="">config = processorProperties.getRouter();
String klass = MapUtils.getString(config, "class");
Object object = newObject(klass, config);
return (Router) object;
}
privateT newObject(String className, Map<string, object="">properties) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
Assert.hasLength(className, "Class property is mandatory");
Class klass = Class.forName(className);
Object object = klass.newInstance();
BeanUtils.populate(object, properties);
return (T) object;
}
5. 插件設計Processor
Processor用于編排文件讀寫邏輯,可調用Router,Detector,Filter,Storage和Notification接口。所有用戶API的請求均重定向至Processor,由Processor統一管理。
Detector
Detector用于文件類型識別。本系統提供FastDetector,CustomDefaultDetector, ExtraOfficeDetector, FastStringDetector, StringDetector,TokenDetector和TextDetector等。
基于Tika類型探測的基礎上進行擴展,通過Stream頭尾字節,綜合運用了Tika自身和自定義的擴展探測能力,可以實現對上傳文件類型的快速探測,不同文件類型的探測能力達到10w/s,甚至100w/s。
其中,帶Fast前綴的為優化版本, 適合海量數據的文件類型探測,單線程探測性能在每秒數萬至百萬級別。
Filter
Filter用于文件過濾,因為很多文件是沒有價值的圖片/js/css/二進制文件等,為了提高OSS的整體效率,實現了基于網站和類型的文件過濾功能。
文件過濾正則示例:
"*:+|+text/html|+text/xml|+text/plain|+application/*json*|+application/*xml*|+application/*form*|+message/*|+multipart/*
|+application/pdf|+application/*office*|+application/*word*|+application/*excel*|+application/*powerpoint*
|+application/*document*|+application/zip|+application/rar|-*/*"
RateLimiter
RateLimiter用于限流,根據既定規則在請求過載的時候進行限流。
Router
Router用于對讀寫請求進行路由,以實現大小文件分發、按類型分發等功能,可同時路由到多個存儲以實現讀負載均衡或雙寫等特殊場景。此外,Router方法可返回null值,表示該對象被過濾??砂⊿ingleRouter,SizeBasedRouter。如果在寫時路由變量多于讀時路由變量,則可能需要使用緩存記錄文件ID、文件路徑及存儲ID間的關系。
Storage
Storage用于調用實際的存儲組件進行讀寫,已兼容HBase,FastDFS和Ceph、 SeaweedFS、MinIO等兼容S3協議存儲,如果要實現一個服務目前不支持的后端存儲,只需要實現相應后端存儲的Storage插件即可。
Notification
Notification用于調用各類通知組件,用于讀寫事件、錯誤及性能問題的通知,如果需要對文件進行進一步處理,也可以通過Spark或者Flink消費Kafka中的數據進行處理。
6. 監控設計
OSS服務監控主要使用Prometheus+Grafana實現,各組件使用各自Exporter,或者自身作為Endpoint為Prometheus提供監控數據,Grafana負責監控展示。通過監控能夠觀測到集群的整體運行情況,及時告警出現的問題,方便問題排查。
業務監控
主要是用來監控OSS的吞吐情況,如下圖,顯示的是OSS每秒上傳文件的個數。
應用系統監控
主要是監控OSS服務的內存使用和垃圾回收情況。
后端存儲監控
因為使用HBase和Ceph作為混合存儲,因此后端存儲監控也分為HBase和Ceph的監控。
三、性能測試
1.測試目標
通過Jmeter進行壓力測試,得出OSS服務對于不同類型、不同大小文件的吞吐情況,以驗證新版OSS服務是否達到設計之初的目標,并將測試數據用作后續OSS集群規劃的重要依據;在壓測的過程中通過Jprofiler進行觀測,找出性能瓶頸點并進行優化,最終提高服務的整體性能。
2. 測試工具
性能壓測工具:Apachejmeter性能分析工具:Jprofiler監控工具:Prometheus+Grafna
5. 測試用例
對于不同類型和大小的測試用例,在File Path中指定相應的文件,URL中最后一個字段為文件名,使用Jmeter提供的UUID函數隨機生成不同的文件名以使文件存入HBase不同的Region里面。
通過對不同類型文件的上傳測試可以得出不同類型文件的吞吐情況,因為新版OSS服務增加了對無用類型文件的過濾,所以即使相同大小的兩個文件,如果其中一個文件被Filter組件過濾掉,兩個文件的吞吐量會相差很大。
6. 測試結果
在文件沒被過濾的情況下,性能基本與老版OSS性能持平,不同的文件大小下各有差異;在多類型文件混合負載測試,性能達到78,000/s,遠遠優于老版OSS,并且在過濾掉數據后能節省不少存儲空間。
具體各類型文件的測試結果如下:
結語
新版可插拔OSS架構設計不僅擁有出色的文件存取能力,而且更加靈活,文件存儲服務是百分點科技常用場景之一,結合數據特點,部署靈活可擴展并且高性能的文件存儲服務,不但能更好地滿足客戶需求,也能在一定業務場景下節省大量的存儲服務器,是對相關業務整體解決方案的一大助力。
目前,該方案已經投入到百分點科技CBB(Common Building Block)等項目建設中,相信隨著實踐經驗的累積和技術的不斷優化升級,百分點科技將會為客戶提供更加完善的OSS服務。