<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    小明思考

    Just a software engineer
    posts - 124, comments - 36, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    leveldb研究10- 流程分析:寫數據

    Posted on 2012-03-21 14:41 小明 閱讀(3447) 評論(0)  編輯  收藏 所屬分類: 分布式計算
    總體來說,leveldb的寫操作有兩個步驟,首先是針對log的append操作,然后是對memtable的插入操作。

    影響寫性能的因素有:
    1. write_buffer_size
    2. kL0_SlowdownWritesTrigger and kL0_StopWritesTrigger.提高這兩個值,能夠增加寫的性能,但是降低讀的性能

    看看WriteOptions有哪些參數可以指定
    struct WriteOptions {
      
    //設置sync=true,leveldb會調用fsync(),這會降低插入性能
      
    //同時會增加數據的安全性 
      
    //Default: false
      bool sync;

      WriteOptions()
          : sync(
    false) {
      }
    };


    首先把Key,value轉成WriteBatch
    Status DB::Put(const WriteOptions& opt, const Slice& key, const Slice& value) {
      WriteBatch batch;
      batch.Put(key, value);
      
    return Write(opt, &batch);
    }

    接下來就是真正的插入了
    這里使用了兩把鎖,主要是想提高并發能力,減少上鎖的時間。
    首先是檢查是否可寫,然后append log,最后是插入memtable
    <db/dbimpl.cc>

    Status DBImpl::Write(const WriteOptions& options, WriteBatch* updates) {
      Status status;
      
    //加鎖
      MutexLock l(&mutex_);
      LoggerId self;
      
    //拿到寫log的權利
      AcquireLoggingResponsibility(&self);
      
    //檢查是否可寫
      status = MakeRoomForWrite(false);  // May temporarily release lock and wait
      uint64_t last_sequence = versions_->LastSequence();
      
    if (status.ok()) {
        WriteBatchInternal::SetSequence(updates, last_sequence 
    + 1);
        last_sequence 
    += WriteBatchInternal::Count(updates);

        
    // Add to log and apply to memtable.  We can release the lock during
        
    // this phase since the "logger_" flag protects against concurrent
        
    // loggers and concurrent writes into mem_.
        {
          assert(logger_ 
    == &self);
          mutex_.Unlock();
          
    //IO操作:寫入LOG
          status = log_->AddRecord(WriteBatchInternal::Contents(updates));
          
    if (status.ok() && options.sync) {
            status 
    = logfile_->Sync();
          }
          
    //插入memtable
          if (status.ok()) {
            status 
    = WriteBatchInternal::InsertInto(updates, mem_);
          }
          mutex_.Lock();
          assert(logger_ 
    == &self);
        }
        
    //設置新的seqence number
        versions_->SetLastSequence(last_sequence);
      }
      
    //釋放寫LOG鎖
      ReleaseLoggingResponsibility(&self);
      
    return status;
    }

    寫流量控制:
    <db/dbimpl.cc>
    Status DBImpl::MakeRoomForWrite(bool force) {
      mutex_.AssertHeld();
      assert(logger_ 
    != NULL);
      
    bool allow_delay = !force;
      Status s;
      
    while (true) {
        
    if (!bg_error_.ok()) {
          
    // Yield previous error
          s = bg_error_;
          
    break;
        } 
    else if ( 
            allow_delay 
    &&
            versions_
    ->NumLevelFiles(0>= config::kL0_SlowdownWritesTrigger) {
          mutex_.Unlock();
          
    //如果level0的文件大于kL0_SlowdownWritesTrigger閾值,則sleep 1s,這樣給compaction更多的CPU
          env_->SleepForMicroseconds(1000);
          allow_delay 
    = false;  // Do not delay a single write more than once
          mutex_.Lock();
        } 
    else if (!force &&
                   (mem_
    ->ApproximateMemoryUsage() <= options_.write_buffer_size)) {
          
    //可寫
          break;
        } 
    else if (imm_ != NULL) {
          
    // imm_:之前的memtable 沒有被compaction,需要等待
          bg_cv_.Wait();
        } 
    else if (versions_->NumLevelFiles(0>= config::kL0_StopWritesTrigger) {
          
    // level0文件個數大于kL0_StopWritesTrigger,需要等待
          Log(options_.info_log, "waiting\n");
          bg_cv_.Wait();
        } 
    else {
          
    //生成新的額memtable和logfile,把當前memtable傳給imm_
          assert(versions_->PrevLogNumber() == 0);
          uint64_t new_log_number 
    = versions_->NewFileNumber();
          WritableFile
    * lfile = NULL;
          s 
    = env_->NewWritableFile(LogFileName(dbname_, new_log_number), &lfile);
          
    if (!s.ok()) {
            
    break;
          }
          delete log_;
          delete logfile_;
          logfile_ 
    = lfile;
          logfile_number_ 
    = new_log_number;
          log_ 
    = new log::Writer(lfile);
          imm_ 
    = mem_;
          has_imm_.Release_Store(imm_);
          mem_ 
    = new MemTable(internal_comparator_);
          mem_
    ->Ref();
          force 
    = false;   // Do not force another compaction if have room
          // 發起compaction,dump imm_
          MaybeScheduleCompaction();
        }
      }
      
    return s;
    }

    主站蜘蛛池模板: 亚洲人成电影在线天堂| 亚洲国产欧洲综合997久久| 在线视频免费观看高清| 偷自拍亚洲视频在线观看99| 亚洲欧洲日产国码av系列天堂| 24小时免费看片| 免费激情网站国产高清第一页| 久久精品国产精品亚洲艾| 67194成是人免费无码| 精品多毛少妇人妻AV免费久久| 亚洲视频免费一区| 免费大黄网站在线看| 国产大片91精品免费观看不卡| 日韩色日韩视频亚洲网站| 久久久久久a亚洲欧洲AV| 永久免费视频v片www| 4444www免费看| 成人在线免费视频| 亚洲高清不卡视频| 国产成人A亚洲精V品无码| 女性无套免费网站在线看| 免费看搞黄视频网站| 成年免费大片黄在线观看com| 亚洲日产2021三区在线 | 亚洲大尺度无码无码专区| 好吊妞视频免费视频| 最好看的中文字幕2019免费| 人成午夜免费大片在线观看| 亚洲一区无码中文字幕乱码| 亚洲产国偷V产偷V自拍色戒| 免费大黄网站在线看| 在线视频免费观看www动漫| 69影院毛片免费观看视频在线 | 无码乱肉视频免费大全合集| 久久WWW免费人成—看片| 亚洲国产成人无码AV在线| 亚洲美女aⅴ久久久91| 亚洲精品无码久久久久去q| 亚洲av手机在线观看| 精品剧情v国产在免费线观看| 五月婷婷在线免费观看|