腾讯工程师教你玩转 RocksDB

千亿国际娱乐

2018-02-28 21:27:13

更多腾讯海量技术文章,请关注云 社区: Intro

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

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

调用SHOW ENGINE ROCKSDBicros。

BG_THREADS: 后台线程的状态。

DBSTATS: 数据库操作的统计。

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

MEMORY_STATS: 内存使用情况。

调用SHOW ENGINE ROCKSDB 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增加计数。

使用STATISTICS的方法也很简单。

它的头文件位于:

使用方法:

可选统计级别:

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

kExceptTimeForMutex: 除去mutex等待的计时

kAll: 所有

数据统计类型分成两种:

ticker:计数,类型是64位无符号整型。用于度量countershit”), cumulative byteswritten”) 或者 timeicros”)。

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

统计函数的接口:

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

RecordTick:累加ticker。

获取结果的接口:

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

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

Statistics::getHistogramString:指定Histograms2 RocksDB的STATISTICS实现

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

主要接口:

getTickerCount

histogramData

getHistogramString

getAndResetTickerCount

recordTick

measureTime

ToString

成员变量:

TickerInfo tickers_[INTERNAL_TICKER_ENUM_MAX];

HistogramInfo3 MyRocks的使用

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

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

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

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

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

commit_latency_stats是直方图的类型,输出对应的50%, 95%, 99%, 后台线程

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

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

它的头文件位于:

关键类:

ThreadStatusUpdater:存储了各自后台线程的状态和所有后台线程状态的指针。ThreadStatusUtil:该类只有静态变量和静态方法,推荐通过该类的方法去更新ThreadStatusUpdater中的状态。

使用方法:

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

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

其他修改threadh

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

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

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

flush特有的状态值有:

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

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