首页 > 数据库 >Golang+Gin+ Redis Cluster

Golang+Gin+ Redis Cluster

时间:2023-03-07 11:48:12浏览次数:40  
标签:strconv err Redis redis Golang go Gin localhost

最近用redis shake做redis数据迁移,由于redis提供的客户端没有用于查看集群的工具,且我部署的redis集群是基于k8s来构建的,没有使用ingress做转发,所以只能在k8s内部访问集群,于是我先用go+gin框架编写了访问redis集群的代码,然后打成镜像,再部署到k8s中,创建一个svc类型为NodePort方便外部访问。

环境搭建完毕后,访问接口,发现连接redis集群失败,报错:

dial tcp: lookup redis-cluster-v2-0.redis-cluster-v2.redis: i/o timeout

我尝试在容器内部ping | telnet redis集群某一结点地址,发现网络是可通的,后面在代码中新增net.dail()去连接redis集群,报另一个错误:

 got 4 elements in cluster info address, expected 2 or 3

发现使用的go redis版本与redis的版本不一致造成的,

  • Redis 6.0及以下版本:选择Go-redis v8.0及以下版本。

  • Redis 7.0及以上版本:选择Go-redis v9.0及以上版本。

由于我部署的redis集群是7.0,但go redis使用的版本是 v8["github.com/go-redis/redis/v8"],于是修改go redis版本:

"github.com/redis/go-redis/v9"
package main

import (
    "context"
    "fmt"
    "github.com/redis/go-redis/v9"
    "strconv"
    "testing"
    "time"
)

func TestRedis(t *testing.T) {
    client := redis.NewClusterClient(&redis.ClusterOptions{
        Addrs: []string{
            "localhost:6371",
            "localhost:6372",
            "localhost:6373",
            "localhost:6374",
            "localhost:6375",
            "localhost:6376",
        },
        Password:      "ruiec.com", // 在这里设置你的Redis实例密码
        RouteRandomly: true,        // 启用随机路由,以实现负载均衡
    })
    // 记录开始时间
    start := time.Now()
    for i := 0; i < 100000; i++ {
        // 使用客户端发送Redis命令
        ctx := context.Background()
        err := client.Set(ctx, "name"+strconv.Itoa(i), "张三"+strconv.Itoa(i), 0).Err()
        if err != nil {
            panic(err)
        }

        val, err := client.Get(ctx, "name"+strconv.Itoa(i)).Result()
        if err != nil {
            panic(err)
        }
        fmt.Println("key", val)
    }
    // 记录结束时间
    end := time.Now()
    // 打印代码运行时长
    fmt.Printf("TestRedis代码运行时长: %v\n", end.Sub(start))
}

使用协程的方式:

package main

import (
    "context"
    "fmt"
    "github.com/redis/go-redis/v9"
    "strconv"
    "sync"
    "testing"
    "time"
)

func TestGoroutineRedis(t *testing.T) {
    client := redis.NewClusterClient(&redis.ClusterOptions{
        Addrs: []string{
            "localhost:6371",
            "localhost:6372",
            "localhost:6373",
            "localhost:6374",
            "localhost:6375",
            "localhost:6376",
        },
        Password:      "1234", // 在这里设置你的Redis实例密码
        RouteRandomly: true,        // 启用随机路由,以实现负载均衡
    })
    // 记录开始时间
    start := time.Now()
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go insertGoroutineRedis(client, &wg)
    }
    wg.Wait()
    // 记录结束时间
    end := time.Now()
    // 打印代码运行时长
    fmt.Printf("insertGoroutineRedis代码运行时长: %v\n", end.Sub(start))
}
func insertGoroutineRedis(client *redis.ClusterClient, wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 100000; i++ {
        // 使用客户端发送Redis命令
        ctx := context.Background()
        err := client.Set(ctx, "name"+strconv.Itoa(i), "张三"+strconv.Itoa(i), 0).Err()
        if err != nil {
            panic(err)
        }

        val, err := client.Get(ctx, "name"+strconv.Itoa(i)).Result()
        if err != nil {
            panic(err)
        }
        fmt.Println("key", val)
    }
}

使用协程+通道方式

package main

import (
    "context"
    "fmt"
    "github.com/redis/go-redis/v9"
    "strconv"
    "sync"
    "testing"
    "time"
)

func TestGoroutineChannelRedis(t *testing.T) {
    client := redis.NewClusterClient(&redis.ClusterOptions{
        Addrs: []string{
            "localhost:6371",
            "localhost:6372",
            "localhost:6373",
            "localhost:6374",
            "localhost:6375",
            "localhost:6376",
        },
        Password:      "1234", // 在这里设置你的Redis实例密码
        RouteRandomly: true,        // 启用随机路由,以实现负载均衡
    })
    // 记录开始时间
    start := time.Now()
    fmt.Println(start)
    var wg sync.WaitGroup
    // 创建一个缓冲channel,用于并发插入数据
    ch1 := make(chan int, 1000000)
    // 将100000个值放入channel中
    for i := 0; i < 1000000; i++ {
        ch1 <- i
    }
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            for j := 0; j < 100000; j++ {
                // 从channel中取出一个值插入到Redis Cluster中
                key := <-ch1
                // 使用客户端发送Redis命令
                ctx := context.Background()
                err := client.Set(ctx, "name"+strconv.Itoa(key), "张三"+strconv.Itoa(key), 0).Err()
                if err != nil {
                    fmt.Println("Error inserting value:", err)
                }
            }
        }()
    }
    close(ch1)
    wg.Wait()
    // 记录结束时间
    end := time.Now()
    fmt.Println(end)
    // 打印代码运行时长
    fmt.Printf("insertGoroutineChannelRedis代码运行时长: %v\n", end.Sub(start))
}

 

标签:strconv,err,Redis,redis,Golang,go,Gin,localhost
From: https://www.cnblogs.com/lwhzj/p/17187483.html

相关文章

  • 项目实战总结《模拟gin写一个web框架gee》
    概述:gee框架使用了前缀树算法来匹配路由,实现了路由分组,继承了gin的上下文写法,封装了常用的jsion,html,string,实现了服务端渲染,用钩子函数实现了中间件。项目的难度偏入门......
  • docker-compose搭建redis集群
    1、编写Redis配置文件#创建目录mkdir-p/home/docker/docker-redis/redis-cluster#切换至指定目录cd/home/docker/docker-redis/redis-cluster/#编写re......
  • vulnhub靶场之HARRYPOTTER: NAGINI
    准备:攻击机:虚拟机kali、本机win10。靶机:HarryPotter:Nagini,下载地址:https://download.vulnhub.com/harrypotter/Nagini.ova,下载后直接vbox打开即可。知识点:shell反弹、......
  • 单例模式应用于login-加装饰器
     importrandomdefsingleton(class_):instances={}defget_instance(*args,**kwargs):ifclass_notininstances:instances[cl......
  • 在Linux和Unix上隐藏Nginx版本
    使用CLI显示当前Nginx版本Nginx将在错误页面和“服务器”响应标头字段中显示版本。我们可以使用以下命令进行验证:示例输出:$curl-Ihttps://your-domain$curl-I......
  • golang 升级 1.16.3 之后,编译报错 missing go.sum entry for module providing packag
    问题现象在开发机上升级到了最新golang1.16.3版本,在为一个基于golang1.13的历史项目添加excel依赖包后gogetgithub.com/360EntSecGroup-Skylar/excelize/v2......
  • 11_Redis
    Redis【简介&安装篇】-知乎(zhihu.com)【1】什么是redis,谈谈你对redis的理解redis就是一个数据库,不过与传统数据库不同的是,redis的数据是key-value存储在内存中的,......
  • 10_Nginx
    Nginx有什么用反向代理、缓存、负载均衡。功能1:反向代理背景:随着访问流量的不断增加,系统不足以支持时,可以对系统进行横向扩展,即增加服务节点,比如说从1个服务节点,增加的2......
  • nginx部署前端项目-location root与 alias区别
    1、locationroot:/path/uri(把匹配的路径追加到配置的路径:/demoProject追加到/usr/local/nginx/front/apps/demo)/demoProject{root/usr/local/nginx......
  • huggingface三种添加模型的方法
    首先搞清楚预训练模型一般会有的文件:vocab.txtconfig.jsonpytorch_model.bin这三个分别对应tokenizer,config和model。添加huggingfacehub里面的模型只要有模型名......