feat(tcp): optimize TCP socket configuration for 4M-64M data chunk transfers (#1384)
Signed-off-by: Gaius <gaius.qi@gmail.com>
This commit is contained in:
parent
e6a0b9372d
commit
163a57a0e3
|
|
@ -1018,7 +1018,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dragonfly-client"
|
name = "dragonfly-client"
|
||||||
version = "1.0.26"
|
version = "1.0.27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
|
@ -1094,7 +1094,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dragonfly-client-backend"
|
name = "dragonfly-client-backend"
|
||||||
version = "1.0.26"
|
version = "1.0.27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dragonfly-api",
|
"dragonfly-api",
|
||||||
"dragonfly-client-core",
|
"dragonfly-client-core",
|
||||||
|
|
@ -1125,7 +1125,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dragonfly-client-config"
|
name = "dragonfly-client-config"
|
||||||
version = "1.0.26"
|
version = "1.0.27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytesize",
|
"bytesize",
|
||||||
"bytesize-serde",
|
"bytesize-serde",
|
||||||
|
|
@ -1155,7 +1155,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dragonfly-client-core"
|
name = "dragonfly-client-core"
|
||||||
version = "1.0.26"
|
version = "1.0.27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"headers 0.4.1",
|
"headers 0.4.1",
|
||||||
"hyper 1.6.0",
|
"hyper 1.6.0",
|
||||||
|
|
@ -1175,7 +1175,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dragonfly-client-init"
|
name = "dragonfly-client-init"
|
||||||
version = "1.0.26"
|
version = "1.0.27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
|
|
@ -1192,7 +1192,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dragonfly-client-metric"
|
name = "dragonfly-client-metric"
|
||||||
version = "1.0.26"
|
version = "1.0.27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dragonfly-api",
|
"dragonfly-api",
|
||||||
"dragonfly-client-config",
|
"dragonfly-client-config",
|
||||||
|
|
@ -1207,7 +1207,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dragonfly-client-storage"
|
name = "dragonfly-client-storage"
|
||||||
version = "1.0.26"
|
version = "1.0.27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
|
@ -1222,6 +1222,7 @@ dependencies = [
|
||||||
"dragonfly-client-util",
|
"dragonfly-client-util",
|
||||||
"fs2",
|
"fs2",
|
||||||
"leaky-bucket",
|
"leaky-bucket",
|
||||||
|
"nix 0.30.1",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"prost-wkt-types",
|
"prost-wkt-types",
|
||||||
"quinn",
|
"quinn",
|
||||||
|
|
@ -1241,7 +1242,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dragonfly-client-util"
|
name = "dragonfly-client-util"
|
||||||
version = "1.0.26"
|
version = "1.0.27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
|
@ -1680,7 +1681,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hdfs"
|
name = "hdfs"
|
||||||
version = "1.0.26"
|
version = "1.0.27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dragonfly-client-backend",
|
"dragonfly-client-backend",
|
||||||
"dragonfly-client-core",
|
"dragonfly-client-core",
|
||||||
|
|
@ -2685,6 +2686,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
|
|
@ -2830,6 +2840,19 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.30.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.4",
|
||||||
|
"cfg-if",
|
||||||
|
"cfg_aliases",
|
||||||
|
"libc",
|
||||||
|
"memoffset",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "no-std-net"
|
name = "no-std-net"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
|
|
@ -3545,7 +3568,7 @@ dependencies = [
|
||||||
"inferno",
|
"inferno",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"nix",
|
"nix 0.26.4",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"protobuf 3.7.2",
|
"protobuf 3.7.2",
|
||||||
"protobuf-codegen",
|
"protobuf-codegen",
|
||||||
|
|
|
||||||
18
Cargo.toml
18
Cargo.toml
|
|
@ -13,7 +13,7 @@ members = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "1.0.26"
|
version = "1.0.27"
|
||||||
authors = ["The Dragonfly Developers"]
|
authors = ["The Dragonfly Developers"]
|
||||||
homepage = "https://d7y.io/"
|
homepage = "https://d7y.io/"
|
||||||
repository = "https://github.com/dragonflyoss/client.git"
|
repository = "https://github.com/dragonflyoss/client.git"
|
||||||
|
|
@ -23,14 +23,14 @@ readme = "README.md"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
dragonfly-client = { path = "dragonfly-client", version = "1.0.26" }
|
dragonfly-client = { path = "dragonfly-client", version = "1.0.27" }
|
||||||
dragonfly-client-core = { path = "dragonfly-client-core", version = "1.0.26" }
|
dragonfly-client-core = { path = "dragonfly-client-core", version = "1.0.27" }
|
||||||
dragonfly-client-config = { path = "dragonfly-client-config", version = "1.0.26" }
|
dragonfly-client-config = { path = "dragonfly-client-config", version = "1.0.27" }
|
||||||
dragonfly-client-storage = { path = "dragonfly-client-storage", version = "1.0.26" }
|
dragonfly-client-storage = { path = "dragonfly-client-storage", version = "1.0.27" }
|
||||||
dragonfly-client-backend = { path = "dragonfly-client-backend", version = "1.0.26" }
|
dragonfly-client-backend = { path = "dragonfly-client-backend", version = "1.0.27" }
|
||||||
dragonfly-client-metric = { path = "dragonfly-client-metric", version = "1.0.26" }
|
dragonfly-client-metric = { path = "dragonfly-client-metric", version = "1.0.27" }
|
||||||
dragonfly-client-util = { path = "dragonfly-client-util", version = "1.0.26" }
|
dragonfly-client-util = { path = "dragonfly-client-util", version = "1.0.27" }
|
||||||
dragonfly-client-init = { path = "dragonfly-client-init", version = "1.0.26" }
|
dragonfly-client-init = { path = "dragonfly-client-init", version = "1.0.27" }
|
||||||
dragonfly-api = "=2.1.70"
|
dragonfly-api = "=2.1.70"
|
||||||
thiserror = "2.0"
|
thiserror = "2.0"
|
||||||
futures = "0.3.31"
|
futures = "0.3.31"
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,13 @@ impl HTTP {
|
||||||
.use_preconfigured_tls(client_config_builder)
|
.use_preconfigured_tls(client_config_builder)
|
||||||
.pool_max_idle_per_host(super::POOL_MAX_IDLE_PER_HOST)
|
.pool_max_idle_per_host(super::POOL_MAX_IDLE_PER_HOST)
|
||||||
.tcp_keepalive(super::KEEP_ALIVE_INTERVAL)
|
.tcp_keepalive(super::KEEP_ALIVE_INTERVAL)
|
||||||
|
.tcp_nodelay(true)
|
||||||
|
.http2_adaptive_window(true)
|
||||||
|
.http2_initial_stream_window_size(Some(super::HTTP2_STREAM_WINDOW_SIZE))
|
||||||
|
.http2_initial_connection_window_size(Some(super::HTTP2_CONNECTION_WINDOW_SIZE))
|
||||||
|
.http2_keep_alive_timeout(super::HTTP2_KEEP_ALIVE_TIMEOUT)
|
||||||
|
.http2_keep_alive_interval(super::HTTP2_KEEP_ALIVE_INTERVAL)
|
||||||
|
.http2_keep_alive_while_idle(true)
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
let retry_policy =
|
let retry_policy =
|
||||||
|
|
@ -118,6 +125,13 @@ impl HTTP {
|
||||||
.no_deflate()
|
.no_deflate()
|
||||||
.hickory_dns(true)
|
.hickory_dns(true)
|
||||||
.use_preconfigured_tls(client_config_builder)
|
.use_preconfigured_tls(client_config_builder)
|
||||||
|
.tcp_nodelay(true)
|
||||||
|
.http2_adaptive_window(true)
|
||||||
|
.http2_initial_stream_window_size(Some(super::HTTP2_STREAM_WINDOW_SIZE))
|
||||||
|
.http2_initial_connection_window_size(Some(super::HTTP2_CONNECTION_WINDOW_SIZE))
|
||||||
|
.http2_keep_alive_timeout(super::HTTP2_KEEP_ALIVE_TIMEOUT)
|
||||||
|
.http2_keep_alive_interval(super::HTTP2_KEEP_ALIVE_INTERVAL)
|
||||||
|
.http2_keep_alive_while_idle(true)
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
let retry_policy =
|
let retry_policy =
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,12 @@ const HTTP2_KEEP_ALIVE_INTERVAL: Duration = Duration::from_secs(300);
|
||||||
/// HTTP2_KEEP_ALIVE_TIMEOUT is the timeout for HTTP2 keep alive.
|
/// HTTP2_KEEP_ALIVE_TIMEOUT is the timeout for HTTP2 keep alive.
|
||||||
const HTTP2_KEEP_ALIVE_TIMEOUT: Duration = Duration::from_secs(20);
|
const HTTP2_KEEP_ALIVE_TIMEOUT: Duration = Duration::from_secs(20);
|
||||||
|
|
||||||
|
/// HTTP2_STREAM_WINDOW_SIZE is the stream window size for HTTP2 connection.
|
||||||
|
const HTTP2_STREAM_WINDOW_SIZE: u32 = 16 * 1024 * 1024;
|
||||||
|
|
||||||
|
/// HTTP2_CONNECTION_WINDOW_SIZE is the connection window size for HTTP2 connection.
|
||||||
|
const HTTP2_CONNECTION_WINDOW_SIZE: u32 = 16 * 1024 * 1024;
|
||||||
|
|
||||||
/// MAX_RETRY_TIMES is the max retry times for the request.
|
/// MAX_RETRY_TIMES is the max retry times for the request.
|
||||||
const MAX_RETRY_TIMES: u32 = 1;
|
const MAX_RETRY_TIMES: u32 = 1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,10 @@ impl ObjectStorage {
|
||||||
.hickory_dns(true)
|
.hickory_dns(true)
|
||||||
.pool_max_idle_per_host(super::POOL_MAX_IDLE_PER_HOST)
|
.pool_max_idle_per_host(super::POOL_MAX_IDLE_PER_HOST)
|
||||||
.tcp_keepalive(super::KEEP_ALIVE_INTERVAL)
|
.tcp_keepalive(super::KEEP_ALIVE_INTERVAL)
|
||||||
|
.tcp_nodelay(true)
|
||||||
|
.http2_adaptive_window(true)
|
||||||
|
.http2_initial_stream_window_size(Some(super::HTTP2_STREAM_WINDOW_SIZE))
|
||||||
|
.http2_initial_connection_window_size(Some(super::HTTP2_CONNECTION_WINDOW_SIZE))
|
||||||
.http2_keep_alive_timeout(super::HTTP2_KEEP_ALIVE_TIMEOUT)
|
.http2_keep_alive_timeout(super::HTTP2_KEEP_ALIVE_TIMEOUT)
|
||||||
.http2_keep_alive_interval(super::HTTP2_KEEP_ALIVE_INTERVAL)
|
.http2_keep_alive_interval(super::HTTP2_KEEP_ALIVE_INTERVAL)
|
||||||
.http2_keep_alive_while_idle(true)
|
.http2_keep_alive_while_idle(true)
|
||||||
|
|
|
||||||
|
|
@ -1014,11 +1014,11 @@ pub struct Storage {
|
||||||
)]
|
)]
|
||||||
pub write_piece_timeout: Duration,
|
pub write_piece_timeout: Duration,
|
||||||
|
|
||||||
/// write_buffer_size is the buffer size for writing piece to disk, default is 128KB.
|
/// write_buffer_size is the buffer size for writing piece to disk, default is 4MiB.
|
||||||
#[serde(default = "default_storage_write_buffer_size")]
|
#[serde(default = "default_storage_write_buffer_size")]
|
||||||
pub write_buffer_size: usize,
|
pub write_buffer_size: usize,
|
||||||
|
|
||||||
/// read_buffer_size is the buffer size for reading piece from disk, default is 128KB.
|
/// read_buffer_size is the buffer size for reading piece from disk, default is 4MiB.
|
||||||
#[serde(default = "default_storage_read_buffer_size")]
|
#[serde(default = "default_storage_read_buffer_size")]
|
||||||
pub read_buffer_size: usize,
|
pub read_buffer_size: usize,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ bincode = "1.3.3"
|
||||||
walkdir = "2.5.0"
|
walkdir = "2.5.0"
|
||||||
quinn = "0.11.9"
|
quinn = "0.11.9"
|
||||||
socket2 = "0.6.0"
|
socket2 = "0.6.0"
|
||||||
|
nix = { version = "0.30.1", features = ["socket", "net"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile.workspace = true
|
tempfile.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@ pub mod tcp;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
/// DEFAULT_SEND_BUFFER_SIZE is the default size of the send buffer for network connections.
|
/// DEFAULT_SEND_BUFFER_SIZE is the default size of the send buffer for network connections.
|
||||||
const DEFAULT_SEND_BUFFER_SIZE: usize = 4 * 1024 * 1024;
|
const DEFAULT_SEND_BUFFER_SIZE: usize = 16 * 1024 * 1024;
|
||||||
|
|
||||||
/// DEFAULT_RECV_BUFFER_SIZE is the default size of the receive buffer for network connections.
|
/// DEFAULT_RECV_BUFFER_SIZE is the default size of the receive buffer for network connections.
|
||||||
const DEFAULT_RECV_BUFFER_SIZE: usize = 4 * 1024 * 1024;
|
const DEFAULT_RECV_BUFFER_SIZE: usize = 16 * 1024 * 1024;
|
||||||
|
|
||||||
/// DEFAULT_KEEPALIVE_INTERVAL is the default interval for sending keepalive messages.
|
/// DEFAULT_KEEPALIVE_INTERVAL is the default interval for sending keepalive messages.
|
||||||
const DEFAULT_KEEPALIVE_INTERVAL: Duration = Duration::from_secs(5);
|
const DEFAULT_KEEPALIVE_INTERVAL: Duration = Duration::from_secs(5);
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,18 @@ impl TCPClient {
|
||||||
socket.set_tcp_keepalive(
|
socket.set_tcp_keepalive(
|
||||||
&TcpKeepalive::new().with_interval(super::DEFAULT_KEEPALIVE_INTERVAL),
|
&TcpKeepalive::new().with_interval(super::DEFAULT_KEEPALIVE_INTERVAL),
|
||||||
)?;
|
)?;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
use nix::sys::socket::{setsockopt, sockopt::TcpFastOpenConnect};
|
||||||
|
use std::os::fd::AsFd;
|
||||||
|
use tracing::{info, warn};
|
||||||
|
|
||||||
|
if let Err(err) = setsockopt(&socket.as_fd(), TcpFastOpenConnect, &true) {
|
||||||
|
warn!("failed to set tcp fast open: {}", err);
|
||||||
|
} else {
|
||||||
|
info!("set tcp fast open to true");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let (reader, mut writer) = stream.into_split();
|
let (reader, mut writer) = stream.into_split();
|
||||||
writer.write_all(&request).await.inspect_err(|err| {
|
writer.write_all(&request).await.inspect_err(|err| {
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@ pub mod tcp;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
/// DEFAULT_SEND_BUFFER_SIZE is the default size of the send buffer for network connections.
|
/// DEFAULT_SEND_BUFFER_SIZE is the default size of the send buffer for network connections.
|
||||||
const DEFAULT_SEND_BUFFER_SIZE: usize = 4 * 1024 * 1024;
|
const DEFAULT_SEND_BUFFER_SIZE: usize = 16 * 1024 * 1024;
|
||||||
|
|
||||||
/// DEFAULT_RECV_BUFFER_SIZE is the default size of the receive buffer for network connections.
|
/// DEFAULT_RECV_BUFFER_SIZE is the default size of the receive buffer for network connections.
|
||||||
const DEFAULT_RECV_BUFFER_SIZE: usize = 4 * 1024 * 1024;
|
const DEFAULT_RECV_BUFFER_SIZE: usize = 16 * 1024 * 1024;
|
||||||
|
|
||||||
/// DEFAULT_KEEPALIVE_INTERVAL is the default interval for sending keepalive messages.
|
/// DEFAULT_KEEPALIVE_INTERVAL is the default interval for sending keepalive messages.
|
||||||
const DEFAULT_KEEPALIVE_INTERVAL: Duration = Duration::from_secs(5);
|
const DEFAULT_KEEPALIVE_INTERVAL: Duration = Duration::from_secs(5);
|
||||||
|
|
|
||||||
|
|
@ -99,11 +99,21 @@ impl TCPServer {
|
||||||
)?;
|
)?;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
use tracing::warn;
|
use nix::sys::socket::{setsockopt, sockopt::TcpFastOpenConnect};
|
||||||
if let Err(err) = socket.set_tcp_congestion("bbr".as_bytes()) {
|
use std::os::fd::AsFd;
|
||||||
|
use tracing::{info, warn};
|
||||||
|
|
||||||
|
if let Err(err) = socket.set_tcp_congestion("cubic".as_bytes()) {
|
||||||
warn!("failed to set tcp congestion: {}", err);
|
warn!("failed to set tcp congestion: {}", err);
|
||||||
|
} else {
|
||||||
|
info!("set tcp congestion to cubic");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(err) = setsockopt(&socket.as_fd(), TcpFastOpenConnect, &true) {
|
||||||
|
warn!("failed to set tcp fast open: {}", err);
|
||||||
|
} else {
|
||||||
|
info!("set tcp fast open to true");
|
||||||
}
|
}
|
||||||
info!("set tcp congestion to bbr");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.bind(&self.addr.into())?;
|
socket.bind(&self.addr.into())?;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue