原文链接: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的更多相关文章

  1. 高并发简单解决方案————redis队列缓存+mysql 批量入库(ThinkPhP)

    问题分析 问题一:要求日志最好入库:但是,直接入库mysql确实扛不住,批量入库没有问题,done.[批量入库和直接入库性能差异] 问题二:批量入库就需要有高并发的消息队列,决定采用redis lis ...

  2. Golang 并发简介

    并发概要 随着多核CPU的普及, 为了更快的处理任务, 出现了各种并发编程的模型, 主要有以下几种: 模型名称 优点 缺点 多进程 简单, 隔离性好, 进程间几乎无影响 开销最大 多线程 目前使用最多 ...

  3. golang 并发锁的陷阱

    错误代码示例 package main import ( "sync" "strconv" "fmt" ) type Node struct ...

  4. Golang - 并发编程

    目录 Golang - 并发编程 1. 并行和并发 2. go语言并发优势 3. goroutine是什么 4. 创建goroutine 5. runtime包 6. channel是什么 7. ch ...

  5. 4种Golang并发操作中常见的死锁情形

    摘要:什么是死锁,在Go的协程里面死锁通常就是永久阻塞了,你拿着我的东西,要我先给你然后再给我,我拿着你的东西又让你先给我,不然就不给你.我俩都这么想,这事就解决不了了. 本文分享自华为云社区< ...

  6. golang并发编程

    golang并发编程 引子 golang提供了goroutine快速实现并发编程,在实际环境中,如果goroutine中的代码要消耗大量资源时(CPU.内存.带宽等),我们就需要对程序限速,以防止go ...

  7. 马蜂窝搜索基于 Golang 并发代理的一次架构升级

    搜索业务是马蜂窝流量分发的重要入口.很多用户在使用马蜂窝时,都会有目的性地主动搜索与自己旅行需求相关的各种信息,衣食住行,事无巨细,从而做出最符合需求的旅行决策. 因此在马蜂窝,搜索业务交互的下游模块 ...

  8. 批量写入redis

    批量写入redis key := GetSeriesKey(series.Id) idNames = append(idNames, key, series.Name) == { err = Mset ...

  9. lua模块demo(redis,http,mysql,cjson,本地缓存)

    1. lua模块demo(redis,http,mysql,cjson,本地缓存) 1.1. 配置 在nginx.conf中设置lua_shared_dict my_cache 128m; 开启ngi ...

随机推荐

  1. 重学c#系列——非托管实例(五)

    前言 托管资源到是好,有垃圾回收资源可以帮忙,即使需要我们的一些小小的调试来优化,也是让人感到欣慰的.但是非托管资源就显得苍白无力了,需要程序员自己去设计回收,同样有设计的地方也就能体现出程序员的设计 ...

  2. Kubernetes 教程:根据 PID 获取 Pod 名称

    原文链接:https://fuckcloudnative.io/posts/find-kubernetes-pod-info-from-process-id/ 在管理 Kubernetes 集群的过程 ...

  3. 彻底弄懂angularJS表单验证

    常用的表单验证指令 (基本概念) 1. 必填项验证 某个表单输入是否已填写,只要在输入字段元素上添加HTML5标记required即可: <input type="text" ...

  4. MySQL数据库常见命令

    数据库的操作 MySQL服务器的常见命令 开启:sudo service mysql start关闭:sudo service mysql stop重启:sudo service mysql rest ...

  5. 小甲鱼零基础汇编语言学习笔记第二章之寄存器(CPU工作原理,CPU内部通讯)

    这一章主要介绍了CPU中的重要器件——寄存器,整个系列通篇是以8086CPU作为探讨对象,其它更高级的CPU都是在此基础之上进行的升级.   1.一个典型的CPU是由运算器.控制器.寄存器等器件组成, ...

  6. P4463 [集训队互测2012] calc 拉格朗日插值 dp 多项式分析

    LINK:calc 容易得到一个nk的dp做法 同时发现走不通了 此时可以考虑暴力生成函数. 不过化简那套不太熟 且最后需要求多项式幂级数及多项式exp等难写的东西. 这里考虑观察优化dp的做法. 不 ...

  7. luogu P4008 [NOI2003]文本编辑器 splay 块状链表

    LINK:文本编辑器 这个东西感觉块状链表写细节挺多 (块状链表本来就难写 解释一下块状链表的做法:其实是一个个数组块 然后利用链表给链接起来 每个块的大小为sqrt(n). 这样插入删除的时候直接暴 ...

  8. linux的用户扩充权限管理acl和用户使用系统资源的限制

    用户扩充权限管理 acl 1.扩充权限的方式 文件扩充权限 ACL 磁盘配额 2.文件扩充权限 1.安全位 安全位   ---set位    SUID  SGID   set仅可以加给 u.g, 如: ...

  9. com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'user'

    nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'user' 可能错误原因: ...

  10. 解决IIS发布时CS0016未能写入输出文件错误

    今天遇到一个将asp.net项目部署到IIS后访问的时候报的一个错误: 在网上查询了相关资料后,解决方法如下: 找到C:\Windows\下的temp文件,右键属性>安全>编辑,给其中II ...