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

    主站蜘蛛池模板: 国产男女猛烈无遮挡免费视频网站 | 亚洲中文字幕第一页在线 | 免费看美女午夜大片| 在线观看人成视频免费| 欧洲 亚洲 国产图片综合| 一个人看www在线高清免费看| 亚洲色欲久久久综合网东京热| 暖暖免费中文在线日本| 亚洲精品国产自在久久 | 免费人成网上在线观看| 亚洲人成无码久久电影网站| 一级一级一级毛片免费毛片| 中文字幕亚洲无线码| 99在线免费视频| 亚洲激情在线观看| 在线视频免费观看爽爽爽| 亚洲综合精品伊人久久| 国产又大又长又粗又硬的免费视频| 亚洲影院天堂中文av色| 亚洲福利视频一区二区| 三年片免费高清版 | 伊人久久国产免费观看视频| 亚洲一区二区高清| 久久成人a毛片免费观看网站| 亚洲a一级免费视频| 麻豆视频免费观看| 亚洲AⅤ男人的天堂在线观看| 日本免费人成视频播放 | 亚洲精品国产成人中文| 无码人妻精品一二三区免费| 麻豆va在线精品免费播放| 亚洲av永久无码精品国产精品| 特级无码毛片免费视频尤物| 亚洲欧洲av综合色无码| 最新亚洲成av人免费看| 野花高清在线电影观看免费视频| 亚洲AV无码专区亚洲AV桃| 久久精品亚洲一区二区| 日日AV拍夜夜添久久免费| 无码国产精品一区二区免费16| 国产精品亚洲自在线播放页码|