MySQL · myrocks · MyRocks之memtable切换与刷盘
概述
MyRocks的memtable默认是skiplist,其大小和个数分别由参数write_buffer_size和max_write_buffer_number控制。数据写入时先写入active memtable, 当active memtable写满时,active memtable会转化为immutable memtable. immutable memtable数据是不会变化的,最终会刷入level0的sst文件中。
memtable 内存分配
RocksDB有自己的内存分配机制,称为Arena. Arena由固定的inline_block_和动态的blocks_组成。 inline_block_固定为2048bytes, blocks_由一系列的block组成,这些block大小一般为KBlockSize, 但从arena申请较大内存时(> KBlockSize/4)单独分配一个所申请大小的block. KBlockSize由参数arena_block_size指定,arena_block_size 不指定时默认为write_buffer_size的1/8.
这里有两个重要的概念
- blocks_memory_
- Arena当前已分配的内存
- alloc_bytes_remaining_
- Arena当前block已分配但未使用的内存,注意不是整个Arena已分配而未使用的内存
RocksDB在实际使用内存中用的是ConcurrentArena, 它是在Arena的基础上封装,是线程安全的。 同时ConcurrentArena为了提高并发对内存进行了分片,分片数由cpu个数决定,例如cpu核数为24, 则分片数为32,以下是分片的算法
// find a power of two >= num_cpus and >= 8 auto num_cpus = std::thread::hardware_concurrency();index_mask_ = 7;while (index_mask_ + 1 < num_cpus) {index_mask_ = index_mask_ * 2 + 1;}shards_.reset(new Shard[index_mask_ + 1]);
每个分片都有已分配但未使用的内存, 分片越多浪费的内存越多。一个有趣的例子
测试环境:CPU核数64,write_buffer_size=1G, arena_block_size=0 根据前面的算法,CPU核数64, 内存分片数为64, arena_block_size 默认为write_buffer_size的1/8,对齐后是131072000
我们用1200个连接进行并发插入,这样能够充分使用内存分片数 这是测试某个瞬间取得的内存数据
allocated_memory:1179650048
AllocatedAndUnused:1172297392
write_buffer_size:1048576000
BlockSize:131072000
注意AllocatedAndUnused和allocated_memory是如此的接近,也就是说存在巨大的内存浪费。然而这不是最严重的,更严重的是这种情况导致memtable的切换,后面会进行分析。
memtable 切换
memtable 发生切换的条件有
- memtable内存超过write_buffer_size会切换
- WAL日志满,WAL日志超过rocksdb_max_total_wal_size,会从所有的colomn family中找出含有最老日志(the earliest log containing a prepared section)的memtable进行切换,详见HandleWALFull
- Buffer满,全局的write buffer超过rocksdb_db_write_buffer_size时,会从所有的colomn family中找出最先创建的memtable进行切换,详见HandleWriteBufferFull
- flush memtable前会切换memtable, 下节会介绍
下面详细介绍memtable满切换
- memtable 满切换
memtable内存超过write_buffer_size会切换,由于arena的内存使用,memtable控制内存使用的算法更加精细,切换条件从源码中很容易理解
bool MemTable::ShouldFlushNow() const {// This constant variable can be interpreted as: if we still have more than // "kAllowOverAllocationRatio * kArenaBlockSize" space left, we'd try to over // allocate one more block. const double kAllowOverAllocationRatio = 0.6;// If arena still have room for new block allocation, we can safely say it // shouldn't flush. auto allocated_memory = table_->ApproximateMemoryUsage() +range_del_table_->ApproximateMemoryUsage() +arena_.MemoryAllocatedBytes();// if we can still allocate one more block without exceeding the // over-allocation ratio, then we should not flush. if (allocated_memory + kArenaBlockSize <moptions_.write_buffer_size +kArenaBlockSize * kAllowOverAllocationRatio) {return false;}// if user keeps adding entries that exceeds moptions.write_buffer_size, // we need to flush earlier even though we still have much available // memory left. if (allocated_memory > moptions_.write_buffer_size +kArenaBlockSize * kAllowOverAllocationRatio) {return true;}return arena_.AllocatedAndUnused() < kArenaBlockSize / 4;
}
而上一节举出的例子正好符合切换的条件,正如前面所说的,内存都分配好了,还没来得及使用就发生切换了,白忙活了一场。
这里的现象是虽然write_buffer_size是1G,但最后刷到level0的sst都远远小于1G。
那么如何避免这种情况呢
- 减少内存分片数,不建议
- 调小arena_block_size, 亲测可用
- memtable 切换实现
- NewWritableFile //创建日志文件
- ConstructNewMemtable //创建memtable
- cfd->imm()->Add(cfd->mem(), &context->memtables_to_free_); //设置immutable
- cfd->SetMemtable(new_mem); //设置新的memtable
flush memtable
immutable memtable会不断flush到level0的SST文件中
触发flush的条件有
- WAL日志满,WAL日志超过rocksdb_max_total_wal_size,会从所有的colomn family中找出含有最老日志(the earliest log containing a prepared section)的column family进行flush,详见HandleWALFull
- Buffer满,全局的write buffer超过rocksdb_db_write_buffer_size时,会从所有的colomn family中找出最先创建的memtable的column family进行flush,详见HandleWriteBufferFull
- 手动设置参数force_flush_memtable_now/rocksdb_force_flush_memtable_and_lzero_now时
- CompactRange时
- 创建checkpoint时
- shutdown时avoid_flush_during_shutdown=0会flush所有memtable
other
rocksdb中设置max_background_flushes=-1可以禁止flush,而MyRocks中rocksdb_max_background_flushes最小值限制为0. 因此,MyRocks若要禁止flush需放开此限制。
相关文章:

URLRewriter在ASP.NET配置文件中的用法
<?xml version"1.0"?><configuration><configSections><sectionGroup name"system.web.extensions" type"System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version1.0.61025.0, Culturene…

Travis CI : 最小的分布式系统(二)
大约1年之前,我们发现当时的架构有些不合理了。尤其是Hub,它上面承担了太多的任务。Hub要接收新的处理请求,处理并推动构建日志,它要同步用户信息到Github,它要通知用户构建是否成功。它跟一大群外部API打交道…

百度开设「黄埔学院」,革新者来
1 月 19 日,百度宣布成立「黄埔学院」,开展深度学习架构师培养计划。并借鉴了黄埔军校大门对联的横批「革命者来」,将口号设置为「革新者来」。 首先,为什么叫「黄埔学院」? 2012 年初,百度开始进行深度学…

Linux-find命令应用举例-按时间筛选和删除文件
find参数说明: find有很多参数是以动作首字母时间的方式用于按访问、改变、更新时间来筛选文件。 动作表达: a(last accessed) 最近一次访问时间 c(last changed) 最近一次改变时间 m(last modified) 最近一次修改时间注意此上的c和m的区别,…
2007年11月网络工程师考试试题
● 若某计算机系统由两个部件串联构成,其中一个部件的失效率为710-6/小时。若不考虑其他因素的影响,并要求计算机系统的平均故障间隔时间为105小时,则另一个部件的失效率应为 (1) /小时。 (1&am…

Travis CI : 最小的分布式系统(三)
日志的作用有两个:当构建日志的数据块通过消息队列进来时,更新数据库对应行,然后推送它到Pusher用于实时的用户界面更新。 日志块以流的形式在同一个时间从不同的进程中进来,然后被一个进程处理。这个进程每秒最高可处理100个消息…

windows 上rsync客户端使用方法
阅读目录 1.1 获取 windows上实现rsync的软件(cwRsync)1.2 cwrsync的使用方法1.3 cwrsync的使用回到顶部1.1 获取 windows上实现rsync的软件(cwRsync) cwRsync是Windows 客户端GUI的一个包含Rsync的包装。您可以使用cwRsync快速远…

机器学习开源项目Top10
整理 | Jane 出品 | AI科技大本营 【导语】又到了我们固定给大家推荐开源项目的时间。本期将为大家推荐 10 个机器学习开源项目,统计了过去一个月中 250 个机器学习开源项目,并从中选取了本期的 Top10。平均 1483 Stars。不知道是不是有你喜欢的欢迎大…

大规模服务设计部署经验谈
本文中提出的最佳实践,来自于作者多年大规模服务设计和部署的经验,为设计、开发对运营友好的服务提供了一系列良好的解决方案。■ 文/James Hamilton 译/赖翥翔1 引言 本文就设计和开发运营友好的服务的话题进行总结…

修改mysql数据库默认编码为utf8
查看当前字符编码: mysql < show variables like character%;为了解决中文乱码问题,修改mysql默认数据库编码为utf8,修改/etc/my.cnf [client]default-character-setutf8[mysql]default-character-setutf8[mysqld]character-set-serverutf…

CSDN创始人蒋涛:AI定义的开发者时代
1月18日,由中国软件行业协会主办的2019中国软件产业年会,在国家会议中心举行。CSDN创始人&董事长蒋涛,在大会上发表了题为《AI定义的开发者时代》的主题演讲。 以下为演讲实录: 我们在PC互联网时代就建立了中国软件开发者社区…

numpy.ndarray的赋值操作
matzeros((3,4)) #生成一个3行4列全部元素为0的矩阵mat[1,:]111 #从第1行第0列开始,一直到最后一列,赋值为1,效果与mat[1,0:3]相同,前置0可以省略,最后的列数可以省略输出:[[ 0. 0. 0. 0.][ 111. 111. 111.…

travis-ci如何配置android
travis-ci如何配置android travis-ci 关于android部分:http://docs.travis-ci.com/user/languages/android/ language: android android:components:- build-tools-19.1.0 # BuildTools version- android-19 # SDK version- sy…

你的微笑,拂过我的心海
??初冬的午后,阳光,懒懒地伸展着腰肢,企业形象宣传片 ,偶然从窗帘漏进几缕稀少的斜影。南方的冬天总是姗姗来迟,让人认为,那只不过是秋天残存的脚步,还没来得及捉住,它却已从你的眉间静静地溜…

重读Youtube深度学习推荐系统论文,字字珠玑,惊为神文
作者简介,王喆,硅谷高级机器学习工程师。 本文转载自知乎专栏 https://zhuanlan.zhihu.com/p/52169807 这里是王喆的机器学习笔记,每隔一到两周我会站在算法工程师的角度讲解一些计算广告、推荐系统相关的文章。选择文章必须满足一下三个条件…

Struts的select两种遍历方法
转载于:https://blog.51cto.com/9695005/2050390

nginx http 服务器搭建
下载nginx源码:http://nginx.org/en/download.html 安装: wget http://nginx.org/download/nginx-1.9.3.tar.gz cd nginx-1.9.3 ./configure --prefix/usr/local/nginx发现一个问题: checking for PCRE library ... not found checking for P…

加速电子化报销费控服务,易快报完成1500万美元B轮融资
2019年1月21日,报销费控领头羊品牌——易快报对外宣布完成1500万美元B轮系列融资,本轮融资由美元基金曼图资本领投,DCM、明势、银杏谷等投资机构跟投,冲盈资本为本轮独家财务顾问。国内报销费控SaaS行业是个潜力巨大的增量市场&am…

[转]C# 2.0新特性与C# 3.5新特性
C# 2.0新特性与C# 3.5新特性 一、C# 2.0 新特性: 1、泛型List<MyObject> obj_listnew List();obj_list.Add(new MyObject()); 2、部分类(partial)namespace xxx{public partial class Class1{private string _s1;public string S1{get { return _s1; }set { _…

你需要了解的load和initialize
NSObject类有两种初始化方式load和initialize load (void)load; 复制代码对于加入运行期系统的类及分类,必定会调用此方法,且仅调用一次。 iOS会在应用程序启动的时候调用load方法,在main函数之前调用 执行子类的load方法前,会…

iOS11、iPhone X、Xcode9 适配指南
2017.09.23 不断完善中。。。 2017.10.02 新增 iPhone X 适配官方中文文档 更新iOS11后,发现有些地方需要做适配,整理后按照优先级分为以下三类: 单纯升级iOS11后造成的变化;Xcode9 打包后造成的变化;iPhoneX的适配一、…

Grape和Sinatra结合使用
Grape && Sinatra Grape(https://github.com/intridea/grape) is a REST-like API micro-framework for Ruby Sinatra(http://www.sinatrarb.com/intro.html) is a DSL for quickly creating web applications in Ruby 可见,Grape适合构建纯Api系统…

公告三大“罪状”,无人驾驶公司Roadstar联合创始人被罢免
(从左至右依次是为周光、佟显乔、衡量) 整理 | Jane 出品 | AI科技大本营 1 月 21 日,因技术造假等违规行为,国内自动驾驶创业公司 Roadstar (深圳星行科技有限公司)官方宣布,罢免联合创始人周…

大雁悲歌,月哭泣
??时间,毫无感情的把这段故事剪成了碎片……??――题记????一??眺望天边那抹残红,心瞬间间抖落成一滴血。??无法愈合的伤口,夜夜繁衍着孤寂。爱,颈椎痛 ,这个烂熟于胸的字,有时真是扎心般刺眼,…

写高质量的代码,永不言晚!
作者 | Nitesh sharma 译者 | 弯月责编 | 郭芮出转载自 CSDN(ID:CSDNnews) 以下为译文: 在如今这个时代,每个人都在努力提升资源能力。在Web应用程序方面,我们有Spring、Play和Struts等框架,这…

ios searchBar 的代理方法 集合
下面是搜索框控件的一些代理方法: - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar;将要开始编辑时的回调,返回为NO,则不能编辑- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar;已经开始编辑时的回调- (BOOL)…

双绞线接法详解
一直以来很多人(包括作者)都认为10 base-t 10m网络使用了网线中8条信号线之4条,而100 base-t 100m则使用了全部8条信号线(要不怎么那么快呢?)。可是作者前不久在使用一条按所谓10m直连接法(1与3…

step by step YAML 复用
yaml文件适合用来描述软件测试过程的步骤。当不同类型的CI过程集中在一个yaml文件时,首先碰到的一个问题是:大量重复的步骤如何进行复用? 举个例子: stage1:run_it:exec:- A- B- C- D1stage2:run_it:exec:- A- B- C- D2显然&#…

在winform中从外部拖动节点到树形结构(treeview和listview相互拖动)(一)
最近一个项目要用到从listview向treeview拖动item,达到从外部拖动图标成为树形结构的一部分,通过查阅资料总结了一些实现方式,分享给大家。这是winform中的例子。 在进行拖放操作之前,必须要对进行拖放操作的组件的"AllowDro…

node 模块化 require expores,简易实现原理。
为了更好的理解 Node.js 的 require 实现机制,我实现了一个简易的版本。我们node index.js的时候就是require(./index.js),话不多说我们直接上代码: 目录index.jsa.jsb.jsc.jsindex.js use strictfunction $require(filepath) {const fs req…