【11】Redis快速安装与Golang实战指南

news2025/4/11 23:32:16

文章目录

  • 1 Redis 基础与安装部署
    • 1.1 Redis 核心特性解析
    • 1.2 Docker Compose 快速部署
    • 1.3 Redis 本地快速部署
  • 2 Golang 与 Redis 集成实战
    • 2.1 环境准备与依赖安装
    • 2.2 核心操作与数据结构实践
      • 2.2.1 基础键值操作
      • 2.2.2 哈希结构存储用户信息
  • 3 生产级应用场景实战
    • 3.1 分布式锁实现(Redlock 算法)
    • 3.2 实时计数器设计
  • 4 性能优化与最佳实践
    • 4.1 连接池配置优化
    • 4.2 数据序列化方案对比
  • 5 总结与扩展方向

1 Redis 基础与安装部署

1.1 Redis 核心特性解析

Redis 作为内存型键值数据库,以其高性能、多数据结构支持和丰富特性,成为现代应用开发的重要组件。其核心功能包括:

  • 丰富的数据结构支持
    Redis 支持多种数据结构,如字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)。

    • 字符串常用于缓存简单数据或计数;
    • 哈希适合存储对象;
    • 列表可实现队列或栈;
    • 集合用于去重和集合运算;
    • 有序集合常用于排行榜等需要排序的场景。
  • 原子操作与事务支持
    Redis 的操作具有原子性,确保数据的一致性。同时提供简单的事务功能,能将多个命令打包成一个原子操作执行,使用 MULTIEXECDISCARDWATCH 等命令来管理事务。
    例如:

    MULTI
    SET key1 value1
    SET key2 value2
    EXEC
    
  • 持久化(RDB/AOF)与主从复制
    Redis 提供 RDB(Redis Database)和 AOF(Append Only File)两种持久化机制:

    • RDB 通过生成数据快照来保存数据,适合快速恢复;
    • AOF 通过记录写操作日志来持久化数据,数据完整性更高。
      主从复制功能允许将主节点的数据复制到多个从节点,实现读写分离和数据备份。
  • 发布订阅、地理空间索引等扩展功能

    • 发布订阅功能支持实时消息系统;
    • 地理空间索引功能支持存储和查询地理位置信息。

1.2 Docker Compose 快速部署

通过 Docker 容器化部署 Redis,可实现环境隔离与版本控制。以下是使用 Docker Compose 部署 Redis 的步骤:

  1. 安装 Docker 和 Docker Compose
    确保系统已安装 Docker 和 Docker Compose,未安装时根据官方文档安装。

  2. 创建 docker-compose.yml 文件

    version: '3'
    services:
      redis:
        image: redis:latest
        container_name: my_redis
        command: redis-server --appendonly yes
        restart: always
        ports:
          - "6379:6379"
        volumes:
          - ./data:/data
    
  3. 启动服务
    docker-compose.yml 目录执行:

    docker-compose up -d
    
    • 端口映射:将容器内的 6379 端口映射到宿主机。
    • 数据持久化:挂载 /data 目录确保数据持久化。
    • 开启 AOF:通过 --appendonly yes 保证数据安全性。

1.3 Redis 本地快速部署

在本地部署 Redis 的步骤如下:

  1. 下载与解压
    从 Redis 官方网站 下载最新稳定版本,解压到目标目录(如 /usr/local/redis)。

  2. 编译安装

    make
    make install
    
  3. 配置 Redis
    复制 redis.conf 到安装目录,修改配置项(如绑定 IP、设置密码、开启持久化):

    bind 0.0.0.0
    requirepass your_password
    appendonly yes
    
  4. 启动与验证

    redis-server redis.conf
    redis-cli ping  # 应返回 PONG
    

2 Golang 与 Redis 集成实战

2.1 环境准备与依赖安装

  1. 安装 Go 语言
    确保已安装 Go 并配置环境变量。

  2. 安装 Redis 客户端库

    go get -u github.com/go-redis/redis/v9
    
  3. 创建客户端实例

    package main
    
    import (
        "context"
        "fmt"
        "github.com/go-redis/redis/v9"
    )
    
    var ctx = context.Background()
    
    func main() {
        rdb := redis.NewClient(&redis.Options{
            Addr:     "localhost:6379",
            Password: "",
            DB:       0,
        })
    
        pong, err := rdb.Ping(ctx).Result()
        if err != nil {
            fmt.Printf("Could not connect to Redis: %v\n", err)
            return
        }
        fmt.Println(pong) // 输出: PONG
    }
    

2.2 核心操作与数据结构实践

2.2.1 基础键值操作

// 设置键值对(永不过期)
err := rdb.Set(ctx, "name", "John", 0).Err()

// 获取键值对
val, err := rdb.Get(ctx, "name").Result()

// 删除键值对
err = rdb.Del(ctx, "name").Err()

2.2.2 哈希结构存储用户信息

type User struct {
    ID   int
    Name string
    Age  int
}

// 存储用户信息到 Redis 哈希
func SetUser(rdb *redis.Client, user User) error {
    return rdb.HSet(ctx, fmt.Sprintf("users:%d", user.ID), "name", user.Name, "age", user.Age).Err()
}

// 从 Redis 哈希获取用户信息
func GetUser(rdb *redis.Client, id int) (User, error) {
    user := User{ID: id}
    name, err := rdb.HGet(ctx, fmt.Sprintf("users:%d", id), "name").Result()
    if err != nil {
        return user, err
    }
    ageStr, err := rdb.HGet(ctx, fmt.Sprintf("users:%d", id), "age").Result()
    fmt.Sscanf(ageStr, "%d", &user.Age)
    return user, nil
}

3 生产级应用场景实战

3.1 分布式锁实现(Redlock 算法)

package main

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

const (
    lockKey      = "my_distributed_lock"
    lockValue    = "unique_value_12345"
    lockTimeout  = 5 * time.Second
    retryTimeout = 1 * time.Second
)

func main() {
    rdb1 := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
    rdb2 := redis.NewClient(&redis.Options{Addr: "localhost:6380"})
    rdb3 := redis.NewClient(&redis.Options{Addr: "localhost:6381"})

    success, err := tryLock(ctx, []*redis.Client{rdb1, rdb2, rdb3}, lockKey, lockValue, lockTimeout, retryTimeout)
    if err != nil || !success {
        fmt.Println("Lock acquisition failed")
        return
    }
    defer unlock(ctx, []*redis.Client{rdb1, rdb2, rdb3}, lockKey, lockValue)

    fmt.Println("Performing critical operations...")
    time.Sleep(3 * time.Second)
}

func tryLock(ctx context.Context, clients []*redis.Client, key, value string, lockTimeout, retryTimeout time.Duration) (bool, error) {
    startTime := time.Now()
    var successCount int
    for _, client := range clients {
        ok, err := client.SetNX(ctx, key, value, lockTimeout).Result()
        if err != nil {
            return false, err
        }
        if ok {
            successCount++
        }
        if successCount >= len(clients)/2+1 || time.Since(startTime) > retryTimeout {
            break
        }
    }
    return successCount >= len(clients)/2+1, nil
}

func unlock(ctx context.Context, clients []*redis.Client, key, value string) {
    for _, client := range clients {
        client.Del(ctx, key)
    }
}

3.2 实时计数器设计

// 原子性递增计数器
func incrementCounter(ctx context.Context, rdb *redis.Client, key string) error {
    _, err := rdb.Incr(ctx, key).Result()
    return err
}

// 获取计数器值
func getCounterValue(ctx context.Context, rdb *redis.Client, key string) (int64, error) {
    return rdb.Get(ctx, key).Int64()
}

// 带过期时间的原子操作(使用 Lua 脚本)
func incrementAndSetExpiry(ctx context.Context, rdb *redis.Client, key string, expiry time.Duration) error {
    script := `
        local value = redis.call('INCR', KEYS[1])
        redis.call('EXPIRE', KEYS[1], ARGV[1])
        return value
    `
    _, err := rdb.Eval(ctx, script, []string{key}, int(expiry.Seconds())).Result()
    return err
}

4 性能优化与最佳实践

4.1 连接池配置优化

rdb := redis.NewClient(&redis.Options{
    Addr:         "localhost:6379",
    PoolSize:     100,   // 最大连接数
    MinIdleConns: 10,    // 最小空闲连接数
    IdleTimeout:  5 * time.Minute, // 空闲连接超时时间
})

4.2 数据序列化方案对比

方案优点缺点推荐场景
JSON可读性强、跨语言支持体积大、性能低简单场景、调试需求
Msgpack体积小、性能较高不可读、调试困难对性能和空间有一定要求的场景
Protobuf体积最小、性能最高代码生成复杂、不可读高性能、大规模数据存储

Protobuf 示例

  1. 定义 user.proto

    syntax = "proto3";
    
    package main;
    
    message User {
        int32 id = 1;
        string name = 2;
        int32 age = 3;
    }
    
  2. 生成代码:

    protoc --go_out=. user.proto
    
  3. 使用示例:

    import (
        "google.golang.org/protobuf/proto"
        pb "your_package_path"
    )
    
    user := &pb.User{Id: 1, Name: "John", Age: 30}
    data, err := proto.Marshal(user)
    err = rdb.Set(ctx, "user:1", data, 0).Err()
    
    val, err := rdb.Get(ctx, "user:1").Bytes()
    var newUser pb.User
    proto.Unmarshal(val, &newUser)
    

5 总结与扩展方向

通过本指南,读者已掌握 Redis 的快速部署与基础操作,以及 Golang 与 Redis 的深度集成。建议进一步探索以下方向:

  • Redis Cluster 集群部署
  • AOF 重写与 RDB 快照策略
  • Redis Stream 消息队列
  • 结合 Prometheus 实现监控报警

通过这些扩展学习,可构建高性能、可扩展的现代应用系统,满足从简单缓存到复杂分布式系统的多层次需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2330263.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】图论存储革新:十字链表双链设计高效解决有向图入度查询难题

十字链表 导读一、邻接表的优缺点二、十字链表2.1 结点结构2.2 原理解释2.2.1 顶点表2.2.2 边结点2.2.3 十字链表 三、存储结构四、算法评价4.1 时间复杂度4.2 空间复杂度 五、优势与劣势5.1 优势5.2 劣势5.3 特点 结语 导读 大家好,很高兴又和大家见面啦&#xff…

.net6 中实现邮件发送

一、开启邮箱服务 先要开启邮箱的 SMTP 服务,获取授权码,在实现代码发送邮件中充当邮箱密码用。 在邮箱的 设置 > 账号 > POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务中,把 SMTP 服务开启,获取授权码。 二、安装库 安装 …

【Linux】命令和权限

目录: 一、shell命令及运行原理 (一)什么是外壳 (二)为什么要有外壳 (三)外壳怎么工作的 二、Linux权限的概念 (一)Linux的文件类型 (二)L…

22.OpenCV轮廓匹配原理介绍与使用

OpenCV轮廓匹配原理介绍与使用 1. 轮廓匹配的基本概念 轮廓匹配(Contour Matching)是计算机视觉中的一种重要方法,主要用于比较两个轮廓的相似性。它广泛应用于目标识别、形状分析、手势识别等领域。 在 OpenCV 中,轮廓匹配主要…

深入解析AI绘画技术背后的人工智能

在当今数字艺术领域,AI绘画作为一种新兴艺术形式,正迅速吸引着越来越多的创作者与爱好者。它不仅推动了艺术创作的边界,同时也改变了我们对创作与美的理解。本文将深入探讨AI绘画所依赖的人工智能技术,并分析其背后的原理与应用。…

browser-use开源程序使 AI 代理可以访问网站,自动完成特定的指定任务,告诉您的计算机该做什么,它就会完成它。

一、软件介绍 文末提供程序和源码下载 browser-use开源程序使 AI 代理可以访问网站,自动完成特定的指定任务,浏览器使用是将AI代理与浏览器连接的最简单方法。告诉您的计算机该做什么,它就会完成它。 二、快速开始 使用 pip (Py…

java虚拟机---JVM

JVM JVM,也就是 Java 虚拟机,它最主要的作用就是对编译后的 Java 字节码文件逐行解释,翻译成机器码指令,并交给对应的操作系统去执行。 JVM 的其他特性有: JVM 可以自动管理内存,通过垃圾回收器回收不再…

2025数字中国初赛wp

一,取证与溯源 镜像文件解压密码:44216bed0e6960fa 1.运维人员误删除了一个重要的word文件,请通过数据恢复手段恢复该文件,文件内容即为答案。 先用R-stuido软件进行数据恢复 得到 打开重要文件.docx全选发现有一条空白的被选中…

c#和c++脚本解释器科学运算

说明: 我希望用c#和c写一个脚本解释器,用于科学运算 效果图: step1: c# C:\Users\wangrusheng\RiderProjects\WinFormsApp3\WinFormsApp3\Form1.cs using System; using System.Collections.Generic; using System.Data; using System.Tex…

青蛙吃虫--dp

1.dp数组有关元素--路长和次数 2.递推公式 3.遍历顺序--最终影响的是路长&#xff0c;在外面 其次次数遍历&#xff0c;即这次路长所有情况都更新 最后&#xff0c;遍历次数自然就要遍历跳长 4.max时时更新 dp版本 #include<bits/stdc.h> using namespace std; #def…

LINUX 5 cat du head tail wc 计算机拓扑结构 计算机网络 服务器 计算机硬件

计算机网络 计算机拓扑结构 计算机按性能指标分&#xff1a;巨型机、大型机、小型机、微型机。大型机、小型机安全稳定&#xff0c;小型机用于邮件服务器 Unix系统。按用途分&#xff1a;专用机、通用机 计算机网络&#xff1a;局域网‘、广域网 通信协议’ 计算机终端、客户端…

ModuleNotFoundError: No module named ‘pandas‘

在使用Python绘制散点图表的时候&#xff0c;运行程序报错&#xff0c;如图&#xff1a; 报错显示Python 环境中可能没有安装 pandas 库&#xff0c;执行pip list命令查看&#xff0c;果然没有安装pandas 库&#xff0c;如图&#xff1a; 执行命令&#xff1a;python -m pip in…

【教程】MacBook 安装 VSCode 并连接远程服务器

目录 需求步骤问题处理 需求 在 Mac 上安装 VSCode&#xff0c;并连接跳板机和服务器。 步骤 Step1&#xff1a;从VSCode官网&#xff08;https://code.visualstudio.com/download&#xff09;下载安装包&#xff1a; Step2&#xff1a;下载完成之后&#xff0c;直接双击就能…

Unet网络的Pytorch实现和matlab实现

文章目录 一、Unet网络简介1.1 输入图像1.2 编码器部分&#xff08;Contracting Path&#xff09;1.3 解码器部分&#xff08;Expanding Path&#xff09;1.4 最后一层&#xff08;输出&#xff09;1.5 跳跃连接&#xff08;Skip Connections&#xff09; 二、Unet网络的Pytorc…

【合新通信】相控阵雷达RFoF方案的应用

一、相控阵雷达为何需要RFoF&#xff1f; 核心需求驱动 分布式部署&#xff1a;相控阵雷达&#xff08;AESA/PESA&#xff09;的T/R模块需分散布局&#xff08;如舰载雷达阵面、卫星载荷&#xff09;&#xff0c;传统同轴电缆导致重量和损耗剧增。高频段挑战&#xff1a;X/Ku/…

原理图输出网表及调入

一、输出网表操作步骤 &#xff08;1&#xff09;选中.dsn文件&#xff0c;选者N或进入tools下拉列表选择Creat Netlists &#xff08;2&#xff09;导出网表后的文件 二、网表的导入 &#xff08;1&#xff09;执行菜单命令“File-Import-Logic/netlist”&#xff0c;将原理…

TDengine JAVA 语言连接器

简介 本节简介 TDengine 最重要且使用最多的连接器, 本节内容是以教科书式方式列出对外提供的接口及功能及使用过程中要注意的技术细节&#xff0c;大家可以收藏起来做为今后开发 TDengine 的参考资料。 taos-jdbcdriver 是 TDengine 的官方 Java 语言连接器&#xff0c;Java…

【NLP 55、实践 ⑬ LoRA完成NER任务】

目录 一、数据文件 二、模型配置文件 config.py 三、数据加载文件 loader.py 1.导入文件和类的定义 2.初始化 3.数据加载方法 代码运行流程 4.文本编码 / 解码方法    ① encode_sentence()&#xff1a; ② decode()&#xff1a; 代码运行流程 ③ padding()&#xff1a; 代码…

【蓝桥杯】Python大学A组第十五届省赛

1.填空题 1.1.拼正方形 问题描述 小蓝正在玩拼图游戏,他有个的方块和个的方块,他需要从中挑出一些来拼出一个正方形。 比如用个和个的方块可以拼出一个的正方形;用个的方块可以拼出一个的正方形。 请问小蓝能拼成的最大的正方形的边长为多少。 import math # 2*2的个数 a =…

小球反弹(蓝桥杯C语言)

有一长方形&#xff0c;长为 343720343720 单位长度&#xff0c;宽为 233333233333 单位长度。在其内部左上角顶点有一小球 (无视其体积)&#xff0c;其初速度如图所示且保持运动速率不变&#xff0c;分解到长宽两个方向上的速率之比为 dx:dy15:17dx:dy15:17。小球碰到长方形的…