userver: userver/storages/redis/component.hpp Source File
Loading...
Searching...
No Matches
component.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/redis/component.hpp
4/// @brief @copybrief components::Redis
5
6#include <memory>
7#include <string>
8#include <unordered_map>
9
10#include <userver/components/component_base.hpp>
11#include <userver/components/component_fwd.hpp>
12#include <userver/dynamic_config/source.hpp>
13#include <userver/rcu/rcu.hpp>
14#include <userver/storages/redis/base.hpp>
15#include <userver/storages/redis/fwd.hpp>
16#include <userver/storages/redis/wait_connected_mode.hpp>
17#include <userver/storages/secdist/secdist.hpp>
18#include <userver/testsuite/redis_control.hpp>
19#include <userver/utils/statistics/entry.hpp>
20
21USERVER_NAMESPACE_BEGIN
22
23/// Components, clients and helpers for different databases and storages
24namespace storages {}
25
26/// Valkey and Redis client and helpers
27namespace storages::redis {
28
29class SubscribeClientImpl;
30
31namespace impl {
32class Sentinel;
33class ThreadPools;
34} // namespace impl
35} // namespace storages::redis
36
37namespace components {
38
39/// @ingroup userver_components
40///
41/// @brief Valkey and Redis client component
42///
43/// Provides access to a valkey or redis cluster.
44///
45/// ## Dynamic options:
46/// * @ref REDIS_COMMANDS_BUFFERING_SETTINGS
47/// * @ref REDIS_DEFAULT_COMMAND_CONTROL
48/// * @ref REDIS_METRICS_SETTINGS
49/// * @ref REDIS_PUBSUB_METRICS_SETTINGS
50/// * @ref REDIS_RETRY_BUDGET_SETTINGS
51/// * @ref REDIS_REPLICA_MONITORING_SETTINGS
52/// * @ref REDIS_SUBSCRIBER_DEFAULT_COMMAND_CONTROL
53/// * @ref REDIS_SUBSCRIPTIONS_REBALANCE_MIN_INTERVAL_SECONDS
54/// * @ref REDIS_WAIT_CONNECTED
55///
56/// ## Static options of components::Redis :
57/// @include{doc} scripts/docs/en/components_schema/redis/src/storages/redis/component.md
58///
59/// Options inherited from @ref components::ComponentBase :
60/// @include{doc} scripts/docs/en/components_schema/core/src/components/impl/component_base.md
61///
62/// ## Static configuration example:
63///
64/// ```
65/// # yaml
66/// redis:
67/// groups:
68/// - config_name: cats
69/// db: hello_service_cats_catalogue
70/// sharding_strategy: RedisCluster
71/// - config_name: dogs
72/// db: hello_service_dogs_catalogue
73/// subscribe_groups:
74/// - config_name: food
75/// db: hello_service_pet_food_orders
76/// thread_pools:
77/// redis_thread_pool_size: 8
78/// sentinel_thread_pool_size: 1
79/// ```
80///
81/// ## Secdist format
82///
83/// If a `config_name` option is provided, for example
84/// `groups.some.config_name: some_name_of_your_database`, then the Secdist
85/// entry for that alias should look like following:
86/// @code{.json}
87/// {
88/// "redis_settings": {
89/// "some_name_of_your_database": {
90/// "password": "the_password_of_your_database",
91/// "sentinel_password": "the_password_for_sentinels_if_any",
92/// "secure_connection": false,
93/// "sentinels": [
94/// {"host": "the_host1_of_your_database", "port": 11564}
95/// ],
96/// "shards": [
97/// {"name": "test_master0"}
98/// ]
99/// }
100/// }
101/// }
102/// @endcode
103///
104/// For an example of Secdist setup for standalone, sentinel and cluster testsuite configurations see the snippet:
105///
106/// @snippet redis/functional_tests/integration_tests/tests/conftest.py Sample pytest redis configuration
107///
108/// Note that if the components::Secdist component has `update-period` other
109/// than 0, then new connections are created or gracefully closed as the secdist configuration change to new value.
110///
111/// ## Cluster Valkey or Cluster Redis setup
112///
113/// Valkey/Redis cluster is the new recommended way of setting up key-value datastores with improved stability.
114///
115/// To start, set `sharding_strategy: RedisCluster` in the static config
116/// as shown above.
117///
118/// Secdist configuration is simplified:
119///
120/// 1. `"shards"` field is ignored, you can specify an empty array there;
121/// 2. `"sentinels"` field should contain some of the cluster nodes. They are
122/// only used for topology discovery; it is not necessary to list all nodes.
123class Redis : public ComponentBase {
124public:
125 Redis(const ComponentConfig& config, const ComponentContext& component_context);
126
127 ~Redis() override;
128
129 /// @ingroup userver_component_names
130 /// @brief The default name of components::Redis
131 static constexpr std::string_view kName = "redis";
132
133 std::shared_ptr<storages::redis::Client> GetClient(
134 const std::string& name,
135 storages::redis::RedisWaitConnected wait_connected = {}
136 ) const;
137 [[deprecated("use GetClient()")]] std::shared_ptr<storages::redis::impl::Sentinel> Client(const std::string& name
138 ) const;
139 std::shared_ptr<storages::redis::SubscribeClient> GetSubscribeClient(
140 const std::string& name,
141 storages::redis::RedisWaitConnected wait_connected = {}
142 ) const;
143
144 static yaml_config::Schema GetStaticConfigSchema();
145
146private:
147 void OnConfigUpdate(const dynamic_config::Snapshot& cfg);
148 void OnSecdistUpdate(const storages::secdist::SecdistConfig& cfg);
149
150 void Connect(
151 const ComponentConfig& config,
152 const ComponentContext& component_context,
153 const testsuite::RedisControl& testsuite_redis_control
154 );
155
156 void WriteStatistics(utils::statistics::Writer& writer);
157 void WriteStatisticsPubsub(utils::statistics::Writer& writer);
158
159 std::shared_ptr<storages::redis::impl::ThreadPools> thread_pools_;
160 std::unordered_map<std::string, std::shared_ptr<storages::redis::impl::Sentinel>> sentinels_;
161 std::unordered_map<std::string, std::shared_ptr<storages::redis::Client>> clients_;
162 std::unordered_map<std::string, std::shared_ptr<storages::redis::SubscribeClientImpl>> subscribe_clients_;
163
164 dynamic_config::Source config_;
165 concurrent::AsyncEventSubscriberScope config_subscription_;
166 concurrent::AsyncEventSubscriberScope secdist_subscription_;
167
168 utils::statistics::Entry statistics_holder_;
169 utils::statistics::Entry subscribe_statistics_holder_;
170
171 storages::redis::MetricsSettings::StaticSettings static_metrics_settings_;
172 rcu::Variable<storages::redis::MetricsSettings> metrics_settings_;
173 rcu::Variable<storages::redis::PubsubMetricsSettings> pubsub_metrics_settings_;
174};
175
176template <>
177inline constexpr bool kHasValidate<Redis> = true;
178
179} // namespace components
180
181USERVER_NAMESPACE_END