吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1511|回复: 15
收起左侧

[资源求助] 求Go批量插入Redis10w、20w数据demo

[复制链接]
柯子 发表于 2022-1-18 18:41
100吾爱币
求一个大佬给个Go插入redis数据的Demo, 10w 50w这种级别的,尽量优雅一点的。没有大多要求,主要是模拟数据。

最佳答案

查看完整内容

[md]`redis_utils.go` 文件内容 ```golang package main import ( "github.com/go-redis/redis/v8" "math/rand" "sync" "time" "unsafe" ) func BatchInsert(size int, db int) { //start := time.Now() rdb := redis.NewClient(&redis.Options{ Addr: "localhost:49153", Password: "", // no password set DB: db, // use default DB }) //for i := 0; i < 100000; i++ { // ...

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Todd 发表于 2022-1-18 18:41

redis_utils.go 文件内容


package main

import (
    "github.com/go-redis/redis/v8"
    "math/rand"
    "sync"
    "time"
    "unsafe"
)

func BatchInsert(size int, db int) {
    //start := time.Now()
    rdb := redis.NewClient(&redis.Options{
        Addr:     "localhost:49153",
        Password: "", // no password set
        DB:       db, // use default DB
    })
    //for i := 0; i < 100000; i++ {
    //  err := rdb.Set(ctx, randStr(20), randStr(20), 0).Err()
    //  if err != nil {
    //      println(err)
    //      return
    //  }
    //}
    var wg sync.WaitGroup
    wg.Add(size)
    worker := NewDataWorker()
    go func() {
        for i := 0; i < size; i++ {
            go addData(worker, &wg)
        }
        // 等待生成完成,并且写入空对象
        wg.Wait()
        worker.JobChannel <- &DataProduction{}
    }()
    worker.Start(rdb)
    //end := time.Now()
    //useTime := end.Sub(start)
    //fmt.Println(useTime.String())

}

// addData 填充测试数据
func addData(worker DataWorker, wg *sync.WaitGroup) {

    // Generate a snowflake ID.
    for i := 0; i < 100000; i++ {
        worker.JobChannel <- NewDataProduction()
    }
    wg.Done()
}

// DataProduction 测试数据结构
type DataProduction struct {
    key   string
    value string
}

// NewDataProduction 生成测试数据方法
func NewDataProduction() *DataProduction {
    dp := DataProduction{
        key:   randStr(25),
        value: randStr(25),
    }
    return &dp
}

// ConsumptionData 消费数据
func (p DataProduction) ConsumptionData(rdb *redis.Client) {
    err := rdb.Set(ctx, p.key, p.value, 0).Err()
    if err != nil {
        panic(err)
    }
}

// DataWorker 工作对象
type DataWorker struct {
    JobChannel chan *DataProduction
}

// NewDataWorker 初始化工作对象
func NewDataWorker() DataWorker {
    return DataWorker{JobChannel: make(chan *DataProduction)}
}

func (w DataWorker) Start(rdb *redis.Client) {
    var wg sync.WaitGroup
    wg.Add(1)
    // 四协程
    //for i := 0; i < 4; i++ {
    go func(rdb *redis.Client, group *sync.WaitGroup) {
        for {
            select {
            case job := <-w.JobChannel:
                if job.key == "" {
                    //参考  如果为空,则说明已经生成完毕
                    group.Done()
                    return
                }
                job.ConsumptionData(rdb)

            }
        }
    }(rdb, &wg)
    //}
    // 等待数据消费完毕再退出
    wg.Wait()
}

// 随机字符串
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

var src = rand.NewSource(time.Now().UnixNano())

const (
    // 6 bits to represent a letter index
    letterIdBits = 6
    // All 1-bits as many as letterIdBits
    letterIdMask = 1<<letterIdBits - 1
    letterIdMax  = 63 / letterIdBits
)

func randStr(n int) string {
    b := make([]byte, n)
    // A rand.Int63() generates 63 random bits, enough for letterIdMax letters!
    for i, cache, remain := n-1, src.Int63(), letterIdMax; i >= 0; {
        if remain == 0 {
            cache, remain = src.Int63(), letterIdMax
        }
        if idx := int(cache & letterIdMask); idx < len(letters) {
            b[i] = letters[idx]
            i--
        }
        cache >>= letterIdBits
        remain--
    }
    return *(*string)(unsafe.Pointer(&b))
}

redis_utils_test.go 文件

package main

import (
    "testing"
)

func TestBatchInsert(t *testing.T) {
    tests := []struct {
        name string
        size int
        db   int
    }{
        {
            name: "10W",
            size: 1,
            db:   0,
        },
        {
            name: "20W",
            size: 2,
            db:   1,
        },
        {
            name: "50W",
            size: 5,
            db:   2,
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            BatchInsert(tt.size, tt.db)
        })
    }
}
多谢楼主让我复习了一遍golang

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
柯子 + 1 + 1 用心讨论,共获提升!

查看全部评分

qiqi2050352 发表于 2022-1-18 19:40
放弃吧,我问个MySQL的批量插入都没人理,更别说你这个了,自己研究吧
njbb888 发表于 2022-1-18 19:51
qiqi2050352 发表于 2022-1-18 19:40
放弃吧,我问个MySQL的批量插入都没人理,更别说你这个了,自己研究吧

多少CB ?
8core45153386 发表于 2022-1-18 20:21
直接用框架,起goroutine
https://goframe.org/pages/viewpage.action?pageId=1114154#Redis%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8-%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8.1
gaffey 发表于 2022-1-18 20:45
数据保存为文本文件,用 redis pipeline 方式插入

[Shell] 纯文本查看 复制代码
cat data.txt | redis-cli --pipe
薄荷叶1996 发表于 2022-1-18 21:23
emmmm 不太清楚~
EnterpriseSolu 发表于 2022-1-19 08:39
for(int i=1; i< 200000000, i++)
{
    //执行增加一行redis记录
}
浣熊 发表于 2022-1-19 08:45
本帖最后由 浣熊 于 2022-1-19 09:32 编辑
EnterpriseSolu 发表于 2022-1-19 08:39
for(int i=1; i< 200000000, i++)
{
    //执行增加一行redis记录

这个非常Nice,简单明了【手动狗头】
 楼主| 柯子 发表于 2022-1-19 09:24
浣熊 发表于 2022-1-19 08:45
这个非常Nice,简单明了

你这执行太慢了
快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-27 06:06

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表