/
teterkin
/
vm_load_testing
Обзор
Документация
Войти
/
teterkin
/
vm_load_testing
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/disk.rs
130 строк
4 KB
alexefan136
upload files
12 ноя 2025, 22:51
12 ноя 2025, 22:51
cedcf6a
Код
Авторство
О чём код?
// src/disk.rs use std::fs::{self, OpenOptions}; use std::io::{self, Read, Seek, SeekFrom, Write}; use std::time::Instant; #[derive(Debug, Clone)] pub struct DiskResult { pub test_file_size_bytes: u64, pub sequential_write_mib_s: f64, pub sequential_read_mib_s: f64, pub random_read_iops: f64, pub random_write_iops: f64, pub fsync_latency_ms: f64, pub storage_type: String, } const TEST_FILE: &str = "/tmp/cloud_bench_disk_test.bin"; const BLOCK_SIZE_SEQ: usize = 1024 * 1024; // 1 MiB const BLOCK_SIZE_RAND: usize = 4096; // 4 KiB const RAND_OPS: usize = 20_000; pub fn bench_disk() -> io::Result<DiskResult> { let file_size = determine_test_size(); // Открываем файл let mut file = OpenOptions::new() .read(true) .write(true) .create(true) .open(TEST_FILE)?; // Удаляем из ФС сразу — файл остаётся доступен по дескриптору let _ = fs::remove_file(TEST_FILE); // === 1. Sequential Write === let data = vec![0x7A; BLOCK_SIZE_SEQ]; // ✅ Исправлено: имя переменной 'data' let block_count = file_size as usize / BLOCK_SIZE_SEQ; let start = Instant::now(); for _ in 0..block_count { file.write_all(&data)?; } file.flush()?; let write_duration = start.elapsed(); let sequential_write_mib_s = (file_size as f64 / (1024.0 * 1024.0)) / write_duration.as_secs_f64(); // === 2. Fsync Latency === let mut fsync_total_ms = 0.0; for _ in 0..5 { let start = Instant::now(); file.sync_all()?; fsync_total_ms += start.elapsed().as_millis() as f64; } let fsync_latency_ms = fsync_total_ms / 5.0; // === 3. Sequential Read === file.seek(SeekFrom::Start(0))?; let mut buffer = vec![0u8; BLOCK_SIZE_SEQ]; let mut total_read: u64 = 0; let start = Instant::now(); while total_read < file_size { let n = file.read(&mut buffer)?; if n == 0 { break; } total_read += n as u64; } let read_duration = start.elapsed(); let sequential_read_mib_s = (file_size as f64 / (1024.0 * 1024.0)) / read_duration.as_secs_f64(); // === 4. Random Read & Write (4K) === let mut rng = rand::thread_rng(); let mut rand_buffer = vec![0u8; BLOCK_SIZE_RAND]; // Random Read let start = Instant::now(); for _ in 0..RAND_OPS { let max_offset = (file_size / BLOCK_SIZE_RAND as u64) - 1; let offset = rand::Rng::gen_range(&mut rng, 0..=max_offset) * BLOCK_SIZE_RAND as u64; file.seek(SeekFrom::Start(offset))?; file.read_exact(&mut rand_buffer)?; } let rand_read_duration = start.elapsed(); // Random Write let start = Instant::now(); for _ in 0..RAND_OPS { let max_offset = (file_size / BLOCK_SIZE_RAND as u64) - 1; let offset = rand::Rng::gen_range(&mut rng, 0..=max_offset) * BLOCK_SIZE_RAND as u64; file.seek(SeekFrom::Start(offset))?; rand_buffer[0..8].copy_from_slice(&offset.to_le_bytes()); file.write_all(&rand_buffer)?; } let rand_write_duration = start.elapsed(); // === 5. Тип хранилища === let avg_rand_read_ms = rand_read_duration.as_millis() as f64 / RAND_OPS as f64; let storage_type = if avg_rand_read_ms < 1.0 { "SSD".to_string() } else if avg_rand_read_ms < 10.0 { "Fast HDD / Cloud SSD".to_string() } else { "HDD".to_string() }; Ok(DiskResult { test_file_size_bytes: file_size, sequential_write_mib_s, sequential_read_mib_s, random_read_iops: RAND_OPS as f64 / rand_read_duration.as_secs_f64(), random_write_iops: RAND_OPS as f64 / rand_write_duration.as_secs_f64(), fsync_latency_ms, storage_type, }) } fn determine_test_size() -> u64 { if let Ok(content) = std::fs::read_to_string("/proc/meminfo") { for line in content.lines() { if line.starts_with("MemTotal:") { if let Some(kb_str) = line.split_whitespace().nth(1) { if let Ok(mem_kb) = kb_str.parse::<u64>() { let mem_mb = mem_kb / 1024; let test_mb = (mem_mb as f64 * 0.1) as u64; return test_mb.clamp(256, 1024) * 1024 * 1024; } } } } } 512 * 1024 * 1024 }