比特科技: 存儲、數(shù)據(jù)庫膝擂、大數(shù)據(jù)技術(shù) ? HBase原理和設(shè)計 http://www.bitstech.net/2015/09/16/hbase-architecture/
簡介
HBase —— Hadoop Database的簡稱圾旨,Google BigTable的另一種開源實現(xiàn)方式,從問世之初,就為了解決用大量廉價的機器高速存取海量數(shù)據(jù)辩稽、實現(xiàn)數(shù)據(jù)分布式存儲提供可靠的方案吵瞻。從功能上來講葛菇,HBase不折不扣是一個數(shù)據(jù)庫,與我們熟悉的Oracle橡羞、MySQL眯停、MSSQL等一樣,對外提供數(shù)據(jù)的存儲和讀取服務(wù)卿泽。而從應(yīng)用的角度來說莺债,HBase與一般的數(shù)據(jù)庫又有所區(qū)別,HBase本身的存取接口相當簡單签夭,不支持復(fù)雜的數(shù)據(jù)存取齐邦,更不支持SQL等結(jié)構(gòu)化的查詢語言;HBase也沒有除了rowkey以外的索引第租,所有的數(shù)據(jù)分布和查詢都依賴rowkey措拇。所以,HBase在表的設(shè)計上會有很嚴格的要求煌妈。架構(gòu)上儡羔,HBase是分布式數(shù)據(jù)庫的典范,這點比較像MongoDB的sharding模式璧诵,能根據(jù)鍵值的大小汰蜘,把數(shù)據(jù)分布到不同的存儲節(jié)點上,MongoDB根據(jù)configserver來定位數(shù)據(jù)落在哪個分區(qū)上之宿,HBase通過訪問Zookeeper來獲取-ROOT-表所在地址族操,通過-ROOT-表得到相應(yīng).META.表信息,從而獲取數(shù)據(jù)存儲的region位置比被。
架構(gòu)
上面提到色难,HBase是一個分布式的架構(gòu),除去底層存儲的HDFS外等缀,HBase本身從功能上可以分為三塊:Zookeeper群枷莉、Master群和RegionServer群。
Zookeeper群:HBase集群中不可缺少的重要部分尺迂,主要用于存儲Master地址笤妙、協(xié)調(diào)Master和RegionServer等上下線冒掌、存儲臨時數(shù)據(jù)等等。
Master群:Master主要是做一些管理操作蹲盘,如:region的分配股毫,手動管理操作下發(fā)等等,一般數(shù)據(jù)的讀寫操作并不需要經(jīng)過Master集群召衔,所以Master一般不需要很高的配置即可铃诬。
RegionServer群:RegionServer群是真正數(shù)據(jù)存儲的地方,每個RegionServer由若干個region組成苍凛,而一個region維護了一定區(qū)間rowkey值的數(shù)據(jù)趣席,整個結(jié)構(gòu)如下圖:
HBase結(jié)構(gòu)圖
上圖中,Zookeeper(簡稱ZK)是一個集群醇蝴,通常有奇數(shù)個ZK服務(wù)組成吩坝。Master為了服務(wù)可用性,也建議部署成集群方式哑蔫,因為Master是整個管理操作的發(fā)起者,如果Master一旦發(fā)生意外停機弧呐,整個集群將會無法進行管理操作闸迷,所以Master也必須有多個,當然多個Master也有主從之分俘枫,如何區(qū)分哪個是主腥沽,哪個是從?關(guān)鍵看哪個Master能競爭到ZK上對應(yīng)Master目錄下的鎖鸠蚪,持有該目錄鎖的Master為主Master今阳,其他從Master輪詢競爭該鎖,所以一旦主Master發(fā)生意外停機茅信,從Master很快會因為競爭到Master文件夾上的鎖而接管服務(wù)盾舌。RegionServer(簡稱RS)在非Replication模式下,整個系統(tǒng)中都是唯一的蘸鲸,也就是說妖谴,在整個非Replication的HBase集群中,每臺RS上保存的數(shù)據(jù)都不一樣酌摇,所以相對于前面兩者膝舅,該模式下的RS并不是高可用的,至少RS可能存在單點故障的問題窑多,但是由于HBase內(nèi)部數(shù)據(jù)分region存儲和region可以遷移的機制仍稀,RS服務(wù)的單點故障可能會在極小代價下很快恢復(fù),但是一旦停掉的RS上有-ROOT-或者.META.表的region埂息,那后果還是比較嚴重技潘,因為數(shù)據(jù)節(jié)點的RS停機遥巴,只會在短時間內(nèi)影響該臺RS上的region不可訪問,等到region遷移完成后即可恢復(fù)崭篡,如果是-ROOT-挪哄、.META.所在的RS停機,整個HBase的新的求情都將受到影響琉闪,因為需要通過.META.表來路由迹炼,從而尋找到region所在RS的地址。
數(shù)據(jù)組織
整個架構(gòu)中颠毙,ZK用于服務(wù)協(xié)調(diào)和整個集群運行過程中部分信息的保存和-ROOT-表地址定位斯入,Master用于集群內(nèi)部管理,所以剩下的RS主要用于處理數(shù)據(jù)蛀蜜。RS是處理數(shù)據(jù)的主要場所刻两,那么在RS內(nèi)部的數(shù)據(jù)是怎么分布的?其實RS本身只是一個容器滴某,其定義了一些功能線程磅摹,比如:數(shù)據(jù)合并線程(compact thread)、storeFile分割線程(split thread)等等霎奢。容器中的主要對象就是region户誓,region是一個表根據(jù)自身rowkey范圍劃分的一部分,一個表可以被劃分成若干部分幕侠,也就是若干個region帝美,region可以根據(jù)rowkey范圍不同而被分布在不同的RS上(當然也可以在同一個RS上,但不建議這么做)晤硕。一個RS上可以包含多個表的region悼潭,也可以只包含一個表的部分region,RS和表是兩個不同的概念舞箍。這里還有一個概念——列簇舰褪。對HBase有一些了解的人,或多或少聽說過:HBase是一個列式存儲的數(shù)據(jù)庫疏橄,而這個列式存儲中的列抵知,其實是區(qū)別于一般數(shù)據(jù)庫的列,這里的列的概念软族,就是列簇刷喜,列簇,顧名思義就是很多列的集合立砸,而在數(shù)據(jù)存儲上來講掖疮,不同列簇的數(shù)據(jù),一定是分開存儲的颗祝,即使是在同一個region內(nèi)部浊闪,不同的列簇也存儲在不同的文件夾中恼布,這樣做的好處是,一般我們定義列簇的時候搁宾,通常會把類似的數(shù)據(jù)放入同一個列簇折汞,不同的列簇分開存儲,有利于數(shù)據(jù)的壓縮盖腿,并且HBase本身支持多種壓縮方式爽待。
原理
前面介紹了HBase的一般架構(gòu),我們知道了HBase有ZK翩腐、Master和RS等組成鸟款,本節(jié)我們來介紹下HBase的基本原理,從數(shù)據(jù)訪問茂卦、RS路由到RS內(nèi)部緩存何什、數(shù)據(jù)存儲和刷寫再到region的合并和拆分等等功能。
RegionServer定位
訪問HBase通過HBase客戶端(或API)進行等龙,整個HBase提供給外部的地址处渣,其實是ZK的入口,前面也介紹了蛛砰,ZK中有保存-ROOT-所在的RS地址霍比,從-ROOT-表可以獲取.META.表信息,根據(jù).META.表可以獲取region在RS上的分布暴备,整個region尋址過程大致如下:
RS定位過程
首先,Client通過訪問ZK來請求目標數(shù)據(jù)的地址们豌。
ZK中保存了-ROOT-表的地址涯捻,所以ZK通過訪問-ROOT-表來請求數(shù)據(jù)地址。
同樣望迎,-ROOT-表中保存的是.META.的信息障癌,通過訪問.META.表來獲取具體的RS。
.META.表查詢到具體RS信息后返回具體RS地址給Client辩尊。
Client端獲取到目標地址后涛浙,然后直接向該地址發(fā)送數(shù)據(jù)請求。
上述過程其實是一個三層索引結(jié)構(gòu)摄欲,從ZK獲取-ROOT-信息轿亮,再從-ROOT-獲取.META.表信息,最后從.META.表中查到RS地址后緩存胸墙。這里有幾個問題:
既然ZK中能保存-ROOT-信息我注,那么為什么不把.META.信息直接保存在ZK中,而需要通過-ROOT-表來定位迟隅?
Client查找到目標地址后但骨,下一次請求還需要走ZK —> -ROOT- —> .META.這個流程么励七?
先來回答第一個問題:為什么不直接把.META.表信息直接保存到ZK中?主要是為了保存的數(shù)據(jù)量考慮奔缠,ZK中不宜保存大量數(shù)據(jù)掠抬,而.META.表主要是保存Region和RS的映射信息,region的數(shù)量沒有具體約束校哎,只要在內(nèi)存允許的范圍內(nèi)两波,region數(shù)量可以有很多,如果保存在ZK中贬蛙,ZK的壓力會很大雨女。所以,通過一個-ROOT-表來轉(zhuǎn)存到RS中是一個比較理想的方案阳准,相比直接保存在ZK中氛堕,也就多了一層-ROOT-表的查詢,對性能來說影響不大野蝇。第二個問題:每次訪問都需要走ZK –> -ROOT- —> .META.的流程么讼稚?當然不需要,Client端有緩存绕沈,第一次查詢到相應(yīng)region所在RS后锐想,這個信息將被緩存到Client端,以后每次訪問都直接從緩存中獲取RS地址即可乍狐。當然這里有個意外:訪問的region若果在RS上發(fā)生了改變赠摇,比如被balancer遷移到其他RS上了,這個時候浅蚪,通過緩存的地址訪問會出現(xiàn)異常藕帜,在出現(xiàn)異常的情況下,Client需要重新走一遍上面的流程來獲取新的RS地址惜傲∏⒐剩總體來說,region的變動只會在極少數(shù)情況下發(fā)生盗誊,一般變動不會很大时甚,所以在整個集群訪問過程中,影響可以忽略哈踱。
Region數(shù)據(jù)寫入
HBase通過ZK —> -ROOT- —> .META.的訪問獲取RS地址后荒适,直接向該RS上進行數(shù)據(jù)寫入操作,整個過程如下圖:
RegionServer數(shù)據(jù)操作過程
Client通過三層索引獲得RS的地址后开镣,即可向指定RS的對應(yīng)region進行數(shù)據(jù)寫入吻贿,HBase的數(shù)據(jù)寫入采用WAL(write ahead log)的形式,先寫log哑子,后寫數(shù)據(jù)舅列。HBase是一個append類型的數(shù)據(jù)庫肌割,沒有關(guān)系型數(shù)據(jù)庫那么復(fù)雜的操作,所以記錄HLog的操作都是簡單的put操作(delete/update操作都被轉(zhuǎn)化為put進行)
HLog
HLog寫入
HLog是HBase實現(xiàn)WAL方式產(chǎn)生的日志信息帐要,其內(nèi)部是一個簡單的順序日志把敞,每個RS上的region都共享一個HLog,所有對于該RS上的region數(shù)據(jù)寫入都被記錄到該HLog中榨惠。HLog的主要作用就是在RS出現(xiàn)意外崩潰的時候奋早,可以盡量多的恢復(fù)數(shù)據(jù),這里說是盡量多赠橙,因為在一般情況下耽装,客戶端為了提高性能,會把HLog的auto flush關(guān)掉期揪,這樣HLog日志的落盤全靠操作系統(tǒng)保證掉奄,如果出現(xiàn)意外崩潰,短時間內(nèi)沒有被fsync的日志會被丟失凤薛。
HLog過期
HLog的大量寫入會造成HLog占用存儲空間會越來越大浊猾,HBase通過HLog過期的方式進行HLog的清理羹呵,每個RS內(nèi)部都有一個HLog監(jiān)控線程在運行幕与,其周期可以通過hbase.master.cleaner.interval進行配置坛怪。HLog在數(shù)據(jù)從memstore flush到底層存儲上后,說明該段HLog已經(jīng)不再被需要活玲,就會被移動到.oldlogs這個目錄下涣狗,HLog監(jiān)控線程監(jiān)控該目錄下的HLog,當該文件夾下的HLog達到hbase.master.logcleaner.ttl設(shè)置的過期條件后舒憾,監(jiān)控線程立即刪除過期的HLog镀钓。
Memstore
數(shù)據(jù)存儲
memstore是region內(nèi)部緩存,其大小通過HBase參數(shù)hbase.hregion.memstore.flush.size進行配置珍剑。RS在寫完HLog以后,數(shù)據(jù)寫入的下一個目標就是region的memstore死陆,memstore在HBase內(nèi)部通過LSM-tree結(jié)構(gòu)組織招拙,所以能夠合并大量對于相同rowkey上的更新操作。正是由于memstore的存在措译,HBase的數(shù)據(jù)寫入都是異步的别凤,而且性能非常不錯,寫入到memstore后领虹,該次寫入請求就可以被返回规哪,HBase即認為該次數(shù)據(jù)寫入成功。這里有一點需要說明塌衰,寫入到memstore中的數(shù)據(jù)都是預(yù)先按照rowkey的值進行排序的诉稍,這樣有利于后續(xù)數(shù)據(jù)查找蝠嘉。
數(shù)據(jù)刷盤
memstore中的數(shù)據(jù)在一定條件下會進行刷寫操作,使數(shù)據(jù)持久化到相應(yīng)的存儲設(shè)備上杯巨,觸發(fā)memstore刷盤的操作有多種不同的方式如下圖:
Memstore刷寫流程
以上1,2,3都可以觸發(fā)memstore的flush操作蚤告,但是實現(xiàn)的方式不同:
1通過全局內(nèi)存控制,觸發(fā)memstore刷盤操作服爷。memstore整體內(nèi)存占用上限通過參數(shù)hbase.regionserver.global.memstore.upperLimit進行設(shè)置杜恰,當然在達到上限后,memstore的刷寫也不是一直進行仍源,在內(nèi)存下降到hbase.regionserver.global.memstore.lowerLimit配置的值后心褐,即停止memstore的刷盤操作。這樣做笼踩,主要是為了防止長時間的memstore刷盤逗爹,會影響整體的性能。
在該種情況下戳表,RS中所有region的memstore內(nèi)存占用都沒達到刷盤條件桶至,但整體的內(nèi)存消耗已經(jīng)到一個非常危險的范圍,如果持續(xù)下去匾旭,很有可能造成RS的OOM镣屹,這個時候,需要進行memstore的刷盤价涝,從而釋放內(nèi)存女蜈。
2手動觸發(fā)memstore刷盤操作
HBase提供API接口,運行通過外部調(diào)用進行memstore的刷盤
3 memstore上限觸發(fā)數(shù)據(jù)刷盤
前面提到memstore的大小通過hbase.hregion.memstore.flush.size進行設(shè)置色瘩,當region中memstore的數(shù)據(jù)量達到該值時伪窖,會自動觸發(fā)memstore的刷盤操作。
刷盤影響
memstore在不同的條件下會觸發(fā)數(shù)據(jù)刷盤居兆,那么整個數(shù)據(jù)在刷盤過程中覆山,對region的數(shù)據(jù)寫入等有什么影響?memstore的數(shù)據(jù)刷盤泥栖,對region的直接影響就是:在數(shù)據(jù)刷盤開始到結(jié)束這段時間內(nèi)簇宽,該region上的訪問都是被拒絕的,這里主要是因為在數(shù)據(jù)刷盤結(jié)束時吧享,RS會對改region做一個snapshot魏割,同時HLog做一個checkpoint操作,通知ZK哪些HLog可以被移到.oldlogs下钢颂。從前面圖上也可以看到钞它,在memstore寫盤開始,相應(yīng)region會被加上UpdateLock鎖,寫盤結(jié)束后該鎖被釋放遭垛。
StoreFile
memstore在觸發(fā)刷盤操作后會被寫入底層存儲尼桶,每次memstore的刷盤就會相應(yīng)生成一個存儲文件HFile,storeFile即HFile在HBase層的輕量級分裝耻卡。數(shù)據(jù)量的持續(xù)寫入疯汁,造成memstore的頻繁flush,每次flush都會產(chǎn)生一個HFile卵酪,這樣底層存儲設(shè)備上的HFile文件數(shù)量將會越來越多幌蚊。不管是HDFS還是Linux下常用的文件系統(tǒng)如Ext4、XFS等溃卡,對小而多的文件上的管理都沒有大文件來的有效溢豆,比如小文件打開需要消耗更多的文件句柄;在大量小文件中進行指定rowkey數(shù)據(jù)的查詢性能沒有在少量大文件中查詢來的快等等瘸羡。
Compact
大量HFile的產(chǎn)生漩仙,會消耗更多的文件句柄,同時會造成RS在數(shù)據(jù)查詢等的效率大幅度下降犹赖,HBase為解決這個問題队他,引入了compact操作,RS通過compact把大量小的HFile進行文件合并峻村,生成大的HFile文件麸折。RS上的compact根據(jù)功能的不同,可以分為兩種不同類型粘昨,即:minor compact和major compact垢啼。
Minor Compact
minor compact又叫small compact,在RS運行過程中會頻繁進行张肾,主要通過參數(shù)hbase.hstore.compactionThreshold進行控制芭析,該參數(shù)配置了HFile數(shù)量在滿足該值時,進行minor compact吞瞪,minor compact只選取region下部分HFile進行compact操作馁启,并且選取的HFile大小不能超過hbase.hregion.max.filesize參數(shù)設(shè)置。
Major Compact
相反major compact也被稱之為large compact芍秆,major compact會對整個region下相同列簇的所有HFile進行compact惯疙,也就是說major compact結(jié)束后,同一個列簇下的HFile會被合并成一個浪听。major compact是一個比較長的過程螟碎,對底層I/O的壓力相對較大眉菱。major compact除了合并HFile外迹栓,另外一個重要功能就是清理過期或者被刪除的數(shù)據(jù)。前面提到過俭缓,HBase的delete操作也是通過append的方式寫入克伊,一旦某些數(shù)據(jù)在HBase內(nèi)部被刪除了酥郭,在內(nèi)部只是被簡單標記為刪除,真正在存儲層面沒有進行數(shù)據(jù)清理愿吹,只有通過major compact對HFile進行重組時不从,被標記為刪除的數(shù)據(jù)才能被真正的清理。compact操作都有特定的線程進行犁跪,一般情況下不會影響RS上數(shù)據(jù)寫入的性能椿息,當然也有例外:在compact操作速度跟不上region中HFile增長速度時,為了安全考慮坷衍,RS會在HFile達到一定數(shù)量時寝优,對寫入進行鎖定操作,直到HFile通過compact降到一定的范圍內(nèi)才釋放鎖枫耳。
Split
compact將多個HFile合并單個HFile文件乏矾,隨著數(shù)據(jù)量的不斷寫入,單個HFile也會越來越大迁杨,大量小的HFile會影響數(shù)據(jù)查詢性能钻心,大的HFile也會,HFile越大铅协,相對的在HFile中搜索的指定rowkey的數(shù)據(jù)花的時間也就越長捷沸,HBase同樣提供了region的split方案來解決大的HFile造成數(shù)據(jù)查詢時間過長問題。一個較大的region通過split操作警医,會生成兩個小的region亿胸,稱之為Daughter,一般Daughter中的數(shù)據(jù)是根據(jù)rowkey的之間點進行切分的预皇,region的split過程大致如下圖:
region split流程
region先更改ZK中該region的狀態(tài)為SPLITING侈玄。
Master檢測到region狀態(tài)改變。
region會在存儲目錄下新建.split文件夾用于保存split后的daughter region信息吟温。
Parent region關(guān)閉數(shù)據(jù)寫入并觸發(fā)flush操作序仙,保證所有寫入Parent region的數(shù)據(jù)都能持久化。
在.split文件夾下新建兩個region鲁豪,稱之為daughter A潘悼、daughter B。
Daughter A爬橡、Daughter B拷貝到HBase根目錄下治唤,形成兩個新的region。
Parent region通知修改.META.表后下線糙申,不再提供服務(wù)宾添。
Daughter A、Daughter B上線,開始向外提供服務(wù)缕陕。
如果開啟了balance_switch服務(wù)粱锐,split后的region將會被重新分布。
上面1 ~ 9就是region split的整個過程扛邑,split過程非沉常快,速度基本會在秒級內(nèi)蔬崩,那么在這么快的時間內(nèi)恶座,region中的數(shù)據(jù)怎么被重新組織的?其實沥阳,split只是簡單的把region從邏輯上劃分成兩個奥裸,并沒有涉及到底層數(shù)據(jù)的重組,split完成后沪袭,Parent region并沒有被銷毀湾宙,只是被做下線處理,不再對外部提供服務(wù)冈绊。而新產(chǎn)生的region Daughter A和Daughter B侠鳄,內(nèi)部的數(shù)據(jù)只是簡單的到Parent region數(shù)據(jù)的索引,Parent region數(shù)據(jù)的清理在Daughter A和Daughter B進行major compact以后死宣,發(fā)現(xiàn)已經(jīng)沒有到其內(nèi)部數(shù)據(jù)的索引后伟恶,Parent region才會被真正的清理。
HBase設(shè)計
HBase是一個分布式數(shù)據(jù)庫毅该,其性能的好壞主要取決于內(nèi)部表的設(shè)計和資源的分配是否合理博秫。
Rowkey設(shè)計
rowkey是HBase實現(xiàn)分布式的基礎(chǔ),HBase通過rowkey范圍劃分不同的region眶掌,分布式系統(tǒng)的基本要求就是在任何時候挡育,系統(tǒng)的訪問都不要出現(xiàn)明顯的熱點現(xiàn)象,所以rowkey的設(shè)計至關(guān)重要朴爬,一般我們建議rowkey的開始部分以hash或者MD5進行散列即寒,盡量做到rowkey的頭部是均勻分布的。禁止采用時間召噩、用戶id等明顯有分段現(xiàn)象的標志直接當作rowkey來使用母赵。
列簇設(shè)計
HBase的表設(shè)計時,根據(jù)不同需求有不同選擇具滴,需要做在線查詢的數(shù)據(jù)表凹嘲,盡量不要設(shè)計多個列簇,我們知道构韵,不同的列簇在存儲上是被分開的周蹭,多列簇設(shè)計會造成在數(shù)據(jù)查詢的時候讀取更多的文件溯革,從而消耗更多的I/O。
TTL設(shè)計
選擇合適的數(shù)據(jù)過期時間也是表設(shè)計中需要注意的一點谷醉,HBase中允許列簇定義數(shù)據(jù)過期時間,數(shù)據(jù)一旦超過過期時間冈闭,可以被major compact進行清理俱尼。大量無用歷史數(shù)據(jù)的殘余,會造成region體積增大萎攒,影響查詢效率遇八。
Region設(shè)計
一般地,region不宜設(shè)計成很大耍休,除非應(yīng)用對階段性性能要求很多刃永,但是在將來運行一段時間可以接受停服處理。region過大會導致major compact調(diào)用的周期變長羊精,而單次major compact的時間也相應(yīng)變長斯够。major compact對底層I/O會造成壓力,長時間的compact操作可能會影響數(shù)據(jù)的flush喧锦,compact的周期變長會導致許多刪除或者過期的數(shù)據(jù)不能被及時清理读规,對數(shù)據(jù)的讀取速度等都有影響。相反燃少,小的region意味著major compact會相對頻繁束亏,但是由于region比較小,major compact的相對時間較快阵具,而且相對較多的major compact操作碍遍,會加速過期數(shù)據(jù)的清理。當然阳液,小region的設(shè)計意味著更多的region split風險怕敬,region容量過小,在數(shù)據(jù)量達到上限后帘皿,region需要進行split來拆分赖捌,其實split操作在整個HBase運行過程中,是被不怎么希望出現(xiàn)的矮烹,因為一旦發(fā)生split越庇,涉及到數(shù)據(jù)的重組,region的再分配等一系列問題奉狈。所以我們在設(shè)計之初就需要考慮到這些問題卤唉,盡量避免region的運行過程中發(fā)生split。HBase可以通過在表創(chuàng)建的時候進行region的預(yù)分配來解決運行過程中region的split產(chǎn)生仁期,在表設(shè)計的時候桑驱,預(yù)先分配足夠多的region數(shù)竭恬,在region達到上限前,至少有部分數(shù)據(jù)會過期熬的,通過major compact進行清理后痊硕, region的數(shù)據(jù)量始終維持在一個平衡狀態(tài)。region數(shù)量的設(shè)計還需要考慮內(nèi)存上的限制押框,通過前面的介紹我們知道每個region都有memstore岔绸,memstore的數(shù)量與region數(shù)量和region下列簇的數(shù)量成正比,一個RS下memstore內(nèi)存消耗:
Memory = memstore大小 * region數(shù)量 * 列簇數(shù)量
如果不進行前期數(shù)據(jù)量估算和region的預(yù)分配,通過不斷的split產(chǎn)生新的region橡伞,容易導致因為內(nèi)存不足而出現(xiàn)OOM現(xiàn)象盒揉。