golang 并发demo 写入 redis
原文链接:golang 并发demo 写入 redis
源代码:
package main import (
"fmt"
"runtime"
"strconv"
"time" "gopkg.in/redis.v3"
) var (
jobnum = runtime.NumCPU()
//每次写入redis的数量
//除以 jobnum 为了保证改变了任务数, 总量不变, 便于测试
procnum = / jobnum
) type Job struct {
ID string
Client *redis.Client
Result chan<- string
} func waitJobs(dones <-chan struct{}, results chan string) {
working := jobnum
done := false
for {
select {
case result := <-results:
println(result)
case <-dones:
working--
if working <= {
done = true
}
default:
if done {
return
}
}
}
} func initClient(poolSize int) *redis.Client {
client := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
DialTimeout: time.Second,
ReadTimeout: time.Second,
WriteTimeout: time.Second,
PoolSize: poolSize,
Password: "123.com",
DB: ,
})
if err := client.FlushDb().Err(); err != nil {
panic(err)
}
return client
} func main() {
start := time.Now()
fmt.Println("start:", start)
defer func() {
end := time.Now()
fmt.Println("end:", end)
fmt.Println("jobs num:", jobnum, "total items:", jobnum*procnum)
fmt.Println("total seconds:", end.Sub(start).Seconds())
}() //任务channel 定义缓冲器为job数量
jobs := make(chan Job, jobnum)
//存放结果
results := make(chan string, jobnum*procnum)
//每个任务完成之后给dones发送一次
dones := make(chan struct{}, jobnum) client := initClient()
defer client.Close() //定义每个任务执行的方法
jobfunc := func(client *redis.Client, id string) (string, error) {
defer func() {
//完成之后向 dones 发送数据
dones <- struct{}{}
//fmt.Println("job id:", id, "完成")
}() //写入 procnum 条数据
for idx := ; idx < procnum; idx++ {
key := id + "-" + strconv.Itoa(idx) _, err := client.Set(key, time.Now().String(), ).Result()
if err != nil {
return "", err
}
//fmt.Println("key:", key, " | result:", val, " | error:", err)
} return "ok", nil
} //1 添加 job 到 channel
go func() {
for index := ; index < jobnum; index++ {
jobs <- Job{strconv.Itoa(index), client, results}
}
defer close(jobs)
}() //2 并行执行 jobs
for j := range jobs {
go func(job Job) {
jobfunc(client, job.ID)
job.Result <- "ok"
}(j)
} //3 等待所有任务完成
waitJobs(dones, results)
}
运行结果:
[root@localhost ]# go run redis.go
start: -- ::34.614166323 + UTC m=+0.001802059
ok
ok
ok
ok
ok
ok
ok
ok
end: -- ::35.655656884 + UTC m=+1.043292369
jobs num: total items:
total seconds: 1.04149031
8 个 goroutine: 1s 完成10w数据写入
golang 并发demo 写入 redis的更多相关文章
- 高并发简单解决方案————redis队列缓存+mysql 批量入库(ThinkPhP)
问题分析 问题一:要求日志最好入库:但是,直接入库mysql确实扛不住,批量入库没有问题,done.[批量入库和直接入库性能差异] 问题二:批量入库就需要有高并发的消息队列,决定采用redis lis ...
- Golang 并发简介
并发概要 随着多核CPU的普及, 为了更快的处理任务, 出现了各种并发编程的模型, 主要有以下几种: 模型名称 优点 缺点 多进程 简单, 隔离性好, 进程间几乎无影响 开销最大 多线程 目前使用最多 ...
- golang 并发锁的陷阱
错误代码示例 package main import ( "sync" "strconv" "fmt" ) type Node struct ...
- Golang - 并发编程
目录 Golang - 并发编程 1. 并行和并发 2. go语言并发优势 3. goroutine是什么 4. 创建goroutine 5. runtime包 6. channel是什么 7. ch ...
- 4种Golang并发操作中常见的死锁情形
摘要:什么是死锁,在Go的协程里面死锁通常就是永久阻塞了,你拿着我的东西,要我先给你然后再给我,我拿着你的东西又让你先给我,不然就不给你.我俩都这么想,这事就解决不了了. 本文分享自华为云社区< ...
- golang并发编程
golang并发编程 引子 golang提供了goroutine快速实现并发编程,在实际环境中,如果goroutine中的代码要消耗大量资源时(CPU.内存.带宽等),我们就需要对程序限速,以防止go ...
- 马蜂窝搜索基于 Golang 并发代理的一次架构升级
搜索业务是马蜂窝流量分发的重要入口.很多用户在使用马蜂窝时,都会有目的性地主动搜索与自己旅行需求相关的各种信息,衣食住行,事无巨细,从而做出最符合需求的旅行决策. 因此在马蜂窝,搜索业务交互的下游模块 ...
- 批量写入redis
批量写入redis key := GetSeriesKey(series.Id) idNames = append(idNames, key, series.Name) == { err = Mset ...
- lua模块demo(redis,http,mysql,cjson,本地缓存)
1. lua模块demo(redis,http,mysql,cjson,本地缓存) 1.1. 配置 在nginx.conf中设置lua_shared_dict my_cache 128m; 开启ngi ...
随机推荐
- onepill服务端
运行git搞崩掉了重新创建... 1.新建SpringBoot项目 应该就这些 2. 使用的框架: 数据库:Spring Date JPA Service+Dao+Controller OKHttpC ...
- Python的条件判断与循环
1.if语句 Python中条件选择语句的关键字为:if .elif .else这三个.其基本形式如下 if condition: blockelif condition: block...else: ...
- 萌新学渗透系列之Hack The Box_Lame
我将我的walkthrough过程用视频解说的形式记载 视频地址https://www.bilibili.com/video/BV1Mv411z75c 一是因为看我视频的后来者应该都是刚入门的新手,视 ...
- scrapyd 部署
步骤 1 pip install scrapyd pip install scrapy-client 步骤 2 修改 scrapy.cfg [deploy:targetName]url = http: ...
- MacOS下Nginx安装
1. 先安装homebrew 2. 安装Nginx,终端下执行: $ brew install nginx 安装过程中会自己安装依赖: 3. 启动nginx服务 $ nginx 成功后,使用浏览器打开 ...
- JavaScript Set对象
JavaScript Set对象 Set 用于存储任何类型的唯一值,无论是基本类型还是引用类型. 只有值没有键 严格类型检测存储,字符串数字不等同于数值型数字 存储的值具有唯一性 遍历顺序是添加的顺序 ...
- MySQL进阶篇(03):合理的使用索引结构和查询
本文源码:GitHub·点这里 || GitEE·点这里 一.高性能索引 1.查询性能问题 在MySQL使用的过程中,所谓的性能问题,在大部分的场景下都是指查询的性能,导致查询缓慢的根本原因是数据量的 ...
- 【NOI2001】方程的解数 题解(dfs+哈希)
题目描述 已知一个方程 k1*x1^p1+k2*x2^p2……+kn*xn^pn=0. 求解的个数.其中1<=x<=150,1<=p<=6; 答案在int范围内 输入格式 第一 ...
- cryptopp使用Qt mingw编译,以及海思平台交叉编译
编译工程生成,使用qmake生成qt工程文件(海思平台时,要用海思平台的qmake),将 TEMPLATE = app 修改为: TEMPLATE = lib 添加如下: win32:LIBS += ...
- 我给这个Python库打101分!
日志在开发过程中是一种被很多程序员 不重视 ,但是却 至关重要 的一项功能. 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案 ...