mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-11 23:56:53 +00:00
perf(filemeta): phase-1~3 rename_data metadata optimization (#3011)
* chore(perf): harden amd64 profiling benchmark flow * fix(profiling): isolate bench buckets and map protobuf conflict * perf: avoid blocking owned local writes * style: format profile admin handler * docs: clarify observability trace validation * perf: reduce mkdir overhead on local writes * perf: add rename_data meta microbenchmark * perf(filemeta): fast-path data_dir decode in version meta * perf(filemeta): collapse data-dir lookup into one scan * perf(filemeta): reduce scan allocs and refresh meta bench * perf(ecstore): skip mkdir path on read-only open * perf(filemeta): single-pass unshared data-dir scan * perf(filemeta): add two-key inline remove fast path * perf(filemeta): compare remove-two keys by bytes first * bench(ecstore): add remove_two-only micro benchmark * bench(ecstore): stabilize rename_data meta benchmark timing * bench(ecstore): align rename_data path with remove_two * perf(filemeta): avoid uuid string alloc in remove_two * perf(filemeta): add fast-path for empty inline data * perf(filemeta): streamline add_version match branch * perf(filemeta): fast-return remove_key on miss * perf(filemeta): speed up add_version insertion lookup * style(ecstore): normalize formatting in perf-tuning files * refactor(filemeta): unify inline data removal paths
This commit is contained in:
@@ -54,6 +54,17 @@ pub fn register_profiling_route(r: &mut S3Router<AdminOperation>) -> std::io::Re
|
||||
|
||||
pub struct ProfileHandler {}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn map_cpu_profile_collect_error_message(err: &str) -> (StatusCode, String) {
|
||||
if err.contains("start running cpu profiler error") {
|
||||
return (
|
||||
StatusCode::CONFLICT,
|
||||
"CPU profiler is already running. Disable RUSTFS_OBS_PROFILING_EXPORT_ENABLED or retry later.".to_string(),
|
||||
);
|
||||
}
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, format!("Failed to collect CPU profile: {err}"))
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Operation for ProfileHandler {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
@@ -95,15 +106,19 @@ impl Operation for ProfileHandler {
|
||||
headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/octet-stream"));
|
||||
Ok(S3Response::with_headers((StatusCode::OK, Body::from(bytes)), headers))
|
||||
}
|
||||
Err(e) => Ok(S3Response::new((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Body::from(format!("Failed to read profile file: {e}")),
|
||||
))),
|
||||
Err(e) => {
|
||||
error!("Failed to read profile file {}: {}", path.display(), e);
|
||||
Ok(S3Response::new((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Body::from(format!("Failed to read profile file: {e}")),
|
||||
)))
|
||||
}
|
||||
},
|
||||
Err(e) => Ok(S3Response::new((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Body::from(format!("Failed to collect CPU profile: {e}")),
|
||||
))),
|
||||
Err(e) => {
|
||||
let (status, message) = map_cpu_profile_collect_error_message(&e);
|
||||
error!("CPU protobuf profile collection failed: {}", e);
|
||||
Ok(S3Response::new((status, Body::from(message))))
|
||||
}
|
||||
},
|
||||
"flamegraph" | "svg" => {
|
||||
let freq = get_env_usize(ENV_CPU_FREQ, DEFAULT_CPU_FREQ) as i32;
|
||||
@@ -213,6 +228,7 @@ mod tests {
|
||||
use crate::admin::router::Operation;
|
||||
use http::{Extensions, HeaderMap, Uri};
|
||||
use hyper::Method;
|
||||
use hyper::StatusCode;
|
||||
use matchit::Params;
|
||||
use s3s::{Body, S3ErrorCode, S3Request};
|
||||
|
||||
@@ -268,4 +284,12 @@ mod tests {
|
||||
assert_eq!(err.code(), &S3ErrorCode::AccessDenied);
|
||||
assert_eq!(err.message(), Some("Signature is required"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cpu_profile_collect_error_maps_profiler_conflict_to_409() {
|
||||
let (status, message) =
|
||||
super::map_cpu_profile_collect_error_message("create profiler failed: start running cpu profiler error");
|
||||
assert_eq!(status, StatusCode::CONFLICT);
|
||||
assert!(message.contains("CPU profiler is already running"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +196,10 @@ pub struct ServerOpts {
|
||||
)]
|
||||
pub console_address: String,
|
||||
|
||||
/// Observability endpoint for trace, metrics and logs,only support grpc mode.
|
||||
/// Root OTLP endpoint for traces, metrics, and logs.
|
||||
/// For the current observability pipeline this should be an OTLP/HTTP base
|
||||
/// URL such as `http://otel-collector:4318` or
|
||||
/// `http://host.docker.internal:4318`.
|
||||
#[arg(
|
||||
long,
|
||||
default_value_t = rustfs_config::DEFAULT_OBS_ENDPOINT.to_string(),
|
||||
|
||||
Reference in New Issue
Block a user