mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-26 05:56:50 +00:00
fix(ecstore): reduce GET reader setup shard fanout (#4735)
This commit is contained in:
@@ -35,7 +35,9 @@ use crate::disk::{
|
|||||||
use crate::erasure::coding::{self, bitrot_verify};
|
use crate::erasure::coding::{self, bitrot_verify};
|
||||||
use crate::runtime::sources as runtime_sources;
|
use crate::runtime::sources as runtime_sources;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use metrics::{counter, gauge};
|
use metrics::counter;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use metrics::gauge;
|
||||||
use parking_lot::{Mutex as ParkingLotMutex, RwLock as ParkingLotRwLock};
|
use parking_lot::{Mutex as ParkingLotMutex, RwLock as ParkingLotRwLock};
|
||||||
use rustfs_filemeta::{
|
use rustfs_filemeta::{
|
||||||
Cache, FileInfo, FileInfoOpts, FileMeta, MetaCacheEntry, MetacacheWriter, ObjectPartInfo, Opts, RawFileInfo, UpdateFn,
|
Cache, FileInfo, FileInfoOpts, FileMeta, MetaCacheEntry, MetacacheWriter, ObjectPartInfo, Opts, RawFileInfo, UpdateFn,
|
||||||
|
|||||||
@@ -205,11 +205,11 @@ async fn blackbox_get_restores_body_and_enqueues_repair_after_one_corrupt_shard(
|
|||||||
let mut heal_rx = rustfs_common::heal_channel::init_heal_channel()
|
let mut heal_rx = rustfs_common::heal_channel::init_heal_channel()
|
||||||
.expect("this must be the only ecstore test that owns the heal channel receiver");
|
.expect("this must be the only ecstore test that owns the heal channel receiver");
|
||||||
|
|
||||||
// Force the data-blocks-first reader setup (see
|
// Keep data-blocks-first reader setup explicit for this deterministic
|
||||||
// ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP in set_disk/core/io_primitives.rs):
|
// repair assertion (see ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP in
|
||||||
// under the default all-shards strategy the corrupt shard's failed open can
|
// set_disk/core/io_primitives.rs): if a caller opts back into all-shards,
|
||||||
// lose the setup-quorum race, in which case no repair is submitted and the
|
// the corrupt shard's failed open can lose the setup-quorum race, making
|
||||||
// enqueue assertion below would be a coin flip.
|
// the enqueue assertion below a coin flip.
|
||||||
temp_env::async_with_vars([("RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP", Some("true"))], async {
|
temp_env::async_with_vars([("RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP", Some("true"))], async {
|
||||||
let (_dirs, set_disks) = make_local_set_disks(4, 2).await;
|
let (_dirs, set_disks) = make_local_set_disks(4, 2).await;
|
||||||
let bucket = "bb-corrupt-shard-repair";
|
let bucket = "bb-corrupt-shard-repair";
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ use tokio::task::JoinSet;
|
|||||||
|
|
||||||
pub(in crate::set_disk) const EVENT_SET_DISK_READ: &str = "set_disk_read";
|
pub(in crate::set_disk) const EVENT_SET_DISK_READ: &str = "set_disk_read";
|
||||||
pub(in crate::set_disk) const ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP: &str = "RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP";
|
pub(in crate::set_disk) const ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP: &str = "RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP";
|
||||||
|
const DEFAULT_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP: bool = true;
|
||||||
pub(in crate::set_disk) const ENV_RUSTFS_GET_CODEC_STREAMING_DATA_BLOCKS_FIRST_READER_SETUP: &str =
|
pub(in crate::set_disk) const ENV_RUSTFS_GET_CODEC_STREAMING_DATA_BLOCKS_FIRST_READER_SETUP: &str =
|
||||||
"RUSTFS_GET_CODEC_STREAMING_DATA_BLOCKS_FIRST_READER_SETUP";
|
"RUSTFS_GET_CODEC_STREAMING_DATA_BLOCKS_FIRST_READER_SETUP";
|
||||||
pub(in crate::set_disk) const SLOW_OBJECT_READ_LOG_THRESHOLD: Duration = Duration::from_secs(5);
|
pub(in crate::set_disk) const SLOW_OBJECT_READ_LOG_THRESHOLD: Duration = Duration::from_secs(5);
|
||||||
@@ -990,7 +991,11 @@ pub(in crate::set_disk) fn get_bitrot_reader_setup_strategy(
|
|||||||
) -> BitrotReaderSetupStrategy {
|
) -> BitrotReaderSetupStrategy {
|
||||||
match mode {
|
match mode {
|
||||||
BitrotReaderSetupMode::ReadQuorum
|
BitrotReaderSetupMode::ReadQuorum
|
||||||
if prefer_data_blocks_first || rustfs_utils::get_env_bool(ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, false) =>
|
if prefer_data_blocks_first
|
||||||
|
|| rustfs_utils::get_env_bool(
|
||||||
|
ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP,
|
||||||
|
DEFAULT_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP,
|
||||||
|
) =>
|
||||||
{
|
{
|
||||||
BitrotReaderSetupStrategy::DataBlocksFirst
|
BitrotReaderSetupStrategy::DataBlocksFirst
|
||||||
}
|
}
|
||||||
@@ -4200,6 +4205,18 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[serial_test::serial]
|
#[serial_test::serial]
|
||||||
fn bitrot_reader_setup_tracks_strategy_counters_and_deferred_readers() {
|
fn bitrot_reader_setup_tracks_strategy_counters_and_deferred_readers() {
|
||||||
|
temp_env::with_var(ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, None::<&str>, || {
|
||||||
|
assert!(matches!(
|
||||||
|
get_bitrot_reader_setup_strategy(BitrotReaderSetupMode::ReadQuorum, false),
|
||||||
|
BitrotReaderSetupStrategy::DataBlocksFirst
|
||||||
|
));
|
||||||
|
});
|
||||||
|
temp_env::with_var(ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, Some("false"), || {
|
||||||
|
assert!(matches!(
|
||||||
|
get_bitrot_reader_setup_strategy(BitrotReaderSetupMode::ReadQuorum, false),
|
||||||
|
BitrotReaderSetupStrategy::AllShards
|
||||||
|
));
|
||||||
|
});
|
||||||
temp_env::with_var(ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, Some("true"), || {
|
temp_env::with_var(ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, Some("true"), || {
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
get_bitrot_reader_setup_strategy(BitrotReaderSetupMode::ReadQuorum, false),
|
get_bitrot_reader_setup_strategy(BitrotReaderSetupMode::ReadQuorum, false),
|
||||||
|
|||||||
@@ -3771,7 +3771,10 @@ mod tests {
|
|||||||
|
|
||||||
temp_env::async_with_vars(
|
temp_env::async_with_vars(
|
||||||
[
|
[
|
||||||
(ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, data_blocks_first.then_some("true")),
|
(
|
||||||
|
ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP,
|
||||||
|
Some(if data_blocks_first { "true" } else { "false" }),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
ENV_RUSTFS_GET_CODEC_STREAMING_DATA_BLOCKS_FIRST_READER_SETUP,
|
ENV_RUSTFS_GET_CODEC_STREAMING_DATA_BLOCKS_FIRST_READER_SETUP,
|
||||||
codec_data_blocks_first.then_some("true"),
|
codec_data_blocks_first.then_some("true"),
|
||||||
|
|||||||
Reference in New Issue
Block a user