国外网站入口,利用影视网站做cpa,电网商城,如何在对方网站上做外链0. Intro在facebook的MySQL版本(以下称为MyRocks)中#xff0c;RocksDB是可选的存储引擎。相比于InnoDB引擎#xff0c;RocksDB的一个重要的优势是它使用更少的磁盘空间。在生产系统中#xff0c;特别是用户数在亿级以上的互联网应用#xff0c;磁盘空间是其中比较大的成本…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指令会返回多行数据其中包括STATISTICSRocksDB引擎所有线程的所有操作的各类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 Slicekey,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 hitRecordTick(statistics, BLOCK_CACHE_HIT);// total bytes readfromcacheRecordTick(statistics, BLOCK_CACHE_BYTES_READ,block_cache-GetUsage(cache_handle));// block-type specific cache hitRecordTick(statistics, block_cache_hit_ticker);} else{// overall cache missRecordTick(statistics, BLOCK_CACHE_MISS);// block-type specific cache missRecordTick(statistics, block_cache_miss_ticker);}returncache_handle;}1.1 RocksDB的STATISTICS接口使用STATISTICS的方法也很简单。它的头文件位于include/rocksdb/statistics.hmonitoring/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的接口。主要接口getTickerCounthistogramDatagetHistogramStringgetAndResetTickerCountrecordTickmeasureTimeToString成员变量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_sumHistogreamInfo类型包含两个参数ThreadLocalPtr类型(真实类型ThreadHistogramInfo)的thread_value包含HistogramImpl类型的value指向merged_hist的指针指向merge_lock的指针HistogramImpl类型的merged_histMutex类型的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_THREADSName: 140173379593984Status:thread_type: Low Pri##cf_name: defaultoperation_type: Compactionoperation_stage: CompactionJob::ProcessKeyValueCompactionelapsed_time_ms: 6172.244 msBaseInputLevel: 0BytesRead: 992806363BytesWritten: 992071408IsDeletion: 0IsManual: 0IsTrivialMove: 0JobID: 1936OutputLevel: 5TotalInputBytes: 1586832446state_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.hinclude/rocksdb/thread_status.hutil/thread_operation.hmonitoring/thread_status_updater.hmonitoring/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