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 ...
随机推荐
- Java 异常处理专题,从入门到精通
内置异常和Throwable核心方法 Java内置异常 可查异常(必须要在方法里面捕获或者抛出) ClassNoFoundException 应⽤程序试图加载类,找不到对应的类 IllegalAcce ...
- Ansible部署zabbix-agent
playbook目录 zabbix/ ├── hosts ##定义的主机列表 ├── install_zabbix_agent.yml ##安装入口文件 └── roles ├── install_z ...
- python(xlsxwriter模块使用)
XlsxWriter简介XlsxWriter是一个Python模块,可用于在Excel 2007+ XLSX文件中写入多个工作表的文本,数字,公式和超链接.它支持格式化等功能.可到官网了解更多详情,官 ...
- java动态代理——字段和方法字节码的基础结构及Proxy源码分析三
前文地址:https://www.cnblogs.com/tera/p/13280547.html 本系列文章主要是博主在学习spring aop的过程中了解到其使用了java动态代理,本着究根问底的 ...
- IDEA 修改快捷键和Myeclipse 快捷键一致
介绍 我们知道IDEA这款开发工具功能很强大,为了简化开发步骤,提高开发效率,使用快捷键很显然是必不可少的,那么怎么才能使得IDEA快捷键和MyEclipse快捷键 保持相同呢? 第一种方法,一个快捷 ...
- Fortify Audit Workbench 笔记 Command Injection(命令注入)
Command Injection(命令注入) Abstract 执行不可信赖资源中的命令,或在不可信赖的环境中执行命令,都会导致程序以攻击者的名义执行恶意命令. Explanation Comman ...
- 第七章 vuex专题
一.Vuex安装 一般在创建项目是会选择 Vuex,如果没有选择: cnpm install vuex --save 使用: import Vuex from "vuex"; V ...
- PDOStatement::getAttribute
PDOStatement::getAttribute — 检索一个语句属性(PHP 5 >= 5.1.0, PECL pdo >= 0.2.0)高佣联盟 www.cgewang.com 说 ...
- 记502 dp专练
趁着503的清早 我还算清醒把昨天老师讲的内容总结一下,昨天有点迷了 至使我A的几道题都迷迷糊糊的.(可能是我太菜了) 这道题显然是 数字三角形的变形 好没有经过认真思考然后直接暴力了 这是很不应该的 ...
- Vue通过Blob对象实现导出Excel功能
不同的项目有不同的导出需求,有些只导出当前所显示结果页面的表格进入excel,这个时候就有很多插件,比如vue-json-excel或者是Blob.js+Export2Excel.js来实现导出Exc ...