go-zero(十三)使用MapReduce并发

go zero 使用MapReduce并发

一、MapReduce 介绍

MapReduce 是一种用于并行计算的编程模型,特别适合在大规模数据处理场景中简化逻辑代码。

官方文档:

https://go-zero.dev/docs/components/mr

1. MapReduce 的核心概念

在 MapReduce 中,主要有以下三个核心步骤:
a. Generate (生成数据)

  • 数据的初始输入阶段。可以是一个简单的循环,也可以是从数据库、文件或其他来源加载数据。
    b. Mapper (映射)
  • 将输入数据映射为中间结果。通常用来过滤、转换、查询或处理数据。
    c. Reducer (归约)
  • 对映射后的数据进行汇总处理,生成最终的结果。

在 go zero 中,mr.MapReduce 的具体代码如下:


func MapReduce[T, U, V any](generate GenerateFunc[T], mapper MapperFunc[T, U], reducer ReducerFunc[U, V],opts ...Option) (V, error) {panicChan := &onceChan{channel: make(chan any)}source := buildSource(generate, panicChan)return mapReduceWithPanicChan(source, panicChan, mapper, reducer, opts...)
}

2. 为什么需要 MapReduce

在实际的业务场景中我们常常需要从不同的 rpc 服务中获取相应属性来组装成复杂对象。

比如要查询商品详情:

  • 商品服务-查询商品属性
  • 库存服务-查询库存属性
  • 价格服务-查询价格属性
  • 营销服务-查询营销属性

如果是串行调用的话响应时间会随着 rpc 调用次数呈线性增长,所以我们要优化性能一般会将串行改并行。

简单的场景下使用 WaitGroup 也能够满足需求,但是如果我们需要对 rpc 调用返回的数据进行校验、数据加工转换、数据汇总呢?继续使用 WaitGroup 就有点力不从心了.。

二、项目构建

接下来我们使用一个文章列表功能简单的演示下

1. article数据表

这是存储文章信息的表,包含标题、内容、作者、评论数等字段。

CREATE TABLE `article` (`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',`title` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '标题' COLLATE 'utf8mb4_bin',`content` TEXT NOT NULL COMMENT '内容' COLLATE 'utf8_unicode_ci',`cover` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '封面' COLLATE 'utf8mb4_bin',`description` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '描述' COLLATE 'utf8mb4_bin',PRIMARY KEY (`id`)
);

2.article.api

在实际开发中,应该传入作者ID、游标、页码、排序方法等信息,这里为了方便演示就不传入参数了,API 定义如下:

syntax = "v1"type (ArticleInfo {ArticleId   int64  `json:"article_id"`Title       string `json:"title"`Content     string `json:"content"`Description string `json:"description"`Cover       string `json:"cover"`}ArticleListResponse {Articles []ArticleInfo `json:"articles"`}
)@server (prefix: /v1/article
)
service article-api {@handler Articlelisthandlerpost /list returns (ArticleListResponse)
}

三、使用 MapReduce

拉取库

go get github.com/zeromicro/go-zero/core/mr

1.实现文章列表

我们使用 MapReduce 来并行处理文章数据,

func (l *ArticlelistLogic) Articlelist() (resp *types.ArticleListResponse, err error) {// Step 1: Generate 数据//这里为了方便我使用了简单for循环产生文档IDgenerateFunc := func(source chan<- int) {for id := 1; id < 50; id++ { // 模拟文章 ID 数据source <- id}}articleModel := l.svcCtx.ArticleModel// Step 2: Mapper 映射处理mapperFunc := func(id int, writer mr.Writer[*types.ArticleInfo], cancel func(error)) {//使用产生id,查询文章详情one, err := articleModel.FindOne(l.ctx, uint64(id)) // 查找单篇文章if err != nil {return // 跳过错误}//FindOne返回的是 *model.Article类型,Mapper映射的类型为*types.ArticleInfo//所以需要转换一下articleInfo := &types.ArticleInfo{ArticleId:   int64(one.Id),Title:       one.Title,Content:     one.Content,Description: one.Description,Cover:       one.Cover,}writer.Write(articleInfo) // 写入中间结果}// Step 3: Reducer 汇总处理reduceFunc := func(pipe <-chan *types.ArticleInfo, writer mr.Writer[[]types.ArticleInfo], cancel func(error)) {var articleList []types.ArticleInfofor article := range pipe {articleList = append(articleList, *article) }writer.Write(articleList) // 写入最终结果}// 调用 MapReduce//mr.WithWorkers(5)  允许调用者自定义并发工作线程数。//如果不传入mr.WithWorkers ,默认Workers为16个reduce, err := mr.MapReduce(generateFunc, mapperFunc, reduceFunc, mr.WithWorkers(5))   if err != nil {return nil, err // 处理错误}// 返回结果return &types.ArticleListResponse{Articles: reduce,}, nil
}

在这里插入图片描述

2. 详细讲解

Step 1: Generate 数据
generateFunc 的作用是提供初始数据。在本例中,我们通过一个循环生成了文章的 ID:

generateFunc := func(source chan<- int) {for id := 1; id < 50; id++ {source <- id}
}

Step 2: Mapper 映射处理
mapperFunc 用于处理每一个文章 ID,并将其转换为 ArticleInfo

  • 使用 articleModel.FindOne 从数据库中获取文章数据。
  • 如果获取失败,跳过该 ID。
  • 将结果通过 writer.Write 写入到下一步。
mapperFunc := func(id int, writer mr.Writer[*types.ArticleInfo], cancel func(error)) {one, err := articleModel.FindOne(l.ctx, uint64(id))if err != nil {return}articleInfo := &types.ArticleInfo{ArticleId:   int64(one.Id),Title:       one.Title,Content:     one.Content,Description: one.Description,Cover:       one.Cover,}writer.Write(articleInfo)
}

Step 3: Reducer 汇总处理
reduceFuncmapperFunc 的结果汇总为最终的 []types.ArticleInfo

  • 遍历管道中的每个 *types.ArticleInfo
  • 将解引用后的 ArticleInfo 添加到结果列表。
reduceFunc := func(pipe <-chan *types.ArticleInfo, writer mr.Writer[[]types.ArticleInfo], cancel func(error)) {var articleList []types.ArticleInfofor article := range pipe {articleList = append(articleList, *article)}writer.Write(articleList)
}

3. 测试运行

/v1/article/list 发送 POST 请求:

curl -X POST http://localhost:8888/v1/article/list

运行结果如下:

{"articles": [{"article_id": 1,"title": "标题1","content": "这是内容1","description": "描述1","cover": "封面1.jpg"},...]
}

4.效率对比

普通循环

为了更直观的对比效率,我们使用普通循环再次实现下文章列表:

func (l *ArticlelistLogic) Articlelist() (resp *types.ArticleListResponse, err error) {// todo: add your logic here and delete this linetime1 := time.Now()var articleList []types.ArticleInfoarticleModel := l.svcCtx.ArticleModelfor id := 1; id < 50; id++ {article, _ := articleModel.FindOne(l.ctx, uint64(id))articleInfo := types.ArticleInfo{ArticleId:   int64(article.Id),Title:       article.Title,Content:     article.Content,Description: article.Description,Cover:       article.Cover,}articleList = append(articleList, articleInfo)}time2 := time.Now()logx.Info("执行时间为:", time2.Sub(time1))return &types.ArticleListResponse{Articles: articleList,}, nil}

效率对比

这个执行时间可能每次都不一样,但是进过多次对比, 使用mapreduce 效率是高于普通方法的

使用串行调用时间:
在这里插入图片描述

使用MapReduce消耗时间:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/489978.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

入门pytorch-Transformer

前言 虽然Transformer是2017年由Google推出&#xff0c;如果按照读论文只读近两年的思路看&#xff0c;那它无疑是过时的&#xff0c;但可惜的是&#xff0c;目前很多论文的核心依然是Transformer&#xff0c;或者由其进行改进的&#xff0c;故本文使用pytorch来搭建一下Trans…

利用代理IP爬取Zillow房产数据用于数据分析

引言 最近数据分析的热度在编程社区不断攀升&#xff0c;有很多小伙伴都开始学习或从事数据采集相关的工作。然而&#xff0c;网站数据已经成为网站的核心资产&#xff0c;许多网站都会设置一系列很复杂的防范措施&#xff0c;阻止外部人员随意采集其数据。为了解决这个问题&a…

精品基于Python实现的微信小程序校园导航系统-微信小程序

[含文档PPT源码等] [包运行成功永久免费答疑辅导] 《django微信小程序校园导航系统》该项目采用技术Python的django框架、mysql数据库 &#xff0c;项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、核心代码介绍视频等 软件开发环境及开发工具&#xf…

动手学深度学习-线性神经网络-7softmax回归的简洁实现

目录 初始化模型参数 重新审视Softmax的实现 优化算法 训练 小结 在 线性回归的实现中&#xff0c; 我们发现通过深度学习框架的高级API能够使实现 线性回归变得更加容易。 同样&#xff0c;通过深度学习框架的高级API也能更方便地实现softmax回归模型。 本节如在上一节…

09篇--图片的水印添加(掩膜的运用)

如何添加水印&#xff1f; 添加水印其实可以理解为将一张图片中的某个物体或者图案提取出来&#xff0c;然后叠加到另一张图片上。具体的操作思想是通过将原始图片转换成灰度图&#xff0c;并进行二值化处理&#xff0c;去除背景部分&#xff0c;得到一个类似掩膜的图像。然后…

封装数组去重的方法

前言 之前在工作中我一直在用lodash这个方法库&#xff0c;前段时间又接触了更现代化的方法库radash&#xff0c;这两个方法库可以说是各有优劣&#xff0c;lodash中有很实用的cloneDeep&#xff0c;radash中则有tryit、all等异步方法&#xff0c;它们都无法做到完全代替对方。…

前端成长之路:CSS复合选择器

复合选择器 在CSS中&#xff0c;可以根据选择器的类型将选择器分为基础选择器和复合选择器。 基础选择器就是前面提到过的类选择器、id选择器、标签选择器等&#xff1b;而复合选择器就是在基础选择器的基础之上&#xff0c;将基本选择器进行组合形成的。 复合选择器是由两个及…

在数字孪生开发领域threejs现在的最新版本已经更新到多少了?

在数字孪生开发领域three.js现在的最新版本已经更新到多少了&#xff1f; 在数字孪生开发领域&#xff0c;three.js作为一款强大的JavaScript 3D库&#xff0c;广泛应用于Web3D可视化、智慧城市、智慧园区、数字孪生等多个领域。随着技术的不断进步和需求的日益增长&#xff0…

HTML入门级学习笔记1【超详细】

目录 一、计算机基础知识 2.1 文件和文件夹管理 2.2 特殊按键和快捷键 2.3 打字速度 二、互联网的原理 3.1 上网就是请求数据 3.2 服务器 3.3 浏览器 3.4 HTTP 三、HTML初步认识 4.1 认识什么是纯文本文件txt 4.2 HTML是负责描述文档语义的语言 四、Sublime 五、HTML骨架和基本…

【网络】传输层协议UDP/TCP网络层IP数据链路层MACNAT详解

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;计算机网络原理_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.传输层协议 UDP 1.1 传输层 1.2 端口号 1.3 UDP 协议 1.3.1 UDP 协议端格式 1.3.2 UDP 的特点 1.3.3 面向数据报 1…

计算机网络技术基础:3.计算机网络的拓扑结构

网络拓扑结构是指用传输媒体互连各种设备的物理布局&#xff0c;即用什么方式把网络中的计算机等设备连接起来。将工作站、服务站等网络设备抽象为点&#xff0c;称为“节点”&#xff1b;将通信线路抽象为线&#xff0c;称为“链路”。由节点和链路构成的抽象结构就是网络拓扑…

SecureCRT/FX使用[无限试用SecureCRT][新版本SecureFX双击站点总是自动跳到SecureCRT]

无限试用SecureCRT 本文摘录于&#xff1a;https://blog.csdn.net/qq_52162404/article/details/139703993#:~:textSecureCRT只是做学习备份之用&#xff0c;绝无抄袭之意&#xff0c;有疑惑请联系本人&#xff01; 我这里修改BAT如下,同时删除CRT和FX的license: echo off re…

Nacos系列:Nacos 控制台手册

引言 Nacos是阿里巴巴中间件部门开源的一款用于服务发现和配置管理的产品&#xff0c;Nacos 控制台主要旨在于增强对于服务列表、健康状态管理、服务治理、分布式配置管理等方面的管控能力&#xff0c;以便进一步帮助用户降低管理微服务应用架构的成本。 一、访问 Nacos 控制台…

frida打印日志字体加颜色

平时写frida hook 脚本&#xff0c;有时打印出来的日志太多都是一个颜色不美观。 于是找AI 问了一下frida打印日志字体加颜色的方法 // ANSI 转义码 const RESET “\x1b[0m”; const RED “\x1b[31m”; const GREEN “\x1b[32m”; const YELLOW “\x1b[33m”; const BLUE …

Thunderfury, Blessed Blade of the Windseeker

Thunderfury, Blessed Blade of the Windseeker 雷霆之怒&#xff0c;逐风者的祝福之剑 她应该是wow里面造型最帅&#xff0c;最酷的模型超大武器&#xff0c;而且特效触发频率很高&#xff0c;群拉效果非常好。 雷霆之怒&#xff0c;逐风者的祝福之剑 - 物品 - NFU魔兽世界1…

ubuntu+ros新手笔记(三)

系统ubuntu22.04 ros2 humble 1. 设置ubuntu终端字体大小 点击Terminal右上角的三条横线—>Preferences—>Unnamed—>Text—>勾选Custom font—>点击右侧的字号&#xff08;我的显示的是12&#xff09;—>最下方Size处设置字号大小—>Select—>设置完…

Deveco报错Only files in a module can be previewed

创建工程后需要看看预览的效果&#xff0c;却出现了这个错误 到Index.ets文件下重新构建工程 详细可以查询 鸿蒙报错&#xff08;Only files in a module can be previewed&#xff09;

第六届地博会开幕,世界酒中国菜美食文化节同期启幕推动地标发展

第六届知交会暨地博会开幕&#xff0c;辽黔欧三地馆亮点纷呈&#xff0c;世界酒中国菜助力地理标志产品发展 第六届知交会暨地博会盛大开幕&#xff0c;多地展馆亮点频出&#xff0c;美食文化节同期启幕推动地标产业发展 12月9日&#xff0c;第六届粤港澳大湾区知识产权交易博…

计算机毕业设计PySpark+PyFlink+Hive地震预测系统 地震数据分析可视化 地震爬虫 大数据毕业设计 Hadoop 机器学习 深度学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

C# 探险之旅:第二十七节 - 类型class(属性) —— 给你的类穿上“属性”的外衣

嘿&#xff0c;探险家们&#xff01;欢迎再次踏上我们的C#奇幻之旅。今天&#xff0c;我们要聊聊一个超级有趣的话题——类的“属性”。想象一下&#xff0c;如果我们要给类穿上一件酷炫的外衣&#xff0c;那属性就是这件外衣上的各种口袋和装饰&#xff0c;让类变得既实用又拉…