使用golang实现一个MapReduce

2023年 9月 21日 50.7k 0

背景

在日常业务开发中,我们经常遇到需要并发处理的场景。例如:

  • 依据id列表查询db,获取数据。为了保证查询性能,单次查询的id列表长度最好不要超过50(依据业务来判断),当id列表长度超过50时,拆分成并发请求,减少耗时和提高性能,返回聚合后的结果
  • 外部提供的接口不支持批量写入/读取数据,当需要批量处理数据时,为了减少耗时和提高性能,并发请求外部接口

以上处理数据的场景,都可以分成两个阶段:

  • 请求阶段。基本都是IO操作,请求db,或者是调用外部接口
  • 处理阶段。对返回的数据进行转换,过滤,聚合等操作
  • 同步调用,调用耗时增长明显

    whiteboard_exported_image.png

    并发调用,可以减少调用耗时

    whiteboard_exported_image-2.png

    分析

    上面说的处理数据的场景,都可以分成两个阶段:

  • 请求阶段。IO操作,可以并发的去进行,互不干扰
  • 处理阶段。同步进行,保证聚合结果的正确性
  • 这种是一种特殊的MapReduce

    whiteboard_exported_image-3.png
    为了处理这类场景,我们需要明确以下几个部分:

    • 列表长度。代表有多少数据需要进行处理
    • map函数。并发处理的函数,互不干扰
    • reduce函数。同步处理的函数
    • 最大并发数。决定需要开多少线程/协程来处理
    • 拆分长度。列表长度 / 拆分长度 = 子任务数

    由于我在日常开发中常使用golang语言,下面梳理下使用golang来解决这类问题的一个思路

    函数签名

    func ChunkProcess(length int, procedure func(start, end int) (interface{}, error),
       reduce func(partialResult interface{}, partialErr error, start, end int), maxConcurrent int, chunkSize int) 
    

    核心逻辑:

    • 当最大并发数

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论