摘要:在修改完成之后將數(shù)據(jù)寫(xiě)入分布式存儲(chǔ)某地址,并標(biāo)記新數(shù)據(jù)的地址為該數(shù)據(jù)源地址,控制起來(lái)比較復(fù)雜,由于沒(méi)有統(tǒng)一的服務(wù)實(shí)例地址,本地操作之間互不知曉,所以不支持并行寫(xiě)入。
簡(jiǎn)單描述需求,當(dāng)前我們的分析型數(shù)據(jù)都是不可變的,且每次的分析都是要將整體數(shù)據(jù)都加載到計(jì)算節(jié)點(diǎn)進(jìn)行分析計(jì)算,所以基礎(chǔ)的存儲(chǔ)和緩存都是面向文件的,并不支持對(duì)某一行的修改,如果需要Update某些行或者插入新的記錄,需要將增量修改與原數(shù)據(jù)源聯(lián)合進(jìn)行復(fù)雜的合并操作,對(duì)于經(jīng)常需要修改的數(shù)據(jù)源尤其是更新某些行的屬性值不那么方便,如果只是Append還好,并且還有對(duì)這個(gè)數(shù)據(jù)源的實(shí)時(shí)查詢(xún)需求,用戶(hù)希望能夠在頁(yè)面上進(jìn)行交互式查詢(xún),要求響應(yīng)速度亞秒級(jí)別。
看起來(lái)這個(gè)需求很像是一個(gè)數(shù)據(jù)庫(kù)所擅長(zhǎng)的,但是從另外的角度看,這并不是典型的數(shù)據(jù)庫(kù)的應(yīng)用場(chǎng)景,我們平時(shí)使用數(shù)據(jù)庫(kù)都是作為某個(gè)成熟的業(yè)務(wù)場(chǎng)景的數(shù)據(jù)保存,這個(gè)數(shù)據(jù)一般是提前定義好的結(jié)構(gòu),數(shù)量可以很大但是數(shù)一個(gè)或者一組數(shù)據(jù)庫(kù)實(shí)例服務(wù)組合在一起的這個(gè)集群,其中的表格種類(lèi)一般是有限的幾十最多幾百個(gè),而在我們的產(chǎn)品中,這種可變數(shù)據(jù)源不屬于產(chǎn)品的結(jié)構(gòu)化數(shù)據(jù),而是用戶(hù)所自定義的個(gè)人數(shù)據(jù),屬于數(shù)據(jù)里邊的數(shù)據(jù),格式多種多樣,作為一個(gè)個(gè)獨(dú)立的數(shù)據(jù)源,且使用的頻率非常低,有可能存在很大量的這種數(shù)據(jù)源,每個(gè)的結(jié)構(gòu)完全不同且屬于不同的用戶(hù),有可能一天也用不上一次,使用數(shù)據(jù)庫(kù)來(lái)管理這種低頻數(shù)據(jù)對(duì)資源有些浪費(fèi),大概可以采用的方案有以下三種:
1. 分布式數(shù)據(jù)庫(kù):也就是上邊提到的,數(shù)據(jù)不再以文件的形式存在于分布式存儲(chǔ)中,而是直接寫(xiě)入到支持索引和復(fù)雜查詢(xún)的數(shù)據(jù)庫(kù)中,這個(gè)數(shù)據(jù)庫(kù)可以支持各種存儲(chǔ)結(jié)構(gòu),文檔、圖、key-value最好都支持,最好是支持很方便橫向的擴(kuò)展,能夠無(wú)限制的新建很多的數(shù)據(jù)庫(kù)和表,并且可以控制將表加載到內(nèi)存以及釋放內(nèi)存,以減少資源的占用。從NOSQL Databases這個(gè)網(wǎng)站看了比較了很多的數(shù)據(jù)庫(kù),目前看來(lái)支持以上要求的數(shù)據(jù)庫(kù)有RethinkDB和ArangoDB(ArangoDB on Github),Mongodb由于有明確的命名空間數(shù)量限制,所以創(chuàng)建表有數(shù)量限制,暫時(shí)不考慮,RethinkDB理念不錯(cuò)且支持對(duì)表的加載釋放,API和文檔非常友好,然而這家公司已經(jīng)被收購(gòu),產(chǎn)品未來(lái)前景不明朗,而ArangoDB相對(duì)來(lái)說(shuō)很小眾,支持的數(shù)據(jù)模型和索引種類(lèi)很多,使用起來(lái)也相對(duì)比較靈活,運(yùn)行效率也不錯(cuò),可以作為首選考慮。
優(yōu)勢(shì)就是使用起來(lái)簡(jiǎn)單,數(shù)據(jù)采用傳統(tǒng)的數(shù)據(jù)庫(kù)增刪改語(yǔ)句寫(xiě)入到數(shù)據(jù)庫(kù)中,查詢(xún)也就直接使用索引,執(zhí)行效率較高,使用數(shù)據(jù)庫(kù)的引擎可以避免我們自己去處理各種原始數(shù)據(jù)和增量數(shù)據(jù)的合并,以Write-Ahead-Log(WAL)系統(tǒng)為例,其實(shí)所有的修改操作都是直接寫(xiě)入日志,由數(shù)據(jù)庫(kù)引擎去尋找對(duì)應(yīng)的數(shù)據(jù)同步或者異步的將操作反應(yīng)到底層的數(shù)據(jù)庫(kù)存儲(chǔ)中,可能是某種自定義的文件結(jié)構(gòu),也可能是某種更小巧的嵌入式數(shù)據(jù)庫(kù)。最終數(shù)據(jù)的存在形式一般是一個(gè)方便插入的樹(shù)型結(jié)構(gòu),常見(jiàn)的有B+樹(shù),LSM樹(shù)。
缺點(diǎn)也比較明顯,一是資源的占用,用戶(hù)的數(shù)據(jù)作為低頻使用數(shù)據(jù)使用數(shù)據(jù)庫(kù)來(lái)做托管相對(duì)比較昂貴,如果支持從內(nèi)存中釋放還可以減少數(shù)據(jù)庫(kù)自身的緩存處理壓力,如果表的數(shù)據(jù)很大數(shù)量很多則壓力會(huì)更大,二是寫(xiě)入速度受限于數(shù)據(jù)庫(kù)集群的處理能力,比如有大量的插入時(shí)需要路由節(jié)點(diǎn)的運(yùn)行效率足夠高,與Alluxio這種直接寫(xiě)本地緩存的速度有較大的差距,另外插入的過(guò)程中需要建立大量的連接,否則單連接的循環(huán)寫(xiě)入速度會(huì)非常慢,三是跟Spark等分布式處理框架的結(jié)合,目前數(shù)據(jù)的輸入輸出都是類(lèi)Hadoop文件的,如果直接讀取或者寫(xiě)入數(shù)據(jù)庫(kù),需要自己開(kāi)發(fā),目前這方便比較少見(jiàn),大家的分析型數(shù)據(jù)要么是直接從某系統(tǒng)導(dǎo)出要么就是直接生成的日志,很少直接使用分布式計(jì)算引擎去讀取已經(jīng)結(jié)構(gòu)化的帶索引的數(shù)據(jù)庫(kù),這樣也會(huì)加大當(dāng)前支持業(yè)務(wù)產(chǎn)品服務(wù)的數(shù)據(jù)庫(kù)的壓力。四是分析型數(shù)據(jù)的使用,假如這個(gè)數(shù)據(jù)源也會(huì)經(jīng)常的跟其他數(shù)據(jù)聯(lián)合或者獨(dú)立的進(jìn)行復(fù)雜的統(tǒng)計(jì)分析,這時(shí)典型的場(chǎng)景會(huì)通過(guò)Spark將數(shù)據(jù)都加載到內(nèi)存中,相當(dāng)于一次將數(shù)據(jù)庫(kù)全表導(dǎo)出的過(guò)程,比直接讀一個(gè)幾百M(fèi)的文件要慢很多。
2. 采用嵌入式數(shù)據(jù)庫(kù)嵌入式數(shù)據(jù)庫(kù)相對(duì)分布式數(shù)據(jù)庫(kù)更靈活,只需要在數(shù)據(jù)需要進(jìn)行讀寫(xiě)的時(shí)候啟動(dòng)一個(gè)實(shí)例供調(diào)用,不用的時(shí)候數(shù)據(jù)以文件的形式存在于系統(tǒng)中,對(duì)資源的消耗低,同時(shí)具有數(shù)據(jù)庫(kù)讀寫(xiě)的各種優(yōu)勢(shì)。缺點(diǎn)是文件只能存在于本地,如果我們需要以統(tǒng)一的存儲(chǔ)來(lái)作為嵌入式數(shù)據(jù)的來(lái)源,每次修改都需要去遠(yuǎn)程分布式文件系統(tǒng)去比較數(shù)據(jù)是否有更新,如果有需要加鎖并下載數(shù)據(jù)到本地,啟動(dòng)實(shí)例進(jìn)行讀寫(xiě),如果這時(shí)候有其他用戶(hù)想修改則只能等待這個(gè)寫(xiě)操作釋放,如果是讀操作則不影響直接下載使用。在修改完成之后將數(shù)據(jù)寫(xiě)入分布式存儲(chǔ)某地址,并標(biāo)記新數(shù)據(jù)的地址為該數(shù)據(jù)源地址,控制起來(lái)比較復(fù)雜,由于沒(méi)有統(tǒng)一的服務(wù)實(shí)例地址,本地操作之間互不知曉,所以不支持并行寫(xiě)入。同樣也有分布式數(shù)據(jù)庫(kù)的問(wèn)題,需要自己開(kāi)發(fā)Spark到嵌入式數(shù)據(jù)結(jié)構(gòu)的轉(zhuǎn)換代碼,如果有直接支持遠(yuǎn)程分布式存儲(chǔ)的嵌入式數(shù)據(jù)庫(kù)就比較完美了,當(dāng)然這種定義本身就比較矛盾,不是嵌入式數(shù)據(jù)庫(kù)的使用場(chǎng)景。有個(gè)比較有趣的數(shù)據(jù)庫(kù)是CouchBase,他家的嵌入式數(shù)據(jù)庫(kù)可以在聯(lián)網(wǎng)的時(shí)候?qū)⑿薷耐降竭h(yuǎn)程數(shù)據(jù)庫(kù),適合網(wǎng)絡(luò)環(huán)境不穩(wěn)定的移動(dòng)端,如果要在我們的產(chǎn)品中使用也存在數(shù)據(jù)同步問(wèn)題,因?yàn)閿?shù)據(jù)不是在固定的某個(gè)“移動(dòng)端”,隨著計(jì)算資源分配的不同,用戶(hù)的可變數(shù)據(jù)源可能是在任意一臺(tái)機(jī)器的任意的一個(gè)容器。另外就是嵌入式數(shù)據(jù)庫(kù)支持的數(shù)據(jù)量普遍規(guī)模較小。
3. 采用文件存儲(chǔ)+OLAP解決方案Parquet+Druid解決方案,目前我們采用Alluxio作為文件還存,HDFS或者S3作為底層的文件存儲(chǔ),具體的存儲(chǔ)格式采用了利于分析的Parquet格式,且經(jīng)過(guò)了壓縮。但是不管是Alluxio還是Partqut,都不支持對(duì)原來(lái)數(shù)據(jù)的修改,只適合于不可變的分析型數(shù)據(jù)源,假如需要對(duì)原來(lái)的數(shù)據(jù)進(jìn)行修改,需要在Spark內(nèi)部進(jìn)行數(shù)據(jù)的聯(lián)合,之后寫(xiě)入新的數(shù)據(jù)源,這個(gè)操作消耗較大,讀寫(xiě)成本高。而且直接使用SparkSQL做數(shù)據(jù)分析實(shí)時(shí)性較差,即使對(duì)DataSet做了Cache也難以在秒內(nèi)返回結(jié)果,所以需要借助于額外的索引服務(wù),這里考慮了Druid,Pinot,Kylin這三種OLAP方案,其中麒麟純粹的以絕對(duì)的空間換取時(shí)間,建立索引的時(shí)間也很長(zhǎng),使用不靈活,不考慮,前兩者區(qū)別不大,成熟度上Druid更高,LinkIn 所開(kāi)發(fā)的Pinot對(duì)非BitMap索引支持的較好,可能未來(lái)會(huì)比Druid好,但暫時(shí)不考慮。
Druid做的事情比較簡(jiǎn)單,就是根據(jù)預(yù)先定義的數(shù)據(jù)格式(包括timestamp, dimension, metric 列的屬性)將批量的和實(shí)時(shí)的數(shù)據(jù)經(jīng)過(guò)一個(gè)Indexing service來(lái)生成目標(biāo)的segment數(shù)據(jù),生成的數(shù)據(jù)經(jīng)過(guò)了壓縮,針對(duì)不同的統(tǒng)計(jì)列和分析列來(lái)生成對(duì)應(yīng)的segment數(shù)據(jù),以自己開(kāi)發(fā)的列式存儲(chǔ)的形式將這些中間索引數(shù)據(jù)保存下來(lái),用戶(hù)提交的查詢(xún)經(jīng)過(guò)broker節(jié)點(diǎn)會(huì)根據(jù)預(yù)先保存在metadata server里邊的數(shù)據(jù)找到對(duì)應(yīng)的historical節(jié)點(diǎn)或者realtime節(jié)點(diǎn)去進(jìn)行索引數(shù)據(jù)的二次查詢(xún)分析,不需要查詢(xún)的節(jié)點(diǎn)不會(huì)收到請(qǐng)求,最終結(jié)果匯總到broker返回給客戶(hù)端。作為一個(gè)額外的索引服務(wù),其數(shù)據(jù)來(lái)源可以是Hadoop文件系統(tǒng)或者兼容的協(xié)議,索引數(shù)據(jù)也可以保存到他所定義的deep storage里邊,也就是hdfs或者s3,保證數(shù)據(jù)也是分布式存儲(chǔ)的,這個(gè)額外的服務(wù)除了占用系統(tǒng)計(jì)算資源不對(duì)現(xiàn)在的存儲(chǔ)結(jié)構(gòu)造成大的影響,也可以方便的遷移或者替換,如果我們采用了數(shù)據(jù)庫(kù),這樣如果要切換一種數(shù)據(jù)庫(kù),所需要的遷移工作是巨大的。
4. ElasticSearch解決方案原始數(shù)據(jù)依然通過(guò)文件備份,同時(shí)發(fā)送給ES做索引服務(wù),支持增量更新以及一些簡(jiǎn)單的聚合運(yùn)算,優(yōu)勢(shì)在于查詢(xún)速度快,對(duì)于需要小規(guī)模結(jié)果返回的查詢(xún)來(lái)說(shuō)優(yōu)勢(shì)很大,索引同時(shí)攜帶原始數(shù)據(jù),可以作為數(shù)據(jù)庫(kù)使用,但其核心引擎又是列式存儲(chǔ),利用率很高。
ES還可以跟Spark直接連接,讀取或者寫(xiě)入都有成熟的connector可用,結(jié)合ES的索引能力和Spark的分析能力,可以滿(mǎn)足大部分的需求。
目前看來(lái),選擇哪種方案還是看具體的需求,能滿(mǎn)足產(chǎn)品的設(shè)計(jì)。
是否需要提供用戶(hù)交互界面修改數(shù)據(jù),或者每次批量的更新規(guī)模非常小,這種情況適合通過(guò)數(shù)據(jù)庫(kù)來(lái)托管關(guān)系型數(shù)據(jù)源。
是否經(jīng)常需要重新分析這個(gè)數(shù)據(jù)源,還是只是用來(lái)做實(shí)時(shí)查詢(xún)展示用,如果需要分析,就會(huì)涉及倒全量數(shù)據(jù)的讀取,適合采用文件。
轉(zhuǎn)載自:
https://medium.com/@leighton....
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/19027.html
摘要:當(dāng)活動(dòng)線(xiàn)程核心線(xiàn)程非核心線(xiàn)程達(dá)到這個(gè)數(shù)值后,后續(xù)任務(wù)將會(huì)根據(jù)來(lái)進(jìn)行拒絕策略處理。線(xiàn)程池工作原則當(dāng)線(xiàn)程池中線(xiàn)程數(shù)量小于則創(chuàng)建線(xiàn)程,并處理請(qǐng)求。當(dāng)線(xiàn)程池中的數(shù)量等于最大線(xiàn)程數(shù)時(shí)默默丟棄不能執(zhí)行的新加任務(wù),不報(bào)任何異常。 spring-cache使用記錄 spring-cache的使用記錄,坑點(diǎn)記錄以及采用的解決方案 深入分析 java 線(xiàn)程池的實(shí)現(xiàn)原理 在這篇文章中,作者有條不紊的將 ja...
閱讀 3335·2021-11-23 09:51
閱讀 2977·2021-10-28 09:33
閱讀 933·2021-10-08 10:04
閱讀 3730·2021-09-22 15:13
閱讀 1046·2019-08-30 15:55
閱讀 2932·2019-08-30 15:44
閱讀 596·2019-08-30 13:04
閱讀 2961·2019-08-30 12:56