<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;
    }

    主站蜘蛛池模板: 久久这里只精品热免费99| caoporn成人免费公开| 久久国产免费观看精品3| 久久夜色精品国产亚洲AV动态图| 国产黄色片免费看| 亚洲av综合av一区| 最近中文字幕电影大全免费版 | 中文字幕视频免费在线观看 | 国产免费拔擦拔擦8x| 国产偷国产偷亚洲高清在线| 国产一区视频在线免费观看 | a级毛片免费完整视频| 亚洲国产精品无码久久久秋霞2 | 亚洲精品国产V片在线观看| jizz在线免费播放| 亚洲三级电影网址| 色se01短视频永久免费| 亚洲日韩久久综合中文字幕| 免费国产一级特黄久久| 91成人免费观看在线观看| 亚洲美女视频免费| 日本高清免费网站| 9久热精品免费观看视频| 337p欧洲亚洲大胆艺术| 免费网站看v片在线香蕉| 一区视频免费观看| 亚洲小视频在线播放| 免费又黄又爽的视频| 国产一精品一AV一免费| 精品久久久久久亚洲精品| 亚洲AV无码成H人在线观看| 国产午夜免费高清久久影院| 亚洲影院天堂中文av色| 亚洲视频人成在线播放| 国产精品色拉拉免费看| 男女啪啪免费体验区| 亚洲国产美女福利直播秀一区二区 | 亚洲高清有码中文字| 亚洲一区二区三区乱码A| 精品熟女少妇av免费久久| 国产成人亚洲午夜电影|