rocksdb原理_教你玩转MyRocks/RocksDB—STATISTICS与后台线程篇

0. Intro

在facebook的MySQL版本(以下称为MyRocks)中,RocksDB是可选的存储引擎。相比于InnoDB引擎,RocksDB的一个重要的优势是它使用更少的磁盘空间。在生产系统中,特别是用户数在亿级以上的互联网应用,磁盘空间是其中比较大的成本之一,而能够使用更少的磁盘空间的RocksDB无疑是具有吸引力的。然而在生产系统中使用新的存储引擎自然有它的潜在风险,除了通过外部的各种benchmark工具测试得到各种性能数据,全方位的内部指标可以帮助我们真正了解数据库内部正在发生的事情,对于性能调优和开发都具有指导意义。而MyRocks通过SHOW ENGINE ROCKSDB STATUS和多个INFORMATION_SCHEMA表等方式提供了较为全面的内部指标。

本文将介绍SHOW ENGINE ROCKSDB STATUS中关于STATISTICS统计值与后台线程的实现原理。在了解实现原理的基础上,便可以较容易地通过扩展功能使它更好地为我们服务。

调用SHOW ENGINE ROCKSDB STATUS指令会返回多行数据,其中包括:

STATISTICS:RocksDB引擎所有线程的所有操作的各类count/time的累加,比如rocksdb.block.cache.hit和rocksdb.db.write.micros。

BG_THREADS: 后台线程的状态。

DBSTATS: 数据库操作的统计。

CF_COMPACTION: 各个Column family进行compaction的相关指标统计。

MEMORY_STATS: 内存使用情况。

调用SHOW ENGINE ROCKSDB STATUS会返回若干行数据,然而这些数据并非事先存储于某个表格中,而是通过调用位于rocksdb/ha_rocksdb.cc文件中的rocksdb_show_status函数将内存中对应的数值进行规整返回给用户。

1. STATISTICS

根据RocksDB官方相关文档介绍STATISTICS,开启STATISTICS会增加增加5%-10%额外开销。

STATISTICS统计值记录着RocksDB引擎所有线程的所有操作的各类count/time的累加。RocksDB引擎在它的各类操作如Put/Get/Delete中的代码都设立了很多埋点。

以函数GetEntryFromCache为例,它的作用是返回可用的block cache。特别地,可以看到statistics是GetEntryFromCache和block_cache->Lookup的一个参数。没错,就是靠着statistics这个参数它到处收集数据。

当有可用的block cache时,调用了三次RecordTick为其中三个统计值增加计数;没有可用的block cache,同样也为BLOCK_CACHE_MISS和block_cache_miss_ticker增加计数。

Cache::Handle* GetEntryFromCache(Cache* block_cache, const Slice&key,

Tickers block_cache_miss_ticker,

Tickers block_cache_hit_ticker,

Statistics*statistics) {

auto cache_handle = block_cache->Lookup(key,statistics);

if (cache_handle != nullptr) {

PERF_COUNTER_ADD(block_cache_hit_count, 1);

// overall cache hit

RecordTick(statistics, BLOCK_CACHE_HIT);

// total bytes readfromcache

RecordTick(statistics, BLOCK_CACHE_BYTES_READ,

block_cache->GetUsage(cache_handle));

// block-type specific cache hit

RecordTick(statistics, block_cache_hit_ticker);

} else{

// overall cache miss

RecordTick(statistics, BLOCK_CACHE_MISS);

// block-type specific cache miss

RecordTick(statistics, block_cache_miss_ticker);

}

returncache_handle;

}

1.1 RocksDB的STATISTICS接口

使用STATISTICS的方法也很简单。

它的头文件位于:

include/rocksdb/statistics.h

monitoring/statistics.h

使用方法:

Options options;

options.statistics= rocksdb::CreateDBStatistics();

可选统计级别:

kExceptDetailedTimers: 除去mutex等待和压缩的计时

kExceptTimeForMutex: 除去mutex等待的计时

kAll: 所有

数据统计类型分成两种:

ticker:计数,类型是64位无符号整型。用于度量counters (e.g. “rocksdb.block.cache.hit”), cumulative bytes (e.g. “rocksdb.bytes.written”) 或者 time (e.g. “rocksdb.l0.slowdown.micros”)。

histogram:统计数据的统计分布,包括***值、最小值、平均值、中位数、标准差。

统计函数的接口:

MeasureTime:函数名有歧义。实际上是把value记录到histogram中。

RecordTick:累加ticker。

获取结果的接口:

Statistics::getTickerCount:指定ticker type获得count。

Statistics::histogramData:指定Histograms type,返回一个HistogramData结构体,成员是统计值,包括***值、最小值、平均值、中位数、标准差。

Statistics::getHistogramString:指定Histograms type,返回直方图可读的字符串。

Statistics::ToString():返回可读的字符串,包括所有的ticker和histogram。

1.2 RocksDB的STATISTICS实现

RocksDB实现了StatisticsImpl类,继承了Statistics的接口。

主要接口:

getTickerCount

histogramData

getHistogramString

getAndResetTickerCount

recordTick

measureTime

ToString

成员变量:

TickerInfo tickers_[INTERNAL_TICKER_ENUM_MAX];

HistogramInfo histograms_[INTERNAL_HISTOGRAM_ENUM_MAX];

这里的TickerInfo和HistogramInfo类型的数据结构是相似的:一个线程局部的counter或者time;加上一个非线程局部的统计值用来累加counter或者time。

TickerInfo类型包含两个参数:

ThreadLocalPtr类型(真实类型ThreadTickerInfo)的thread_value,包含:

整型类型的value

指向merged_sum的指针

整型类型的merged_sum

HistogreamInfo类型包含两个参数:

ThreadLocalPtr类型(真实类型ThreadHistogramInfo)的thread_value,包含:

HistogramImpl类型的value

指向merged_hist的指针

指向merge_lock的指针

HistogramImpl类型的merged_hist

Mutex类型的merge_lock

事实上,STATISTICS相关实现是比较巧妙的,也是使用STATISTICS仅增加5%-10%的关键。为了避免线程间共享数据导致CPU的cache频繁失效,merged_sum和merged_hist初始化时都是空的,而且当且仅当线程退出时,才调用mergeThreadValue函数将TickerInfo和HistogreamInfo中的线程局部变量累加到merged_sum和merged_hist。

1.3 MyRocks的使用

MyRocks使用了RocksDB提供的接口进行数据统计。通过声明了变量rocksdb_stats,并且随着RocksDB引擎启动时通过rocksdb_init_func函数进行初始化。

rocksdb_stats = rocksdb::CreateDBStatistics();

rocksdb_db_options->statistics= rocksdb_stats;

除了使用所有RocksDB引擎层的统计,MyRocks还通过定义了

commit_latency_stats = new rocksdb::HistogramImpl();

在rocksdb_commit_by_xid和rocksdb_commit两个函数中通过计时的方式,统计了每一次commit所花费的时间。

rocksdb::StopWatchNano timer(rocksdb::Env::Default(),true);

...

commit_latency_stats->Add(timer.ElapsedNanos() / 1000);

在rocksdb_show_status函数中,输出Statistics统计的过程如下:

如果定义rocksdb_stats,则调用rocksdb_stats->ToString()将统计值转化为可读的字符串;

commit_latency_stats是直方图的类型,输出对应的50%, 95%, 99%, 100%四个位点的对应的值。

假如定义了is-write-stopped或者actual-delayed-write-rate等Property变量,同样会将它们输出。

2 后台线程

通过调用SHOW ENGINE ROCKSDB STATUS可以得到与BG_THREADS相关结果,它的输出结果类似于:

Type: BG_THREADS

Name: 140173379593984

Status:

thread_type: Low Pri##

cf_name: default

operation_type: Compaction

operation_stage: CompactionJob::ProcessKeyValueCompaction

elapsed_time_ms: 6172.244 ms

BaseInputLevel: 0

BytesRead: 992806363

BytesWritten: 992071408

IsDeletion: 0

IsManual: 0

IsTrivialMove: 0

JobID: 1936

OutputLevel: 5

TotalInputBytes: 1586832446

state_type:

可以看到较多的信息量:这个线程正在进行Compaction,处于CompactionJob::ProcessKeyValueCompaction阶段,已经耗时6172.244 ms,读取的字节数为992806363,写出的字节数为992071408。然而并不包括可能感兴趣的正在进行Compaction的源文件和目标文件等信息。正如文章开头提到的,了解实现原理能够使我们更好地进行扩展。

2.1 thread status的接口与实现

MyRocks中的SHOW ENGINE ROCKSDB STATUS指令展示BG_THREAD的机制使用了RocksDB中关于thread status的接口。

它的头文件位于:

include/rocksdb/env.h

include/rocksdb/thread_status.h

util/thread_operation.h

monitoring/thread_status_updater.h

monitoring/thread_status_util.h

关键类:

ThreadStatusUpdater:存储了各自后台线程的状态和所有后台线程状态的指针。

ThreadStatusUtil:该类只有静态变量和静态方法,推荐通过该类的方法去更新ThreadStatusUpdater中的状态。

使用方法:

将该线程的统计加入ThreadStatusUpdater:调用ThreadStatusUtil::RegisterThread

将该线程的统计从ThreadStatusUpdater删除:调用ThreadStatusUtil::UnregisterThread

其他修改thread status的函数:见monitoring/thread_status_util.h

通过调用env的GetThreadList()函数可以获得当前后台线程的状态,状态的状态值存放于一个vector中。将其中的内容展现出来,类似于下图:

从代码中可以看到,实现thread status的目的展示flush和compaction的运行状态。当然,我们也可以将用户线程的状态存储到thread status,通过调用SHOW ENGINE ROCKSDB STATUS指令展示。

特别地,可以看到compaction特有的状态值有:

enum CompactionPropertyType :int{

COMPACTION_JOB_ID = 0,

COMPACTION_INPUT_OUTPUT_LEVEL,

COMPACTION_PROP_FLAGS,

COMPACTION_TOTAL_INPUT_BYTES,

COMPACTION_BYTES_READ,

COMPACTION_BYTES_WRITTEN,

NUM_COMPACTION_PROPERTIES

};

flush特有的状态值有:

enum FlushPropertyType :int{

FLUSH_JOB_ID = 0,

FLUSH_BYTES_MEMTABLES,

FLUSH_BYTES_WRITTEN,

NUM_FLUSH_PROPERTIES

};

2.2 MyRocks/RocksDB的使用

在RocksDB的线程池实现中,每一个启动的后台线程都会通过调用ThreadStatusUtil::RegisterThread加入被观测的后台线程的集合中。

ThreadPoolImpl::Impl::StartBGThreads-->BGThreadWrapper-->ThreadStatusUtil::RegisterThread

在rocksdb_show_status函数中,输出BG_THREAD的过程如下:

通过调用GetThreadList(&thread_list)获得所有后台线程的ThreadStatus的集合。

通过遍历ThreadStatus的集合将每一个后台线程的状态依次输出。

3. 小结

本文章介绍了SHOW ENGINE ROCKSDB STATUS指令中关于STATISTICS与BG_THREAD的相关内容。

【编辑推荐】

【责任编辑:庞桂玉 TEL:(010)68476606】

点赞 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/381083.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有效需求分析的基本流程

今天工作不算太忙,本来下午是要开会,由于这周的idea比较少,就把AT会议移到下周一起开,所有今天没有什么忙的,只是开了简单的idea评审会议,同时对组内的一些问题进行简单的整理,本来想整理出好的…

PHP Socket 编程

让我们以一个简单的例子开始---一个接收输入字符串,处理并返回这个字符串到客户端的TCP服务.下面是相应的代码: PHP 代码: -------------------------------------------------------------------------------- <? // 设置一些基本的变量 $host "192.168.1.99";…

服务器可否替代手机芯片,基于ARM的处理器能取代桌面处理器吗?

科技的发展速度太快了&#xff0c;从手机进入智能时代开始&#xff0c;手机处理器的速度也越来越快了&#xff0c;以前人们办公都是在电脑端进行的&#xff0c;随着手机的功能越来越多&#xff0c;手机处理器速度越来越快&#xff0c;已经有一小部分的工作可以在手机上完成了。…

tr闭包_嵌套函数及闭包

这篇文章其实是要讲闭包的一些初级应用&#xff0c;但是为了将闭包&#xff0c;我们还是从嵌套函数开始说吧&#xff0c;纵使所有的JavaScript函数都可以说是闭包&#xff0c;但是只有当一个嵌套函数被导出到它所定义的作用域之外时&#xff0c;这种闭包才是有趣的。【嵌套函数…

转]从一个男人关注的事情上 可以看出他的修养和抱负

一、拥有自信和风度 男人到了二十几岁后&#xff0c;就要开始学着用心去经营自己了&#xff0c;它体现在自己的思想与涵养上。自信是一个男人最重要的品质&#xff0c;自信的男人就你像一只在暴风雨中战斗的海鸥。海鸥所要说的只有一句话“让暴风雨来的再猛烈些吧”&#xff0…

python歌星大奖赛_在歌星大奖赛中,有10个评委为参赛选手打分,分数为1到100分。...

/*********************************************************************************** 功能描述&#xff1a; 求一个比赛的选手成绩** 作 者&#xff1a; 郭强生** 修改日期&#xff1a; 2012-08-06** 备 注&#xff1a; 在歌星大奖赛中&#xff0c;有10…

投资最重要的事读后感_《投资最重要的事》读书笔记

《投资最重要的事》读书笔记《投资最重要的事》作者详细阐述了“第二层次思维”、价格/价值关系、耐心等待机会、以及多元化投资等概念&#xff0c;对自身的决策以及偶尔的失误做出了坦诚的评价&#xff0c;为读者进行批判性思考、风险评估、建立投资策略提供了宝贵的经验教训&…

VS2010 RTM

Visual Studio 2010 已经RTM并且在Msdn subscription提供了下载和试用版本&#xff0c;为了迎接这一产品&#xff0c;我在这个周末格式化了系统分区重新安装了Windows 7 x64。 在最新的Visual Assist配合下&#xff0c;整个IDE较之之前的版本更加舒适。 比如&#xff0c;选中的…

python搭建分布式集群_利用python的dask搭建分布式集群

一、dask介绍优势&#xff1a;dask内部自动实现了分布式调度、无需用户自行编写复杂的调度逻辑和程序&#xff1b;通过调用简单的方法就可以进行分布式计算、并支持部分模型的并行化处理&#xff1b;内部实现的分布式算法&#xff1a;xgboost、LR、sklearn的部分方法等用一句话…

【J2EE设计模式】模型-视图-控制器模式(MVC模式)

MVC将用户接口分割成3个截然不同的部分。 一、视图 状态无关的组件&#xff0c;从模型中读取数据&#xff0c;简单的把模型中的值转化为对客户端有用的格式。 二、控制器 协调请求处理&#xff0c;将用户输入转变为模型更新和视图 。它就像一个主管&#xff0c;首先策划要做哪些…

HttpURLConnection简单用法

HttpURLConnection为javaAPI提供的一种Rest访问的方式。其支持对Post,Delete,Get,Put等方式的访问。 以下为对于HttpURLConnection对Post等方式访问的一段代码。 view plaincopy to clipboardprint? 1. package com.sw.study.urlConnection; 2. 3. import java.io.Bu…

天勤python_天勤量化策略库:菲阿里四价策略

文章策略均基于开源免费&#xff0c;简单强大的Python量化开发包——天勤量化(TqSdk)实现菲阿里四价策略故事在2000年7月&#xff0c;日本举办了首次“ROBBINS-TAICOM期货冠军比赛”&#xff0c;总共比赛历时半年。从第一周起&#xff0c;一位名叫Fairy(菲阿里)的先生便位居首位…

个人宣传画

转载于:https://www.cnblogs.com/yellowyu/archive/2010/04/19/1715735.html

touch 连续创建文件_touch命令 – 创建文件

touch命令有两个功能&#xff1a;一是创建新的空文件&#xff0c;二是改变已有文件的时间戳属性。touch命令会根据当前的系统时间更新指定文件的访问时间和修改时间。如果文件不存在&#xff0c;将会创建新的空文件&#xff0c;除非指定了”-c”或”-h”选项。注意&#xff1a;…

转载CTF

1.MD5 compare漏洞 PHP在处理哈希字符串时&#xff0c;会利用”!”或””来对哈希值进行比较&#xff0c;它把每一个以”0E”开头的哈希值都解释为0&#xff0c;所以如果两个不同的密码经过哈希以后&#xff0c;其哈希值都是以”0E”开头的&#xff0c;那么PHP将会认为他们相同…

java jtable刷新_java-单击按钮更新JTable

I have searched on stackoverflow and a couple of people have said to use that method.不,您不应在TableModel本身的上下文之外调用任何fireTableXxx方法,否则人们会认为这完全是错误的,将来会给您带来麻烦.从代码的外观来看,什么都没有改变.如果您已根据上一个问题中提供的…

韩寒说世博会

先声明:我不是韩寒的什么粉丝,也不太关注这些作家的事情,希望这些文字能让你想到一些什么东西...........转载自:http://tieba.baidu.com/f?kz752703402 最近&#xff0c;老是有媒体要关于世博会采访我&#xff0c;我觉得很为难&#xff0c;如果我赞美他吧&#xff0c;估计我良…

windows系统下的云服务器部署tomcat

在环境配置没问题的基础下&#xff0c;如果启动服务器缺无法打开默认页面&#xff0c;则很有可能说明是你的端口问题&#xff1a; 这里我的解决方法&#xff1a; 控制面板-->系统和安全-->Windows 防火墙-->高级设置-->入站规则-->新建规则 依次选择端口-->…

营销公式

世界上最难得事情就是将别人的钱放到自己口袋。 要想别人给钱&#xff0c;首先要有控制别人的能力&#xff0c;例子&#xff0c;奴隶主能控制奴隶。 权力是来钱的关键因素。也就是说应该增加别人对你的依赖。 人们的弱点&#xff1a; 1.只看到短期利益&#xff0c;往往忽视长期…

centos修改磁盘uuid_Centos更换损坏硬盘UUID改变导致系统不能正常启动处理

Centos更换损坏硬盘UUID改变导致系统不能正常启动处理一、适用场景本文档的适用场景为&#xff0c;更换硬盘导致系统启动时因UUID不同&#xff0c;导致挂载文件读取失败&#xff0c;系统不能正常启动&#xff0c;同时本文档的处理方法也适用于fstab文件配置出错导致无法启动系统…