Coverage Report

Created: 2026-08-28 18:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/cloud/cloud_ms_rpc_rate_limiters.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <bvar/bvar.h>
21
22
#include <array>
23
#include <atomic>
24
#include <memory>
25
#include <string>
26
#include <string_view>
27
28
#include "common/atomic_shared_ptr.h"
29
#include "cpp/token_bucket_rate_limiter.h"
30
31
namespace doris::cloud {
32
33
// Macro to define all Meta Service RPC types
34
// Usage: META_SERVICE_RPC_TYPES(X) where X(enum_name, config_suffix, display_name)
35
// - enum_name: the enum value name (e.g., GET_TABLET_META)
36
// - config_suffix: suffix for the config name (e.g., get_tablet_meta -> ms_rpc_qps_get_tablet_meta)
37
// - display_name: the human-readable name for bvar metrics (e.g., "get tablet meta")
38
#define META_SERVICE_RPC_TYPES(X)                                         \
39
73
    X(GET_TABLET_META, get_tablet_meta, "get tablet meta")                \
40
73
    X(GET_ROWSET, get_rowset, "get rowset")                               \
41
73
    X(PREPARE_ROWSET, prepare_rowset, "prepare rowset")                   \
42
73
    X(COMMIT_ROWSET, commit_rowset, "commit rowset")                      \
43
73
    X(UPDATE_TMP_ROWSET, update_tmp_rowset, "update tmp rowset")          \
44
73
    X(COMMIT_TXN, commit_txn, "commit txn")                               \
45
73
    X(ABORT_TXN, abort_txn, "abort txn")                                  \
46
73
    X(PRECOMMIT_TXN, precommit_txn, "precommit txn")                      \
47
73
    X(GET_OBJ_STORE_INFO, get_obj_store_info, "get obj store info")       \
48
73
    X(START_TABLET_JOB, start_tablet_job, "start tablet job")             \
49
73
    X(FINISH_TABLET_JOB, finish_tablet_job, "finish tablet job")          \
50
73
    X(GET_DELETE_BITMAP, get_delete_bitmap, "get delete bitmap")          \
51
73
    X(UPDATE_DELETE_BITMAP, update_delete_bitmap, "update delete bitmap") \
52
73
    X(GET_DELETE_BITMAP_UPDATE_LOCK, get_delete_bitmap_update_lock,       \
53
69
      "get delete bitmap update lock")                                    \
54
73
    X(REMOVE_DELETE_BITMAP_UPDATE_LOCK, remove_delete_bitmap_update_lock, \
55
69
      "remove delete bitmap update lock")                                 \
56
73
    X(GET_INSTANCE, get_instance, "get instance")                         \
57
73
    X(PREPARE_RESTORE_JOB, prepare_restore_job, "prepare restore job")    \
58
73
    X(COMMIT_RESTORE_JOB, commit_restore_job, "commit restore job")       \
59
73
    X(FINISH_RESTORE_JOB, finish_restore_job, "finish restore job")       \
60
73
    X(LIST_SNAPSHOTS, list_snapshots, "list snapshots")                   \
61
73
    X(GET_CLUSTER_STATUS, get_cluster_status, "get cluster status")       \
62
73
    X(UPDATE_PACKED_FILE_INFO, update_packed_file_info, "update packed file info")
63
64
// Enum class for Meta Service RPC types
65
enum class MetaServiceRPC : size_t {
66
#define DEFINE_ENUM(enum_name, config_suffix, display_name) enum_name,
67
    META_SERVICE_RPC_TYPES(DEFINE_ENUM)
68
#undef DEFINE_ENUM
69
            COUNT // Total number of RPC types
70
};
71
72
// Get the display name for a MetaServiceRPC enum value
73
std::string_view meta_service_rpc_display_name(MetaServiceRPC rpc);
74
75
// Rate limiter with associated metrics for a single RPC method
76
struct RpcRateLimiter {
77
    std::unique_ptr<TokenBucketRateLimiterHolder> limiter;
78
    std::unique_ptr<bvar::LatencyRecorder> latency_recorder;
79
80
    RpcRateLimiter(int qps, std::string_view op_name);
81
82
    // Each RPC type owns one RpcRateLimiter, so log suppression is independent per RPC type.
83
    bool should_log(int64_t now_us);
84
85
    // Reset the rate limiter with new QPS
86
    void reset(int qps);
87
88
private:
89
    std::atomic<int64_t> _next_log_time_us {0};
90
};
91
92
// Host-level rate limiters for MS RPCs to prevent burst traffic
93
// Each RPC method has its own rate limiter and bvar metrics
94
// Uses enum class MetaServiceRPC as key for O(1) lookup
95
class HostLevelMSRpcRateLimiters {
96
public:
97
    // Constructor initializes rate limiters for all RPC types from config
98
    HostLevelMSRpcRateLimiters();
99
100
    // Constructor for testing: initializes all rate limiters with uniform QPS
101
    // This allows unit tests to be independent of config values
102
    explicit HostLevelMSRpcRateLimiters(int uniform_qps);
103
104
76
    ~HostLevelMSRpcRateLimiters() = default;
105
106
    // Rate limit the specified RPC method, returning the actual sleep time in nanoseconds.
107
    // Dry-run mode updates the limiter and its metrics without sleeping, and returns 0.
108
    // Thread-safe: each limiter handles its own synchronization
109
    int64_t limit(MetaServiceRPC rpc);
110
111
    // Reset a specific rate limiter with new QPS
112
    void reset(MetaServiceRPC rpc, int qps);
113
114
    // Reset all rate limiters (re-reads QPS from config)
115
    void reset_all();
116
117
private:
118
    void init_from_config();
119
    void init_with_uniform_qps(int qps);
120
121
    // Use atomic_shared_ptr for thread-safe access during concurrent limit() and reset() calls
122
    std::array<doris::atomic_shared_ptr<RpcRateLimiter>, static_cast<size_t>(MetaServiceRPC::COUNT)>
123
            _limiters;
124
};
125
126
} // namespace doris::cloud