• Go语言中操作Redis


    Redis介绍

    Redis是一个开源的内存数据库,Redis提供了多种不同类型的数据结构,很多业务场景下的问题都可以很自然地映射到这些数据结构上。 除此之外,通过复制、持久化和客户端分片等特性,我们可以很方便地将Redis扩展成一个能够包含数百GB数据、每秒处理上百万次请求的系统

    Redis支持的数据结构

    Redis支持诸如字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、带范围查询的排序集合(sorted sets)、位图(bitmaps)、hyperloglogs、带半径查询和流的地理空间索引等数据结构(geospatial indexes)。

    Redis应用场景

    • 缓存系统,减轻主数据库(MySQL)的压力。
    • 计数场景,比如微博、抖音中的关注数和粉丝数。
    • 热门排行榜,需要排序的场景特别适合使用ZSET。
    • 利用LIST可以实现队列的功能。

    准备Redis环境

    1 下载安装包!redis-5.0.8.tar.gz
    2 解压Redis的安装包!程序一般放在 /opt 目录下
    在这里插入图片描述
    3 . 进入解压后的文件,可以看到我们redis的配置文件

    在这里插入图片描述
    4. 基本的环境安装命令

    yum install gcc-c++
    #然后进入redis目录下执行
    make
    #然后执行
    make install
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这里make命令输入之后, 需要等待一段时间.
    5. redis默认安装路径 /usr/local/bin
    在这里插入图片描述
    6. 将redis的配置文件复制到 程序安装目录 /usr/local/bin/kconfig下(这个kconfig文件夹可以自己创建一个)

    在这里插入图片描述

    关于连接阿里云服务器的注意事项

    golang安装

    区别于另一个比较常用的Go语言redis client库:redigo,我们这里采用https://github.com/go-redis/redis连接Redis数据库并进行操作,因为支持连接哨兵及集群模式的Redis。go-redis

    使用以下命令下载并安装:

    go get -u github.com/go-redis/redis
    
    • 1

    普通连接

    // 声明一个全局的rdb变量
    var rdb *redis.Client
    
    // 初始化连接
    func initClient() (err error) {
    	rdb = redis.NewClient(&redis.Options{
    		Addr:     "localhost:6379",
    		Password: "", // no password set
    		DB:       0,  // use default DB
    	})
    
    	_, err = rdb.Ping().Result()
    	if err != nil {
    		return err
    	}
    	return nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    连接Redis哨兵模式

    func initClient()(err error){
    	rdb := redis.NewFailoverClient(&redis.FailoverOptions{
    		MasterName:    "master",
    		SentinelAddrs: []string{"x.x.x.x:26379", "xx.xx.xx.xx:26379", "xxx.xxx.xxx.xxx:26379"},
    	})
    	_, err = rdb.Ping().Result()
    	if err != nil {
    		return err
    	}
    	return nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    连接Redis集群

    func initClient()(err error){
    	rdb := redis.NewClusterClient(&redis.ClusterOptions{
    		Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},
    	})
    	_, err = rdb.Ping().Result()
    	if err != nil {
    		return err
    	}
    	return nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    基本使用

    set/get示例

    func redisExample() {
    	err := rdb.Set("score", 100, 0).Err()
    	if err != nil {
    		fmt.Printf("set score failed, err:%v\n", err)
    		return
    	}
    
    	val, err := rdb.Get("score").Result()
    	if err != nil {
    		fmt.Printf("get score failed, err:%v\n", err)
    		return
    	}
    	fmt.Println("score", val)
    
    	val2, err := rdb.Get("name").Result()
    	if err == redis.Nil {
    		fmt.Println("name does not exist")
    	} else if err != nil {
    		fmt.Printf("get name failed, err:%v\n", err)
    		return
    	} else {
    		fmt.Println("name", val2)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    zset示例

    func redisExample() {
    	err := rdb.Set("score", 100, 0).Err()
    	if err != nil {
    		fmt.Printf("set score failed, err:%v\n", err)
    		return
    	}
    
    	val, err := rdb.Get("score").Result()
    	if err != nil {
    		fmt.Printf("get score failed, err:%v\n", err)
    		return
    	}
    	fmt.Println("score", val)
    
    	val2, err := rdb.Get("name").Result()
    	if err == redis.Nil {
    		fmt.Println("name does not exist")
    	} else if err != nil {
    		fmt.Printf("get name failed, err:%v\n", err)
    		return
    	} else {
    		fmt.Println("name", val2)
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    管道

    Pipeline主要是一种网络优化。 它本质上意味着客户端缓冲一堆命令并一次性将它们发送到服务器。 这些命令不能保证在事务中执行。 这样做的好处是节省了每个命令的网络往返时间(RTT)。

    Pipeline 基本示例如下:

    pipe := rdb.Pipeline()
    
    incr := pipe.Incr("pipeline_counter")
    pipe.Expire("pipeline_counter", time.Hour)
    
    _, err := pipe.Exec()
    fmt.Println(incr.Val(), err)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    上面的代码相当于将以下两个命令一次发给redis server端执行,与不使用相比能减少一次RTT。Pipeline

    INCR pipeline_counter
    EXPIRE pipeline_counts 3600
    
    • 1
    • 2

    也可以使用:Pipelined

    var incr *redis.IntCmd
    _, err := rdb.Pipelined(func(pipe redis.Pipeliner) error {
    	incr = pipe.Incr("pipelined_counter")
    	pipe.Expire("pipelined_counter", time.Hour)
    	return nil
    })
    fmt.Println(incr.Val(), err)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在某些场景下,当我们有多条命令要执行时,就可以考虑使用pipeline来优化。

    注意

    如果使用Pipeline是前一个命令和后一个命令存在了依赖关系就不要使用Pipeline,就是前一个查询的结果后一个要用的情况下

  • 相关阅读:
    【数据库】如何利用Python中的petl将PostgreSQL中所有表的外键删除,迁移数据,再重建外键
    云原生丨5大Datadog集成,快速提高团队效率!
    【智慧工地源码】物联网和传感器技术在智慧工地的应用
    QT程序打包
    【前端】Vue网络应用
    Chapter006-FPGA学习之LCD显示
    第四章 文件管理 四、文件的物理结构(文件分配方式)
    Java面试+笔试题大集合
    2022年武汉市仿制药一致性评价政策性奖励申报条件要求以及奖补措施!
    抽象类和接口
  • 原文地址:https://blog.csdn.net/ZN175623/article/details/128029016