leveldb多线程读写(大数据高并发解决方案)

在并发写入的时候,leveldb巧妙的利用一个时间窗口做batch写入,这部分代码值得一读:StatusDBImpl::Write(constWriteOptions&options,WriteBatch*my_batch){  //partA  Writerw(&mutex_);  w.batch=my_batch;  w.sync=options.syn…

大家好,又见面了,我是你们的朋友全栈君。

在并发写入的时候,leveldb巧妙的利用一个时间窗口做batch写入,这部分代码值得一读:

Status DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) {
  
//part A
  Writer w(&mutex_);
  w.batch = my_batch;
  w.sync = options.sync;
  w.done = false;

  //part B
  MutexLock l(&mutex_);
  writers_.push_back(&w);
  while (!w.done && &w != writers_.front()) {
    w.cv.Wait();
  }
  if (w.done) {
    return w.status;
  }
   
  // May temporarily unlock and wait.
  Status status = MakeRoomForWrite(my_batch == NULL);
  uint64_t last_sequence = versions_->LastSequence();
  Writer* last_writer = &w;
    //part C
  if (status.ok() && my_batch != NULL) {  // NULL batch is for compactions
    WriteBatch* updates = BuildBatchGroup(&last_writer);
    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 &w is currently responsible for logging
    // and protects against concurrent loggers and concurrent writes
    // into mem_.

    //part D
    {
      mutex_.Unlock();
      status = log_->AddRecord(WriteBatchInternal::Contents(updates));
      if (status.ok() && options.sync) {
        status = logfile_->Sync();
      }
      if (status.ok()) {
        status = WriteBatchInternal::InsertInto(updates, mem_);
      }
      mutex_.Lock();
    }

    if (updates == tmp_batch_) tmp_batch_->Clear();

    versions_->SetLastSequence(last_sequence);
  }

//part E
  while (true) {
    Writer* ready = writers_.front();
    writers_.pop_front();
    if (ready != &w) {
      ready->status = status;
      ready->done = true;
      ready->cv.Signal();
    }
    if (ready == last_writer) break;
  }

   //part F
  // Notify new head of write queue
  if (!writers_.empty()) {
    writers_.front()->cv.Signal();
  }

  return status;
}

     假设同时有w1, w2, w3, w4, w5, w6 并发请求写入。
  B部分代码让竞争到mutex资源的w1获取了锁。w1将它要写的数据添加到了writers_队列里去,此时队列只有一个w1, 从而其顺利的进行buildbatchgroup。当运行到(
part C)时mutex_互斥锁释放,之所以这儿可以释放mutex_,是因为其它的写操作都不满足队首条件,进而不会进入log和memtable写入阶段。这时(w2, w3, w4, w5, w6)会竞争锁,由于B段代码中不满足队首条件,均等待并释放锁了。从而队列可能会如(w3, w5, w2, w4).
  继而w1进行log写入和memtable写入。 当w1完成log和memtable写入后,则mutex_又锁住,这时(PART B)代码中队列因为获取不到锁则队列不会修改。
  随后(
part E)开始,w1被pop出来,由于ready==w, 并且ready==last_writer,所以到(
part F),唤醒了此时处于队首的w3.
      w3唤醒时,发现自己是队首,可以顺利的进行进入buildbatchgroup,在BuildBatchGroup函数中,遍历了目前所有的队列元素,形成一个update的batch,即将w3, w5, w2, w4合并为一个batch. 并将last_writer置为此时处于队尾的最后一个元素w4,(
part D)运行后,因为释放了锁资源,队列可能随着dbimpl::write的调用而更改,如队列状况可能为(w3, w5, w2, w4, w6, w9, w8).
   (
part D)的代码将w3, w5, w2, w4整个的batch写入log和memtable. 到(
part E),分别对w5, w2, w4进行了一次cond signal.当判断到完w4 == lastwriter时,则退出循环。(
part F)则对队首的w6唤醒,从而按上述步骤依次进行下去。
  这样就形成了多个并发write 合并为一个batch写入log和memtable的机制。

转载于:
http://www.cnblogs.com/cobbliu/p/6193164.html 若存在版权问题,请联系。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/127413.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • MAC下安装opencv,pycharm 引入 cv2出现问题「建议收藏」

    MAC下安装opencv,pycharm 引入 cv2出现问题「建议收藏」尝试使用caffe中的mnist模型测试手写的图片时,发现pycharm没有cv2,然后安装借鉴前人经验,总结安装过成如下:前提本人系统,已经安装brew,xcode1.直接输入命令 brewinstallopencv2.成功安装opencv之后,进入python的site-packages目录下,并创建链接(下载好的opencv放在/usr/local/Cellar/ope

  • 小程序生成普通二维码_注册一个小程序

    小程序生成普通二维码_注册一个小程序uniapp生成二维码`参考了https://blog.csdn.net/lemontealin/article/details/104437584这篇文章并做了修改,要想实现二维码的生成的话是需要引用相应插件的,这个插件的作者是echo,echo写了整个ThorUI组件,我个人很佩服他,喜欢他的可以去ThorUI网站看看,学习一下。1)首先下载你需要下载weapp-qrcode.js(百度网盘下载链接:链接:https://pan.baidu.com/s/1VXhq3ZjxmDcH1tFujK

    2022年10月31日
  • CNN垃圾分类_垃圾分类卡通画

    CNN垃圾分类_垃圾分类卡通画基于TensorFlow和Keras的垃圾分类模型本篇博客主要介绍基于TensorFlow和Keras实现垃圾分类模型,目前是一篇占坑的博客,由于该项目目前用于参加比赛,因此暂时不能提供代码,感兴趣的可以私信我一起交流,识别结果如下所示:

  • linux解压zip文件,

    linux解压zip文件,一,linux解压zip文件,命令:unzip如果没有该命令,可先安装,命令为:yum-yinstallunzip

  • 跨平台数据整合系统_lvc异构系统

    跨平台数据整合系统_lvc异构系统1.muleESB整合系统四种模式A.简单服务模式属于几个webService之间的同步调用,请求响应处理模式。B.桥接模式C.校验器模式校验器模式通过定义一个校验过滤器过滤服务请求,并同步返回

  • rsync服务的三种模式测试[通俗易懂]

    rsync服务的三种模式测试[通俗易懂]目录1什么是rsync1.1rsync简介rsync特性1.3rsync的企业工作场景说明2rsync三种模式:2.1rsync常用参数选项2.2rsync本地模式2.3rsyncshell模式2.4rsyncdaemon模式3rsync服务故障模拟4rsync多模块实战5rsync排除及无差异同步实战6rsync优缺点6….

    2022年10月13日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号