Skip to content

Commit

Permalink
ref(redis): Configure min_idle for the Redis pool
Browse files Browse the repository at this point in the history
  • Loading branch information
Dav1dde committed Jul 25, 2024
1 parent 5f46bf7 commit 6cb93f3
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 5 deletions.
18 changes: 13 additions & 5 deletions relay-config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2285,12 +2285,20 @@ impl Config {

let redis = self.values.processing.redis.as_ref()?;

let max_connections = redis
.options
.max_connections
.unwrap_or(cpu_concurrency as u32 * 2)
.max(crate::redis::DEFAULT_MIN_MAX_CONNECTIONS);

let min_idle = redis
.options
.min_idle
.unwrap_or_else(|| max_connections.div_ceil(crate::redis::DEFAULT_MIN_IDLE_RATIO));

let options = RedisConfigOptions {
max_connections: redis
.options
.max_connections
.unwrap_or(cpu_concurrency as u32 * 2)
.min(crate::redis::DEFAULT_MIN_MAX_CONNECTIONS),
max_connections,
min_idle: Some(min_idle),
connection_timeout: redis.options.connection_timeout,
max_lifetime: redis.options.max_lifetime,
idle_timeout: redis.options.idle_timeout,
Expand Down
13 changes: 13 additions & 0 deletions relay-config/src/redis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ use serde::{Deserialize, Serialize};
/// In this case, we fall back to the old default.
pub(crate) const DEFAULT_MIN_MAX_CONNECTIONS: u32 = 24;

/// By default the `min_idle` count of the Redis pool is set to the calculated
/// amount of max connections divided by this value and rounded up.
///
/// To express this value as a percentage of max connections,
/// use this formula: `100 / DEFAULT_MIN_IDLE_RATIO`.
pub(crate) const DEFAULT_MIN_IDLE_RATIO: u32 = 5;

/// Additional configuration options for a redis client.
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
#[serde(default)]
Expand All @@ -13,6 +20,11 @@ pub struct PartialRedisConfigOptions {
/// Defaults to 2x `limits.max_thread_count` or a minimum of 24.
#[serde(skip_serializing_if = "Option::is_none")]
pub max_connections: Option<u32>,
/// Minimum amount of idle connections kept alive in the pool.
///
/// If not set it will default to 20% of [`Self::max_connections`].
#[serde(skip_serializing_if = "Option::is_none")]
pub min_idle: Option<u32>,
/// Sets the connection timeout used by the pool, in seconds.
///
/// Calls to `Pool::get` will wait this long for a connection to become available before returning an error.
Expand All @@ -31,6 +43,7 @@ impl Default for PartialRedisConfigOptions {
fn default() -> Self {
Self {
max_connections: None,
min_idle: None,
connection_timeout: 5,
max_lifetime: 300,
idle_timeout: 60,
Expand Down
5 changes: 5 additions & 0 deletions relay-redis/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ use serde::{Deserialize, Serialize};
pub struct RedisConfigOptions {
/// Maximum number of connections managed by the pool.
pub max_connections: u32,
/// Minimum amount of idle connections kept alive in the pool.
///
/// If not set it will default to [`Self::max_connections`].
pub min_idle: Option<u32>,
/// Sets the connection timeout used by the pool, in seconds.
///
/// Calls to `Pool::get` will wait this long for a connection to become available before returning an error.
Expand All @@ -23,6 +27,7 @@ impl Default for RedisConfigOptions {
fn default() -> Self {
Self {
max_connections: 24,
min_idle: None,
connection_timeout: 5,
max_lifetime: 300,
idle_timeout: 60,
Expand Down
2 changes: 2 additions & 0 deletions relay-redis/src/real.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ impl RedisPool {
) -> Result<Self, RedisError> {
let pool = Pool::builder()
.max_size(opts.max_connections)
.min_idle(opts.min_idle)
.test_on_check_out(false)
.max_lifetime(Some(Duration::from_secs(opts.max_lifetime)))
.idle_timeout(Some(Duration::from_secs(opts.idle_timeout)))
Expand All @@ -166,6 +167,7 @@ impl RedisPool {
pub fn single(server: &str, opts: RedisConfigOptions) -> Result<Self, RedisError> {
let pool = Pool::builder()
.max_size(opts.max_connections)
.min_idle(opts.min_idle)
.test_on_check_out(false)
.max_lifetime(Some(Duration::from_secs(opts.max_lifetime)))
.idle_timeout(Some(Duration::from_secs(opts.idle_timeout)))
Expand Down

0 comments on commit 6cb93f3

Please sign in to comment.