EasyDarwin媒体文件管理:自动清理与存储策略

EasyDarwin媒体文件管理:自动清理与存储策略

【免费下载链接】EasyDarwin open source、high performance、industrial rtsp streaming server,a lot of optimization on streaming relay,KeyFrame cache,RESTful,and web management,also EasyDarwin support distributed load balancing,a simple streaming media cloud platform architecture.高性能开源RTSP流媒体服务器,基于go语言研发,维护和优化:RTSP推模式转发、RTSP拉模式转发、录像、检索、回放、关键帧缓存、秒开画面、RESTful接口、WEB后台管理、分布式负载均衡,基于EasyDarwin构建出了一套基础的流媒体云视频平台架构! 【免费下载链接】EasyDarwin 项目地址: https://gitcode.com/gh_mirrors/ea/EasyDarwin

痛点直击:流媒体服务器的存储管理困境

你是否遇到过流媒体服务器因存储耗尽导致服务中断?是否还在手动清理过期视频文件?EasyDarwin作为高性能RTSP流媒体服务器,每天处理大量视频数据,如何高效管理媒体文件生命周期、避免存储溢出成为关键挑战。本文将系统解析EasyDarwin的媒体文件自动清理机制与存储优化策略,帮助你构建稳定可靠的流媒体存储系统。

读完本文你将获得:

  • 掌握EasyDarwin双维度自动清理机制的工作原理
  • 学会配置文件过期时间与磁盘使用率阈值
  • 理解媒体文件存储架构与路径规划
  • 优化存储策略的5个实用技巧
  • 常见清理问题的排查与解决方案

存储管理核心架构

EasyDarwin采用分层存储架构,将媒体文件生命周期管理分为主动清理被动清理两大维度,结合文件系统监控与数据库记录,实现完整的存储治理闭环。

mermaid

核心存储目录结构

EasyDarwin采用双目录结构分离管理原始文件与转码文件:

目录类型配置参数功能描述
源文件目录VodConfig.SrcDir存储上传的原始视频文件,保留完整质量
转码文件目录VodConfig.Dir存储转码后的TS分片文件及索引,用于点播服务

通过finder.Engine组件统一管理这两个目录的文件生命周期,确保存储系统有序运行。

自动清理机制详解

1. 定时过期清理:基于时间维度的治理

EasyDarwin实现了基于文件修改时间的自动过期清理机制,通过finder.Engine组件的定时任务扫描文件系统,删除超过设定存活时间的媒体文件。

核心实现代码分析
// deadline 超时删除
func (e *Engine) deadline() {
    ticker := time.NewTimer(e.deadlineDurationTimer)
    defer ticker.Stop()
    for {
        select {
        case <-e.ctx.Done():
            return
        case <-ticker.C:
            if err := filepath.Walk(e.prefix, func(path string, info os.FileInfo, _ error) error {
                if info == nil || info.IsDir() {
                    return nil
                }
                // 判断文件修改时间是否超过过期时间
                if time.Since(info.ModTime()) > e.expire {
                    _ = os.RemoveAll(path)
                }
                return nil
            }); err != nil {
                slog.Error("deadline", "err", err)
            }
            ticker.Reset(e.deadlineDurationTimer)
        }
    }
}
关键参数配置
参数默认值说明
expire可配置文件过期时间,超过此时间的文件将被删除
deadlineDurationTimer10分钟定时扫描间隔,建议根据文件创建频率调整

最佳实践:对于安防场景建议设置7-30天过期时间,直播回放场景可缩短至24-48小时,具体根据业务需求和存储容量规划。

2. 磁盘阈值清理:基于空间维度的治理

当磁盘使用率达到设定阈值时,系统会触发紧急清理流程,按文件创建时间从旧到新删除文件,确保磁盘空间维持在安全水位。

核心实现代码分析
// overWrite 处理磁盘空间超过阈值的清理
func (e *Engine) overWrite() {
    for {
        select {
        case <-e.ctx.Done():
            return
        case <-e.limit:
            var files []system.FileInfo
            for {
                // 获取当前磁盘使用率
                got, err := system.DiskUsagePercent(e.prefix)
                if err != nil {
                    slog.Error("DiskUsagePercent", "err", err)
                    continue
                }
                
                // 检查是否低于安全阈值
                if float32(got) < e.diskUsagePercentLimit {
                    // 根据使用率差距动态调整下次检查间隔
                    s := e.diskUsagePercentLimit - float32(got)
                    switch true {
                    case s > 30:
                        time.Sleep(5 * time.Minute)
                    case s > 10:
                        time.Sleep(time.Minute)
                    case s > 6:
                        time.Sleep(10 * time.Second)
                    }
                    break
                }
                
                // 首次运行时获取文件列表
                if files == nil {
                    files, err = system.GlobFiles(e.prefix)
                    if err != nil {
                        slog.Error("GlobFiles", "err", err)
                        continue
                    }
                }
                
                // 清理旧文件
                count, err := system.CleanOldFiles(files, e.deleteElements)
                if err != nil {
                    slog.Error("CleanOldFiles", "err", err)
                }
                if count <= len(files) {
                    files = files[count:]
                }
                // 如果一次删除不足,退出循环等待下次触发
                if count < e.deleteElements {
                    break
                }
            }
        }
    }
}
磁盘清理关键参数
参数默认值说明
diskUsagePercentLimit85%磁盘使用率阈值,超过此值触发清理
deleteElements5每次清理的文件数量,避免一次性删除过多文件影响系统性能

工作流程:当磁盘使用率超过阈值时,系统会按文件创建时间从旧到新排序,每次删除deleteElements数量的文件,直到使用率低于阈值。清理过程采用渐进式策略,避免对系统负载造成冲击。

3. 手动清理API:按需触发的文件删除

除自动清理外,EasyDarwin提供RESTful API接口用于手动触发文件清理,支持单文件删除和批量删除两种模式。

单文件删除API
/**
 * @api {post} /vod/remove 08 删除点播
 * @apiGroup 02vod
 * @apiParam {String} id
 * @apiUse simpleSuccess
 */
func (r *VODRouter) remove(c *gin.Context) {
    form := IDForm{}
    if err := c.Bind(&form); err != nil {
        c.AbortWithStatus(http.StatusBadRequest)
        return
    }
    db := data.GetDatabase()

    var vod video.TVod
    db.First(&vod, consts.SqlWhereID, form.ID)
    if vod.ID != "" {
        if vod.Status == consts.VodStatusTransing {
            AbortWithString(c, http.StatusBadRequest, fmt.Sprintf("%s 正在转码", vod.Name))
            return
        }

        conf := gCfg.VodConfig
        // 必须添加 efile.GetRealPath 才能对比。要不然 video.Folder 为空,会导致整个最外层文件夹被删除
        tsFolder := efile.GetRealPath(filepath.Join(conf.Dir, vod.Folder))
        srcFile := efile.GetRealPath(filepath.Join(conf.SrcDir, vod.Path))

        if tsFolder != conf.Dir && srcFile != conf.SrcDir {
            slog.Info("remove tsFole : ", tsFolder)
            slog.Info("remove srcFile : ", srcFile)
            os.RemoveAll(tsFolder)
            os.RemoveAll(srcFile)
        }

        db.Delete(vod)
    }
    Success(c)
}
批量删除API
/**
 * @api {post} /vod/removeBatch 09 批量删除点播文件
 * @apiGroup 02vod
 * @apiParam {Array} ids
 * @apiUse simpleSuccess
 */
func (r *VODRouter) removeBatch(c *gin.Context) {
    form := IDSForm{}
    if err := c.Bind(&form); err != nil {
        c.AbortWithStatus(http.StatusBadRequest)
        return
    }
    var vods []video.TVod
    db := data.GetDatabase()

    tx := db.Begin()
    tx.Find(&vods, consts.SqlWhereIDIn, form.IDS)
    for _, vod := range vods {
        if vod.Status == consts.VodStatusTransing {
            tx.Rollback()
            AbortWithString(c, http.StatusBadRequest, fmt.Sprintf("%s 正在转码", vod.Name))
            return
        }

        tx.Delete(vod)
    }
    tx.Commit()

    conf := gCfg.VodConfig
    for _, vod := range vods {
        tsFolder := efile.GetRealPath(filepath.Join(conf.Dir, vod.Folder))
        srcFile := efile.GetRealPath(filepath.Join(conf.SrcDir, vod.Path))
        if tsFolder != conf.Dir && srcFile != conf.SrcDir {
            slog.Info("remove batch video : ", tsFolder)
            slog.Info("remove batch video : ", srcFile)
            os.RemoveAll(tsFolder)
            os.RemoveAll(srcFile)
        } else {
            CodeWithMsg(c, http.StatusInternalServerError, "内部错误,删除失败。")
            return
        }
    }
    Success(c)
}

安全机制:删除操作前会检查文件状态,对于正在转码(VodStatusTransing)的文件会拒绝删除请求,避免破坏转码过程。同时通过efile.GetRealPath确保路径正确性,防止误删根目录。

存储策略优化实践

1. 合理设置过期时间与磁盘阈值

根据业务场景调整文件过期时间和磁盘使用率阈值,是平衡存储成本与服务质量的关键:

应用场景推荐过期时间推荐磁盘阈值原因分析
实时监控7-30天80%需保留一定历史数据用于回溯,磁盘阈值设低些保证写入稳定性
直播回放24-72小时85%内容时效性强,可快速清理释放空间
点播服务30-90天82%根据内容热度动态调整,热门内容延长过期时间

配置示例

// 创建文件管理器实例,设置默认过期时间为30天
engine := finder.NewEngine("/data/vod", 30*24*time.Hour)
// 调整磁盘使用率阈值为80%
engine.SetDiskUsagePercentLimit(80)
// 设置每次清理10个文件
engine.SetDeleteElements(10)

2. 媒体文件存储路径规划

合理的文件路径设计可提高清理效率,避免单目录下文件数量过多影响文件系统性能:

推荐路径格式{年份}/{月份}/{日期}/{视频ID}/{分辨率}/{文件名}

优点:

  • 按时间维度分层,便于按时间段清理过期文件
  • 每个目录文件数量可控,提高文件系统操作效率
  • 支持多分辨率存储,便于按需求清理低优先级分辨率文件

实现示例

// 生成按日期分层的存储路径
func generateStoragePath(videoID string) string {
    today := time.Now().Format("2006/01/02")
    return filepath.Join(today, videoID)
}

3. 转码文件生命周期管理

转码文件通常比源文件小得多,但数量更多,建议采用更短的过期时间:

  1. 分辨率分级清理:优先清理低分辨率文件,保留高价值内容
  2. 热度基于清理:结合播放次数,长期未播放的转码文件优先清理
  3. 索引先行策略:删除文件前先删除索引,确保用户无法访问后再删除实际文件

4. 存储监控与告警机制

结合EasyDarwin的监控接口,实现存储状态监控与告警:

mermaid

监控指标建议

  • 磁盘使用率及增长趋势
  • 每日清理文件数量
  • 清理操作成功率
  • 各目录文件数量分布

5. 分布式存储扩展

当单节点存储达到瓶颈时,可通过EasyDarwin的分布式架构扩展存储能力:

  1. 按地理位置分布:将文件存储在离用户最近的节点
  2. 按内容类型分片:不同类型的内容存储在不同节点
  3. 冷热数据分离:热门内容存储在高性能存储,冷数据迁移到低成本存储

常见问题与解决方案

问题1:清理不生效,磁盘空间持续增长

排查步骤

  1. 检查是否有进程正在写入被标记为删除的文件,导致文件句柄未释放
  2. 验证finder.Engine是否正确初始化并启动
  3. 检查日志确认是否有清理错误:grep "CleanOldFiles" easydarwin.log
  4. 确认文件系统权限是否允许EasyDarwin删除文件

解决方案

// 增加清理错误日志详细度
func (e *Engine) deadline() {
    // ... 原有代码 ...
    if err := os.RemoveAll(path); err != nil {
        slog.Error("删除过期文件失败", "path", path, "err", err)
    }
    // ... 原有代码 ...
}

问题2:清理过程影响系统性能

优化方案

  1. 降低清理频率:调整deadlineDurationTimer参数延长扫描间隔
  2. 减少每次清理数量:调小deleteElements参数
  3. 错峰清理:在系统负载低的时段执行清理任务
  4. 增加IO优先级控制:降低清理进程的IO优先级

实现示例

// 设置清理任务在凌晨3点执行
func (e *Engine) SetCleanupSchedule(hour, minute int) {
    now := time.Now()
    nextRun := time.Date(now.Year(), now.Month(), now.Day(), hour, minute, 0, 0, now.Location())
    if nextRun.Before(now) {
        nextRun = nextRun.Add(24 * time.Hour)
    }
    delay := nextRun.Sub(now)
    
    time.AfterFunc(delay, func() {
        // 执行清理
        e.cleanupOnce()
        // 每天执行一次
        e.SetCleanupSchedule(hour, minute)
    })
}

问题3:误删重要文件

预防措施

  1. 回收站机制:删除文件前先移动到回收站,保留7-15天再彻底删除
  2. 删除确认:重要文件删除前要求二次确认
  3. 操作审计:记录所有删除操作,包括触发方式、执行人、文件信息
  4. 定期备份:核心文件定期备份到独立存储

回收站实现示例

// 带回收站的文件删除函数
func safeDelete(path string) error {
    recycleBin := filepath.Join(filepath.Dir(path), ".recycle")
    os.MkdirAll(recycleBin, 0755)
    
    // 移动到回收站而不是直接删除
    recyclePath := filepath.Join(recycleBin, fmt.Sprintf("%s_%d", filepath.Base(path), time.Now().Unix()))
    if err := os.Rename(path, recyclePath); err != nil {
        return err
    }
    
    // 启动定时任务,7天后彻底删除
    time.AfterFunc(7*24*time.Hour, func() {
        os.RemoveAll(recyclePath)
    })
    
    return nil
}

总结与展望

EasyDarwin通过定时过期清理磁盘阈值清理双机制,结合手动API,构建了完善的媒体文件存储管理体系。合理配置清理参数、优化存储路径、实施分级存储策略,可有效降低存储成本,提高系统稳定性。

未来存储管理将向更智能的方向发展:

  1. AI预测性清理:基于内容热度和用户行为预测,提前清理低价值文件
  2. 弹性存储扩展:结合云存储自动扩展存储容量
  3. 智能转码决策:根据存储状况动态调整转码策略,平衡质量与存储占用

掌握这些存储管理技术,将帮助你构建更可靠、更经济的流媒体服务系统。建议定期审查存储使用情况和清理效果,持续优化存储策略,以适应业务发展变化。

行动指南

  1. 今日检查你的EasyDarwin存储配置,确保过期时间和磁盘阈值符合业务需求
  2. 实施文件路径优化,按时间和ID分层存储
  3. 部署存储监控,设置关键指标告警
  4. 制定定期审查计划,每季度评估存储策略有效性

【免费下载链接】EasyDarwin open source、high performance、industrial rtsp streaming server,a lot of optimization on streaming relay,KeyFrame cache,RESTful,and web management,also EasyDarwin support distributed load balancing,a simple streaming media cloud platform architecture.高性能开源RTSP流媒体服务器,基于go语言研发,维护和优化:RTSP推模式转发、RTSP拉模式转发、录像、检索、回放、关键帧缓存、秒开画面、RESTful接口、WEB后台管理、分布式负载均衡,基于EasyDarwin构建出了一套基础的流媒体云视频平台架构! 【免费下载链接】EasyDarwin 项目地址: https://gitcode.com/gh_mirrors/ea/EasyDarwin

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值