当前位置: 首页 > 编程日记 > 正文

Rocksdb 的一些参数调优策略

文章目录

    • 写性能优化
      • CF write buffer size
      • DB write buffer size
    • 读性能优化
      • block cache
      • bloom filter
      • Compression 压缩
    • Compaction优化
    • 通用workload的配置

本文在rocksdb 整个读写链路基础上给出一些简单的调优策略,主要是通过调整一些 参数来满足我们大多数workload的性能需求。

更详细的源代码分析暂不涉及,一部分调优机制的源代码分析之前的部分文章中已经有过描述,需要的话会在文中提及。6.4及以上版本的实现中有超过200个参数,对于大多数使用rocksdb的同学来说实在是负担太重,想要通过分析源代码来明确每一个参数的深层含义以及在不同workload下的其表现最优的值显然是不可能的,所以只需要明确核心链路的可优化点即可。

通过本文,能够清楚 读写性能调优,compaction的核心调优,通用的优化配置。

写性能优化

我们知道rocksdb是基于LSM架构的单机存储引擎,其拥有高效的写吞吐。为了保证一致性,整个写入链路会先写WAL,再写memtale即可返回。其中WAL如果开了sync,则需要走一次I/O ,memtable是一个内存数据结构,通常是跳表实现的,基本属于CPU计算。后续数据在memtable的罗盘则通过异步的flush来进行。

wal的写入无法避免,写入参数上的优化就主要集中在写memtable上了。
rocksdb提供了write buffer size的配置,即单个memtable能够接受的最大写入量,并且提供了可以设置每一个DB/ColumnFamily 的写缓存配置。

CF write buffer size

cf_options.write_buffer_size = 64 << 20; 默认是64M。

可以用来设置以Column Family为单位的缓存大小。设置之前最好预估一下最坏情况下的内存使用量,如果发现内存不够用,那么需要降低这个数值。

DB write buffer size

db_options.write_buffer_size = 64 << 30;默认值是0。
这个配置用来设置整个db 所有column family 共享的write buffer size, 表示整个db的write buffer size达到阈值,会对当前db的所有cf进行flush。

如果需要改变这个值,可以通过如上参数的方式将该值设置为64G。

读性能优化

block cache

block cache 主要是用来缓存解压后的数据。blockcache的大小,社区给的建议是 整个内存有效负载大小的1/3。即如果内存有效负载是240G(240G的used的情况下操作系统仍能正常工作,不需要回收低优先级的进程内存),那么blockcache的大小就设置为80G。

block cache的配置可以通过table_options来进行设置,需要注意的是为了保证所有的column family共用一个blockcache,需要让table_options对象所有的cf_options的table_factory公用。

auto cache = NewLRUCache(128 << 20);  // LRUcacheBlockBasedTableOptions table_options;
table_options.block_cache = cache;auto table_factory = new BlockBasedTableFactory(table_options);
cf_options.table_factory.reset(table_factory);

bloom filter

如果你的系统中有查找相关的操作,建议打开bloom filter这个配置。bloom filter主要是用来过滤sst文件中不存在的key的查找请求,可以在O(1)时间内完成这个操作,而不需要额外的CPU计算和昂贵的I/O操作。

需要注意的是bloom filter能够有效提升点查性能,却无法提升range scan的性能。

通过如下配置来打开bloom filter,并将bloom filter位数设置为10位。

rocksdb::BlockBasedTableOptions table_options;
table_options.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false));auto table_factory = new rocksdb::BlockBasedTableFactory(table_options);
cf_options.table_factory.reset(table_factory);

Compression 压缩

压缩的主要目的是为了节省空间但却有读性能 以及 系统CPU和 磁盘I/O的额外消耗,因为需要将读到的datablock 进行解压,这个过程会有CPU的计算和I/O代价,所以这个配置选项是一个权衡。

rocksdb提供了不同压缩算法的选择:

  • cf_options.compression 这个配置控制的是前n-1层的压缩算法,建议使用lz4(kLZ4Compression)算法,如果不可用的话再选择snappy(kSnappyCompression)
  • cf_options.bottommost_compression 控制最后一层的压缩算法,建议使用ZStandard(kZSTD),如果不可用的话可以选择Zlib(kZlibCompression)

为什么要有这样的针对不同层的不同压缩算法的配置?
因为n-1层 的sst文件还是有比较高的概率被读到,所以空间的压缩比不需要那么高,为了降低压缩对系统资源和性能的消耗,编解码的效率则会优先考虑。但文件落到了第n层, 这个文件被读到的概率就比较低,可以设置相对较高的压缩比。

Compaction优化

关于Compaction 的原理及其所带来的问题,之前的多篇文章也有详细描述。
Rocksdb Compaction 源码详解(一):SST文件详细格式源码解析
Rocksdb Compaction源码详解(二):Compaction 完整实现过程 概览
Rocksdb 的 rate_limiter实现 – compaction限速
LSM 优化系列(三)SILK- Preventing Latency Spikes in Log-Structured Merge Key-Value Stores ATC‘19

这里也推荐大家使用rocksdb的Rate limiter进行限速,限速能够达到从I/O层面限制compaction的过程对系统资源CPU和IO的竞争的目的,从而保证客户端的请求无论是qps还是延时(当然qps和请求延时是有相关性的)能够较为平稳。

大家在使用rocksdb的过程中如果发现客户端的请求受到compaction的I/O 竞争,可以选择RateLimiter的配置接入。
通过如下配置进行设置:

db_options.rate_limiter.reset(rocksdb::NewGenericRateLimiter(rate_bytes_per_sec /* int64_t */,refill_period_us /* int64_t */,fairness /* int32_t */));

核心参数如下三个:

  • rate_bytes_per_sec 这个是最常用也是大家使用起来最有效的一个参数,用来控制compaction或者flush过程中每秒写入的量。比如,设置了200M, 表示当compaction 累积的总写入token达到 200M /s 时才会触发系统调用的write.
  • refill_period_us 用来控制 token 更新的频率;比如设置的rate_bytes_per_sec是10M/s, 且refill_period_us 设置的是100ms,那么表示 每100ms即可重新调用一次compaction的写入。针对1M的大value 可以立即写入,而小于1M的数据则需要消耗CPU, 累积到1M 触发一次写入。
  • fairness 表示低优先级请求获得处理的概率。
    RateLimiter 支持接受高优先级线程 和 低优先级线程的请求,一半flush操作是最高的优先级,其次是 L0 --> L1 compaction优先级较高,最后则是Higher Level compactions 优先级最低。那么这个参数 fairness表示 即使现在有较多的高优先级任务在调度,低优先级的任务也有 1 / fairness 的机会能够被调度,从而防止被饿死。

更加详细的原理实现可以参考:
Rocksdb 的 rate_limiter实现 – compaction限速

通过测试接入RateLimiter(限速128M),在100B 的9:1读写比场景,无压缩,单db 500G, blockcache 10G的配置下
L5的P9999 读延时由原来的120ms量级
在这里插入图片描述
降到了2-3ms的量级
在这里插入图片描述
具体的RateLimiter配置需要在实际场景中进行测试,如果写入量比较大,带来的compaction的量也会很大,相应的限速带宽应该更高。

通用workload的配置

下面的这一些配置也是社区提供的他们认为比较通用的配置,大家在检查的过程中会发现这一些配置和我们的默认配置还是有较大差异。 社区为了防止新老版本的db 配置差异导致的一些问题,所以基本没有怎么修改过默认rocksdb的配置项,一直沿用最初的默认配置。

如果用户需要重新加载一个 新的db,那么建议使用这里的配置,能够有较好的性能提升,并不建议直接在旧的db上应用。

基本的配置选项如下:

// 动态调整L0--Ln的大小,保证L0-->L1能够及时刷新,不会因为容量不足而阻塞上层的flush。能够比较好得维护
// LSM tree的树状结构
cf_options.level_compaction_dynamic_level_bytes = true;// 最大compaction的线程数
options.max_background_compactions = 4;
options.max_background_flushes = 2;// flush/compaction 每次sync的数据量,即data block累计达到1M 触发一次sync
options.bytes_per_sync = 1048576;// compaction 过程中选择文件的优先级,能够降低写放大
// 配置了这个参数,会优先选择和下一层sst文件覆盖度较低的文件进行compaction,减少compaction过程中被反复读出写入
options.compaction_pri = kMinOverlappingRatio; // 设置block_size,这里的block是指sst文中的一个个数据block(data,index,filter,meta,range del)
table_options.block_size = 16 * 1024;
table_options.cache_index_and_filter_blocks = true;
table_options.pin_l0_filter_and_index_blocks_in_cache = true;

以上通用的配置就社区的推荐 以及 实际测试过程中发现 并不会有成倍的性能提升, 在不同的通用workload下拥有较好的性能。

所以如果拥有较强的研发实力 以及 对特定的业务场景拥有强需求 ,那么对rocksdb进行定制化改造是一个更加合适的选择。就像阿里的x-engine,针对电商业务的洪峰,泄洪,洋流三个问题 进行了LSM 重写,这样的优化在特定的业务场景所产生的收益肯定比通用的rocksdb的收益来的更加彻底。

相关文章:

Java项目:酒店管理系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 主要技术:java springmvc mybatis mysql tomcat js jauery jsp log4j等一些常见基本技术适用于Java毕设和学习使用 主要实现&#xff1a; 前台&#xff1a;登录、注册、酒店信息浏览、搜索酒店信息…

设计模式之装饰模式(Java实现)

“怎么了&#xff0c;鱼哥&#xff1f;” “唉&#xff0c;别提了&#xff0c;网购了一件衣服&#xff0c;结果发现和商家描述的差太多了&#xff0c;有色差就算了&#xff0c;质量还不好&#xff0c;质量不好就算了&#xff0c;竟然大小也不行&#xff0c;说好的3个X&#xff…

ueditor与七牛云存储结合

2019独角兽企业重金招聘Python工程师标准>>> 摘要&#xff1a; ueditor与七牛云存储结合&#xff0c;主要是表单api. ueditor上传图片到七牛云存储 ueditor结合七牛传图片 传统上&#xff0c;图片是存在自己的服务器上(图片->自己服务器)&#xff0c;如果使用…

微服务网关从零搭建——(七)更改存储方式为oracle

资源准备&#xff1a; 下载开源项目 新建oracle表&#xff1a; -- ---------------------------- -- Table structure for OcelotGlobalConfiguration -- ----------------------------CREATE TABLE OcelotGlobalConfiguration (Id NUMBER(11) NOT NULL ,GatewayName NVARCHAR2…

Rocksdb 的优秀代码(一) -- 工业级分桶算法实现分位数p50,p99,p9999

文章目录基本概念普通的分位数计算Rocksdb中的应用rocksdb中的分桶算法结果展示rocksdb 分桶算法实现一些总结 和 相关论文我们知道一个完整的监控系统必须存在p99/p999等分位数指标&#xff0c;作为系统可用性的评判标准之一。而像开源监控系统中做的很不错的grafana和prometh…

Java项目:前后端分离疫情防疫平台设计和实现(java+springmvc+VUE+node.js+mybatis+mysql+springboot+redis+jsp)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 主要技术&#xff1a;Java、springmvc、VUE、node.js、mybatis、mysql、tomcat、jquery、layui、bootstarp、JavaScript、html、css、jsp、log4j等一些常见的基本技术。 主要模块功能有&#xff1a; 管理员…

js里的匿名函数 数组排序

// 匿名函数&#xff1a;其实就是函数的简写形式 var method function(){ alert("123"); } method(); // 匿名函数可以用于事件的处理 function func(){ alert("456"); } window.οnlοadfunc; window.οnlοadfunction(){ alert("加载完成&#xff0…

oracle监听器动态注册于静态注册的区别

2019独角兽企业重金招聘Python工程师标准>>> 1, oracle 10g 用netca方式建立的都默认为动态注册方式 2&#xff0c;如果想改为静态注册的方式则在listener.ora 中加入如下内容即可 SID_LIST_LISTENER (SID_LIST (SID_DESC (SID_NAME PLSExtProc) (ORACLE_HOME …

什么是Singleton?

Singleton&#xff1a;在Java中即指单例设计模式&#xff0c;它是软件开发中最常用的设计模式之一。 单&#xff1a;指唯一 例&#xff1a;指实例 单例设计模式&#xff0c;即某个类在整个系统中只能有一个实例对象可被获取和使用的代码模式。 要点&#xff1a; 一、单例类只能…

磁盘I:O 性能指标 以及 如何通过 fio 对nvme ssd,optane ssd, pmem 性能摸底

文章目录1. 磁盘I/O性能指标1.1 性能指标1.2 I/O 观测1.2.1 磁盘I/O 观测1.2.2 进程I/O观测2. Fio 性能测试2.1 环境准备2.2 测试维度选择2.3 测试2.3.1 optane ssd和nvme ssd性能测试2.3.2 aep性能测试(intel persistent memory)真正测试之前 我们需要清楚 评判磁盘I/O性能 是…

Java项目:旅游网站管理系统设计和实现(java+springboot+jsp+mysql+spring)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 运行环境: java jdk 1.8 IDE环境&#xff1a; IDEA tomcat环境&#xff1a; Tomcat 7.x,8.x,9.x版本均可 主要功能说明&#xff1a; 管理员角色包含以下功能&#xff1a;管理员登录,用户管理,旅游路线管理,…

稀疏矩阵十字链表表示

类型定义 #include<stdio.h> #include<malloc.h> #include<stdlib.h> #define MAX 100 /*稀疏矩阵的十字链表表示&#xff1a;非零元素节点与表头节点公用一种类型 */ typedef struct matrixnode {int row,col;struct matrixnode *right,*down;union{int val…

thrift框架使用C++

2019独角兽企业重金招聘Python工程师标准>>> 1. 编写thrift接口文件student.thrift struct Student{1: i32 sno,2: string sname,3: bool ssex,4: i16 sage, } service Serv{i32 put(1: Student s), } 2. 用“thrift -r --gen cpp student.thrift”在gen-cpp文件夹中…

shell编程:实现shell字符串连接功能

功能&#xff1a;实现shell字符串连接功能 a0 s1test. s2.wav s3.mp3 s40 s500str"sox ./${s1}${a}${s2} ./${a}${s3}"./tts -c bcgirl.0.0.4.bin -b 1 -i input.txt -s 1.0 -speed 1.0 $str rm ./*.wav转载于:https://www.cnblogs.com/kay2018/p/10673110.html

一文运维zookeeper

文章目录1. zookeeper生产环境的安装配置1.1 软件配置1.2 硬件配置1.3 日志配置文件1.4 配置三节点的zookeeper集群2. zookeeper的监控方法2.1 four letters命令2.2 JMX 监控方式3. 通过zookeeper observer实现跨地域部署3.1 什么是observer3.2 observer 提升 写性能3.3 observ…

Java项目:电商书城平台系统设计和实现(java+springboot+mysql+spring+jsp)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; JAVA springboot 电商书城平台系统(已调试) 主要实现了书城网站的浏览、加入购物车操作、订单操作、支付操作、分类查看、搜索、以及后台上传图书信息以及订单管理和一些基本操作功能 主要功能截图如下&…

(周三赛)FATE

//题意 打怪的经验值 &#xff0c;消耗忍耐度 看升级后还能保留的最大忍耐度 用 背包去做&#xff0c;不是很会啊 T T Description 最近xhd正在玩一款叫做FATE的游戏&#xff0c;为了得到极品装备&#xff0c;xhd在不停的杀怪做任务。久而久之xhd开始对杀怪产生的厌恶感&#…

ASP.NET MVC 3中ViewBag, ViewData和 TempData

ViewBag, ViewData十分类似&#xff0c;都可用于把数据从controller传递到view。 ViewBag是WebViewPage中的一个属性&#xff0c;它的类型是dynamic。dynamic类型可以理解为&#xff0c;编译器在编译到这种类型时&#xff0c;会跳过类型检查&#xff0c;而在运行时做这些事情。…

如何在指定文件夹下进入jupyter notebook

第一步&#xff1a; 打开 Anaconda Prompt 第二步&#xff1a; 查看文件夹所在路径 例如&#xff1a;你有个jupyterwork文件夹在 D:\ 路径下 第三步&#xff1a; 在Anaconda Prompt依次输入一下命令&#xff1a; d:cd jupyterworkjupyter notebook完成。转载于:https://www.cnb…

Go 分布式学习利器(16) -- go中可复用的package构建

通过本文&#xff0c;你将了解go 语言中如何将自己的package构建到项目中 以及如何将远程&#xff08;github&#xff09;的package构建到项目中。 1. 构建本地的package package 是可复用模块的基本单元&#xff0c;以首字母大写的函数实现来表明可被包外代码访问代码的pack…

JQuery UI

//拖拽插件 draggable <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"><head><title>拖曳…

Java项目:房屋租赁系统设计和实现(java+ssm+mysql+spring+jsp)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 主要功能描述&#xff1a; 1.登录管理&#xff1a;主要有管理员登录和租客登录 2.房源列表以及添加房源功能&#xff1a; 3.租赁合同管理以及在租房源和已退租房源信息管理: 4.看房申请和退租申请管理&a…

学习网页制作中如何在正确选取和使用 CSS 单位

在 CSS 测量系统中&#xff0c;有好几种单位&#xff0c;如像素、百分比、英寸、厘米等等&#xff0c;Web 开发人员很难了解哪些单位在何处使用&#xff0c;如何使用。很多人习惯了总是使用同一种单位&#xff0c;但这一决定可能会严重限制你的设计的执行。 这里推荐的《Which …

SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并

Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目。 传送门&#xff1a; 洛谷 P4513 小白逛公园-区间最大子段和-分治线段树区间合并(单点更新、区间查询) 代码: 1 #include<bits/stdc.h>2 using namespace std;3 typedef long long l…

Zookeeper ZAB协议原理浅析

文章目录前言1. 基本角色和概念2. Leader Election3. Discovery4. Synchronization5. BroadCast后记前言 DTCC 要在下周一到周三要在北京举办&#xff0c;身边有不少人都去参加了&#xff0c;领略中国最为领先的一些公司的自研存储技术。 阿里自研polardb&#xff0c;polardb-…

Java项目:仓库管理系统设计和实现(java+ssm+springboot+layui)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 主要功能模块 1.用户模块管理&#xff1a;用户登录、用户注册、用户的查询、添加、删除操作、 2.客户信息管理&#xff1a;.客户列表的展示、添加、修改、删除操作、 3.供应商管理&#xff1a;供应商详情…

Java Web 中的一些问题

http://localhost:8080/struts2demo/online/userLogin.jsp 请求模式 :// 主机名名称&#xff08;或者服务器名称&#xff09; : 端口 / Servlet容器的名称&#xff08;通常为项目名称&#xff09; / 自定义的网页文件夹名或者映射中的文件包名 / 网页名称及其后缀或者响应动作…

《零成本实现Web自动化测试--基于Selenium》第一章 自动化测试基础

第一篇 Selenium 和WebDriver工具篇 第一章 自动化测试基础 1.1 初识自动化测试 自动化测试有两种常见方式 1.1.1 代码驱动测试&#xff0c;又叫测试驱动开发&#xff08;TDD&#xff09; 1.1.2 图形用户接口测试: 测试框架产生用户接口事件&#xff08;例如键盘敲击&#x…

第11章 AOF持久化

AOF持久化在硬盘上保存的是对Redis进行的逻辑操作&#xff0c;类似InnoDB中的bin log。说白了就是你对一个Redis输入了哪些语句&#xff0c;AOF文件都会原封不动的保存起来&#xff0c;等到需要回复Redis的时候再把这些语句执行一遍。 11.1 AOF持久化的实现 AOF简单的理解是把执…

Go 语言实现字符串匹配算法 -- BF(Brute Force) 和 RK(Rabin Karp)

今天介绍两种基础的字符串匹配算法&#xff0c;当然核心还是熟悉一下Go的语法&#xff0c;巩固一下基础知识 BF(Brute Force)RK(Rabin Karp) 源字符串&#xff1a;src, 目标字符串:dest&#xff1b; 确认dest是否是src 的一部分。 BF算法很简单暴力&#xff0c;维护两个下标…