自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MongoDB數(shù)據(jù)緩存刷新機(jī)制

數(shù)據(jù)庫(kù) 其他數(shù)據(jù)庫(kù) MongoDB
在MongoDB開(kāi)發(fā)者論壇里描述了這個(gè)現(xiàn)象,但是 Eliot Horowitz認(rèn)為MongoDB內(nèi)部并沒(méi)有代碼會(huì)釋放文件系統(tǒng)cache。那么,讓我們?nèi)ピ创a里面看一下MongoDB緩存和刷新數(shù)據(jù)的機(jī)制。

最近配合好幾個(gè)項(xiàng)目測(cè)試了MongoDB的寫(xiě)入性能。在內(nèi)存沒(méi)有用盡的情況下,雖然MongoDB只有一個(gè)更新線(xiàn)程,寫(xiě)入還是非??斓?,基本上能達(dá)到25000/s以上(索引數(shù)據(jù)用uuid_generate_randome和uuid_unparse隨機(jī)產(chǎn)生)。當(dāng)內(nèi)存用盡開(kāi)始往磁盤(pán)上刷臟頁(yè)的時(shí)候,性能有非常大的波動(dòng),即使調(diào)整了syncdelay也沒(méi)有太大改善。在測(cè)試中還出現(xiàn)了一個(gè)莫名其妙的情況:MongoDB會(huì)間歇性地釋放文件系統(tǒng)的cache。除了直接刪除表空間之外,很難想到有什么動(dòng)作可以誘發(fā)這個(gè)現(xiàn)象。在MongoDB開(kāi)發(fā)者論壇里描述了這個(gè)現(xiàn)象,但是 Eliot Horowitz認(rèn)為MongoDB內(nèi)部并沒(méi)有代碼會(huì)釋放文件系統(tǒng)cache。那么,讓我們?nèi)ピ创a里面看一下MongoDB緩存和刷新數(shù)據(jù)的機(jī)制。

首先找到mongod的入口(db/db.cpp),發(fā)現(xiàn)MongoDB的初始化步驟非常簡(jiǎn)單,概括起來(lái)就以下三步:

  1. int main(int argc, char* argv[], char *envp[] ) 
  2. … 
  3. Module::configAll( params ); 
  4. dataFileSync.go(); 
  5. … 
  6. initAndListen(cmdLine.port, appsrvPath); 
  7. … 

顯然,dataFileSync就是我們感興趣的那個(gè)類(lèi)。dataFileSync類(lèi)派生自BackgroundJob類(lèi),而B(niǎo)ackgroundJob 主要的功能就是生成一個(gè)后臺(tái)線(xiàn)程并指派任務(wù)。數(shù)據(jù)的刷新是一個(gè)不斷執(zhí)行的后臺(tái)任務(wù),在dataFileSync.run()里面可以找到刷數(shù)據(jù)的相關(guān)代碼:

  1. void run() 
  2. … 
  3. Date_t start = jsTime(); 
  4. int numFiles = MemoryMappedFile::flushAll( true ); 
  5. time_flushing = (int) (jsTime() – start); 
  6. globalFlushCounters.flushed(time_flushing); 
  7. … 

從這一段代碼看,MongoDB會(huì)在syncdelay設(shè)定的周期內(nèi),采取同步的形式刷新所有的臟數(shù)據(jù)。再看一下flushAll是怎么刷新所有數(shù)據(jù)的:

  1. int MongoFile::flushAll( bool sync ) 
  2.  { 
  3.  … 
  4.  set seen; 
  5.  while ( true ){ 
  6.  auto_ptr f; 
  7.  { 
  8.  rwlock lk( mmmutex , false ); 
  9.  for ( set::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ){ 
  10.  MongoFile * mmf = *i; 
  11.  if ( ! mmf ) 
  12.  continue
  13.  if ( seen.count( mmf ) ) 
  14.  continue
  15.  f.reset( mmf->prepareFlush() ); 
  16.  seen.insert( mmf ); 
  17.  break; 
  18.  } 
  19.  } 
  20.  if ( ! f.get() ) 
  21.  break; 
  22.  f->flush(); 
  23.  } 
  24.  return seen.size(); 
  25.  } 

上面這一段代碼實(shí)現(xiàn)的功能很簡(jiǎn)單,就是把mmfiles中所有MongoFile指針?biāo)玫膶?duì)象都flush()一次。不過(guò)在執(zhí)行flush()函數(shù)之前,需要先執(zhí)行prepareFlush()確保這個(gè)對(duì)象是可以執(zhí)行flush()函數(shù)的。下面是***真正執(zhí)行刷新操作的代碼:

  1. void MemoryMappedFile::flush(bool sync) 
  2. if ( view == 0 || fd == 0 ) 
  3. return
  4. if ( msync(view, len, sync ? MS_SYNC : MS_ASYNC) ) 
  5. problem() << “msync ” << errnoWithDescription() << endl; 

終于刷新到磁盤(pán)了,呵呵。不過(guò)這篇blog只涉及到了數(shù)據(jù)刷新的代碼,至于如何緩存,且聽(tīng)下回分解。

【編輯推薦】

  1. 設(shè)計(jì)實(shí)例對(duì)比:MySQL vs MongoDB
  2. MongoDB基于Java、PHP的一般操作和用戶(hù)安全設(shè)置
  3. 在Windows環(huán)境下MongoDB搭建和簡(jiǎn)單操作
  4. 教你如何利用MySQL學(xué)習(xí)MongoDB
  5. 如何用Java操作MongoDB

 

 

責(zé)任編輯:艾婧 來(lái)源: 淘寶數(shù)據(jù)庫(kù)技術(shù)團(tuán)隊(duì)
相關(guān)推薦

2021-12-08 06:53:28

Choreograph屏幕機(jī)制

2021-04-21 07:53:13

Android屏幕刷新

2020-10-13 08:36:30

React 架構(gòu)機(jī)制

2010-09-06 08:43:13

.NET 4

2010-06-02 11:33:26

Linux 內(nèi)存監(jiān)控

2024-01-03 21:50:32

緩存機(jī)制請(qǐng)求

2020-09-21 14:35:20

VuenextTick前端

2010-03-10 11:55:30

Mocha BSM運(yùn)維管理摩卡軟件

2024-06-17 08:55:52

2025-04-03 00:45:00

2016-10-21 09:29:53

嵌入式Linux更新機(jī)制

2021-02-25 11:12:31

人工智能生物技術(shù)肺纖維化藥物

2018-08-10 04:40:56

2009-08-03 18:35:51

ASP.NET數(shù)據(jù)緩存

2024-04-29 08:05:34

NacosJava數(shù)據(jù)結(jié)構(gòu)

2011-12-15 09:33:19

Java

2009-06-17 15:43:03

Hibernate緩存

2023-02-24 16:46:25

Glide緩存機(jī)制

2021-01-19 10:39:03

Redis緩存數(shù)據(jù)

2009-11-09 17:55:13

WCF緩存
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)