| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
- // This source code is licensed under both the GPLv2 (found in the
- // COPYING file in the root directory) and Apache 2.0 License
- // (found in the LICENSE.Apache file in the root directory).
- #pragma once
- #include <utility>
- #include "rocksdb/file_system.h"
- namespace ROCKSDB_NAMESPACE {
- // A FileSystem simulates hybrid file system by ingesting latency and limit
- // IOPs.
- // This class is only used for development purpose and should not be used
- // in production.
- // Right now we ingest 15ms latency and allow 100 requests per second when
- // the file is for warm temperature.
- // When the object is destroyed, the list of warm files are written to a
- // file, which can be used to reopen a FileSystem and still recover the
- // list. This is to allow the information to preserve between db_bench
- // runs.
- class SimulatedHybridFileSystem : public FileSystemWrapper {
- public:
- // metadata_file_name stores metadata of the files, so that it can be
- // loaded after process restarts. If the file doesn't exist, create
- // one. The file is written when the class is destroyed.
- // throughput_multiplier: multiplier of throughput. For example, 1 is to
- // simulate single disk spindle. 4 is to simualte 4 disk spindles.
- // is_full_fs_warm: if true, all files are all included in slow I/O
- // simulation.
- SimulatedHybridFileSystem(const std::shared_ptr<FileSystem>& base,
- const std::string& metadata_file_name,
- int throughput_multiplier, bool is_full_fs_warm);
- ~SimulatedHybridFileSystem() override;
- public:
- IOStatus NewRandomAccessFile(const std::string& fname,
- const FileOptions& file_opts,
- std::unique_ptr<FSRandomAccessFile>* result,
- IODebugContext* dbg) override;
- IOStatus NewWritableFile(const std::string& fname,
- const FileOptions& file_opts,
- std::unique_ptr<FSWritableFile>* result,
- IODebugContext* dbg) override;
- IOStatus DeleteFile(const std::string& fname, const IOOptions& options,
- IODebugContext* dbg) override;
- const char* Name() const override { return name_.c_str(); }
- private:
- // Limit 100 requests per second. Rate limiter is designed to byte but
- // we use it as fixed bytes is one request.
- std::shared_ptr<RateLimiter> rate_limiter_;
- std::mutex mutex_;
- std::unordered_set<std::string> warm_file_set_;
- std::string metadata_file_name_;
- std::string name_;
- bool is_full_fs_warm_;
- };
- // Simulated random access file that can control IOPs and latency to simulate
- // specific storage media
- class SimulatedHybridRaf : public FSRandomAccessFileOwnerWrapper {
- public:
- SimulatedHybridRaf(std::unique_ptr<FSRandomAccessFile>&& t,
- std::shared_ptr<RateLimiter> rate_limiter,
- Temperature temperature)
- : FSRandomAccessFileOwnerWrapper(std::move(t)),
- rate_limiter_(rate_limiter),
- temperature_(temperature) {}
- ~SimulatedHybridRaf() override {}
- IOStatus Read(uint64_t offset, size_t n, const IOOptions& options,
- Slice* result, char* scratch,
- IODebugContext* dbg) const override;
- IOStatus MultiRead(FSReadRequest* reqs, size_t num_reqs,
- const IOOptions& options, IODebugContext* dbg) override;
- IOStatus Prefetch(uint64_t offset, size_t n, const IOOptions& options,
- IODebugContext* dbg) override;
- private:
- std::shared_ptr<RateLimiter> rate_limiter_;
- Temperature temperature_;
- void SimulateIOWait(int64_t num_requests) const;
- };
- class SimulatedWritableFile : public FSWritableFileWrapper {
- public:
- SimulatedWritableFile(std::unique_ptr<FSWritableFile>&& t,
- std::shared_ptr<RateLimiter> rate_limiter)
- : FSWritableFileWrapper(t.get()),
- file_guard_(std::move(t)),
- rate_limiter_(rate_limiter) {}
- IOStatus Append(const Slice& data, const IOOptions&,
- IODebugContext*) override;
- IOStatus Append(const Slice& data, const IOOptions& options,
- const DataVerificationInfo& verification_info,
- IODebugContext* dbg) override;
- IOStatus Sync(const IOOptions& options, IODebugContext* dbg) override;
- IOStatus PositionedAppend(const Slice& data, uint64_t offset,
- const IOOptions& options,
- IODebugContext* dbg) override;
- IOStatus PositionedAppend(const Slice& data, uint64_t offset,
- const IOOptions& options,
- const DataVerificationInfo& verification_info,
- IODebugContext* dbg) override;
- private:
- std::unique_ptr<FSWritableFile> file_guard_;
- std::shared_ptr<RateLimiter> rate_limiter_;
- size_t unsynced_bytes = 0;
- void SimulateIOWait(int64_t num_requests) const;
- };
- } // namespace ROCKSDB_NAMESPACE
|