feat: 优化块

This commit is contained in:
Netlops 2025-04-23 18:36:17 +08:00
parent 4559bb2cd6
commit 3c1cc26896

View File

@ -35,6 +35,9 @@ type PowerLossTest struct {
blocksMap map[int]model.BlockStatus // 数据块状态映射
}
// 预生成的数据块数量常量
const PreGeneratedBlockCount = 1000
// NewPowerLossTest 创建断电测试
func NewPowerLossTest(cfg *config.Config, logger *logrus.Logger) *PowerLossTest {
baseTest := NewBaseTestCase(
@ -93,6 +96,8 @@ func (t *PowerLossTest) Setup(ctx context.Context, recovery bool) error {
}
}
time.Sleep(10 * time.Second)
// 挂载缓存设备
mountPoint := t.config.Server.MountPoint
t.setMessage(fmt.Sprintf("挂载缓存设备到 %s", mountPoint))
@ -140,14 +145,14 @@ func (t *PowerLossTest) Run(ctx context.Context) (*model.TestResult, error) {
startTime := time.Now()
var totalBytesWritten int
// 第一阶段 - 在内存中预先生成所有数据块
t.setMessage("在内存中预生成数据块")
// 第一阶段 - 在内存中预先生成固定数量的数据块
t.setMessage(fmt.Sprintf("在内存中预生成 %d 个数据块", PreGeneratedBlockCount))
// 预先在内存中生成所有数据块
blocksInMemory := make([]*model.TestBlock, t.totalBlocks)
// 预先在内存中生成固定数量的数据块
preGeneratedBlocks := make([]*model.TestBlock, PreGeneratedBlockCount)
checksumMap := make(map[int]string)
for i := 0; i < t.totalBlocks; i++ {
for i := 0; i < PreGeneratedBlockCount; i++ {
select {
case <-ctx.Done():
t.setStatus(StatusAborted)
@ -164,18 +169,22 @@ func (t *PowerLossTest) Run(ctx context.Context) (*model.TestResult, error) {
block := model.NewTestBlock(data, i)
// 存储到内存中
blocksInMemory[i] = block
checksumMap[i] = block.Checksum
preGeneratedBlocks[i] = block
// 更新进度
if i > 0 && i%100 == 0 {
progress := float64(i+1) / float64(t.totalBlocks) * 30 // 前30%进度用于生成
t.setProgress(progress)
t.setMessage(fmt.Sprintf("已在内存中生成 %d/%d 个数据块", i, t.totalBlocks))
}
progress := float64(i+1) / float64(PreGeneratedBlockCount) * 30 // 前30%进度用于生成
t.setProgress(progress)
}
}
t.setMessage("预生成数据块完成,生成校验和映射")
// 为所有实际需要写入的块计算并存储校验和映射
for i := 0; i < t.totalBlocks; i++ {
blockIndex := i % PreGeneratedBlockCount
checksumMap[i] = preGeneratedBlocks[blockIndex].Checksum
}
// 将校验和映射持久化到文件
t.setMessage("持久化校验和映射到文件")
checksumFilePath := filepath.Join(t.testDir, "checksums.json")
@ -202,15 +211,19 @@ func (t *PowerLossTest) Run(ctx context.Context) (*model.TestResult, error) {
t.setMessage("校验和映射已保存,准备断电测试,开始写入数据块...")
time.Sleep(3 * time.Second) // 给用户一些时间准备
// 第二阶段 - 写入数据块到磁盘
// 第二阶段 - 写入数据块到磁盘,使用循环重复的预生成块
t.setMessage("写入数据块到磁盘 (请在适当时手动断电)")
for i, block := range blocksInMemory {
for i := 0; i < t.totalBlocks; i++ {
select {
case <-ctx.Done():
t.setStatus(StatusAborted)
return nil, ctx.Err()
default:
// 获取预生成的块(循环使用)
blockIndex := i % PreGeneratedBlockCount
block := preGeneratedBlocks[blockIndex]
// 添加到数据块列表
t.blocksMu.Lock()
t.blocks = append(t.blocks, block)
@ -244,7 +257,7 @@ func (t *PowerLossTest) Run(ctx context.Context) (*model.TestResult, error) {
t.writtenBlocks++
totalBytesWritten += len(block.Data)
t.setMessage(fmt.Sprintf("同步数据到磁盘 (已写入 %d/%d 块)", i, t.totalBlocks))
t.setMessage(fmt.Sprintf("同步数据到磁盘 (已写入 %d/%d 块)", i+1, t.totalBlocks))
_, err = utils.ExecuteCommand("sync")
if err != nil {
t.logger.Warnf("执行sync命令失败: %v", err)
@ -356,10 +369,11 @@ func (t *PowerLossTest) CheckIntegrity() *model.IntegrityInfo {
if storedChecksum, ok := checksumMap[i]; ok {
expectedChecksum = storedChecksum
} else {
// 回退到内存中的校验和
// 回退到内存中的校验和 - 现在需要考虑块的循环使用
t.blocksMu.RLock()
if i < len(t.blocks) && t.blocks[i] != nil {
expectedChecksum = t.blocks[i].Checksum
blockIndex := i % PreGeneratedBlockCount
if blockIndex < len(t.blocks) && t.blocks[blockIndex] != nil {
expectedChecksum = t.blocks[blockIndex].Checksum
}
t.blocksMu.RUnlock()
}