Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Refactor block cache tracing APIs #9326

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

anand1976
Copy link
Contributor

Refactor the classes, APIs and data structures for block cache tracing to allow a user provided trace writer to be used. Currently, only a TraceWriter is supported, with a default built-in implementation of FileTraceWriter. The TraceWriter, however, takes a flat trace record and is thus only suitable for file tracing. This PR introduces an abstract BlockCacheTraceWriter class that takes a structured BlockCacheTraceRecord. The BlockCacheTraceWriter implementation can then format and log the record in whatever way it sees fit. The default BlockCacheTraceWriterImpl does file tracing using a user provided TraceWriter.

This same philosophy can be applied to KV and IO tracing as well.


// Write a trace header at the beginning, typically on initiating a trace,
// with some metadata like a magic number and RocksDB version.
virtual Status WriteHeader() = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need "WriteFooter"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we could call it on EndTrace() to keep it symmetrical.

#include "rocksdb/trace_record.h"

namespace ROCKSDB_NAMESPACE {
enum Boolean : char { kTrue = 1, kFalse = 0 };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use bool?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. The original definition of BlockCacheTraceRecord in block_cache_tracer.h used it and I just moved the definitions. There is a case for using an enum instead of bool if the constants have descriptive names, as it improves readability. But in this case, the constants are just kTrue and kFalse, which seems rather pointless. It might make more sense if we use something like enum CacheLookupResult : char { kCacheHit = 1, kCacheMiss = 0};.

Comment on lines +111 to +150
std::unique_ptr<BlockCacheTraceWriter> NewBlockCacheTraceWriter(
SystemClock* clock, const BlockCacheTraceWriterOptions& trace_options,
std::unique_ptr<TraceWriter>&& trace_writer);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not make the BlockCacheTraceWriter a Customizable class and use that infrastructure? That will make it simpler if you ever intend to add alternative implementations.

// BlockCacheTraceWriter is an abstract class that captures all RocksDB block
// cache accesses. Every RocksDB operation is passed to WriteBlockAccess()
// with a BlockCacheTraceRecord.
class BlockCacheTraceWriter {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the very least, the class should have a "virtual const char *Name() const = 0" to allow alternate implementations later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I plan to make it a Customizable class.

public:
virtual ~BlockCacheTraceWriter() {}

// Pass Slice references to avoid copy.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment stating what this method does?

Comment on lines 1162 to 1157
assert(c->block_cache_tracer_
.StartTrace(env_->GetSystemClock().get(), trace_opt,
std::move(trace_writer))
.StartTrace(trace_opt, std::move(block_cache_trace_writer))
.ok());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be an ASSERT_OK?

Copy link
Contributor Author

@anand1976 anand1976 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @zhichao-cao and @mrambacher for the review!

#include "rocksdb/trace_record.h"

namespace ROCKSDB_NAMESPACE {
enum Boolean : char { kTrue = 1, kFalse = 0 };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. The original definition of BlockCacheTraceRecord in block_cache_tracer.h used it and I just moved the definitions. There is a case for using an enum instead of bool if the constants have descriptive names, as it improves readability. But in this case, the constants are just kTrue and kFalse, which seems rather pointless. It might make more sense if we use something like enum CacheLookupResult : char { kCacheHit = 1, kCacheMiss = 0};.

include/rocksdb/block_cache_trace_writer.h Show resolved Hide resolved
// BlockCacheTraceWriter is an abstract class that captures all RocksDB block
// cache accesses. Every RocksDB operation is passed to WriteBlockAccess()
// with a BlockCacheTraceRecord.
class BlockCacheTraceWriter {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I plan to make it a Customizable class.


// Write a trace header at the beginning, typically on initiating a trace,
// with some metadata like a magic number and RocksDB version.
virtual Status WriteHeader() = 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we could call it on EndTrace() to keep it symmetrical.

@mdcallag
Copy link
Contributor

Block cache tracing caused the largest regression early in the 6.x cycle, it was eventually fixed (or mostly fixed). Do you have results to confirm this doesn't add CPU overhead when disabled? db_bench --benchmarks=fillseq,readrandom should be sufficient.

@riversand963
Copy link
Contributor

Block cache tracing caused the largest regression early in the 6.x cycle, it was eventually fixed (or mostly fixed). Do you have results to confirm this doesn't add CPU overhead when disabled? db_bench --benchmarks=fillseq,readrandom should be sufficient.

Thanks @mdcallag for the input. Just to catch up, are you referring to a8975b6 as the "eventual fix"?

@anand1976 anand1976 added the WIP Work in progress label Jan 14, 2022
@anand1976
Copy link
Contributor Author

Block cache tracing caused the largest regression early in the 6.x cycle, it was eventually fixed (or mostly fixed). Do you have results to confirm this doesn't add CPU overhead when disabled? db_bench --benchmarks=fillseq,readrandom should be sufficient.

@mdcallag I haven't run any benchmarks yet, but will do and ensure there's no regression. This was a draft in order to get some early feedback


namespace ROCKSDB_NAMESPACE {
// A record for block cache lookups/inserts. This is passed by the table
// reader to the BlockCacheTraceWriter for every block cache op.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we indicate that the class/interfaces/structs in this file is experimental and may be changed in the future?

@zhichao-cao
Copy link
Contributor

So, this change will not continue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed WIP Work in progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants