您的位置 首页 知识

go-redisgo中redis使用的示例代码

目录
  • 一、Redis 简介
  • 二、Go中Redis的使用
    • 1. 安装Go Redis包
    • 2. 单机模式
    • 3. 哨兵模式
  • 三、Redis集群
    • 1. 集群模式
  • 四、常用数据结构与操作
    • 1. 字符串(String)
    • 2. 哈希(Hash)
    • 3. 列表(List)
    • 4. 集合(Set)
    • 5. 有序集合(ZSet)
  • 五、事务与批量操作
    • 1. 事务
    • 2. 管道技术
  • 六、高可用性
    • 1. 复制(主从)
    • 2. 故障转移
    • 3. 连接池
  • 七、监控与性能调优
    • 1. 内置工具
    • 2. 性能指标
    • 3. 调试
  • 八、实际案例
    • 1. 高并发秒杀体系
    • 说明
  • 九、最佳操作
    • 1. 数据过期时刻
    • 2. 内存管理
    • 3. 日志配置
    • 4. 安全性
    • 5. 监控
    • 6. 备份恢复
    • 7. 连接池管理
    • 8. 数据持久化
  • 十、拓展资料

    在Go语言中使用Redis进行数据存储和管理可以带来高效和灵活的优势。下面的讲解包括单机模式、哨兵模式和集群模式的部署及使用。

    一、Redis 简介

    Redis一个高性能的内存数据库,支持多种数据结构,如字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(ZSet)等。它还支持事务、批量操作和流式数据处理。Redis常用于缓存、实时数据处理、计数器、消息队列等场景。

    二、Go中Redis的使用

    1. 安装Go Redis包

    推荐使用github.com/go-redis/redis/v9,它支持单机、哨兵和集群模式。

    安装命令:

    go get github.com/go-redis/redis/v9

    2. 单机模式

    特点:单一Redis实例,简单易用,适合开发和测试环境。

    连接示例

    package mainimport ( “context” “fmt” “github.com/go-redis/redis/v9”)func main() ctx := context.Background() client := redis.NewClient(&redis.Options Addr: “localhost:6379”, Password: “”, DB: 0, }) pong, err := client.Ping(ctx).Result() if err != nil fmt.Printf(“连接失败:%vn”, err) return } fmt.Println(pong) // 输出:PONG // 示例:设置和获取值 if err := client.Set(ctx, “key”, “value”, 0).Err(); err != nil fmt.Printf(“设置失败:%vn”, err) return } val, err := client.Get(ctx, “key”).Result() if err != nil fmt.Printf(“获取失败:%vn”, err) return } fmt.Printf(“值:%vn”, val)}

    说明

    • 使用redis.NewClient创建客户端。
    • 使用Ping测试连接。
    • Set设置键值,Get读取值。

    3. 哨兵模式

    特点:提供高可用性,当主库故障时,自动故障转移。

    依赖

    • 必须安装Redis哨兵服务。

    连接示例

    package mainimport ( “context” “fmt” “github.com/go-redis/redis/v9”)func main() ctx := context.Background() client := redis.NewFailoverClient(&redis.FailoverOptions MasterName: “mymaster”, SentinelAddrs: []string”localhost:26379″, “localhost:26380”, “localhost:26381”}, }) pong, err := client.Ping(ctx).Result() if err != nil fmt.Printf(“连接失败:%vn”, err) return } fmt.Println(pong) // 示例:设置和获取值 if err := client.Set(ctx, “key”, “value”, 0).Err(); err != nil fmt.Printf(“设置失败:%vn”, err) return } val, err := client.Get(ctx, “key”).Result() if err != nil fmt.Printf(“获取失败:%vn”, err) return } fmt.Printf(“值:%vn”, val)}

    说明

    • 使用redis.NewFailoverClient创建客户端。
    • 指定主库名称MasterName和哨兵地址。
    • 当主库故障时,哨兵会自动将从库提升为主库。

    三、Redis集群

    1. 集群模式

    特点:通过分片实现水平扩展,每个节点处理一部分数据,适合高并发场景。

    集群部署

    部署结构

    • 6节点:3主3从,每个主节点负责一个分片。
    • 每个分片有1主1从。

    使用redis-cli创建集群

    • 启动6个Redis实例,分别指定不同端口。
    • 使用redis-cli命令创建集群。

    创建集局脚本:例如start_cluster.sh

    启动6个节点,端口分别为30001到30006for port in 30001..30006}; do redis-server –cluster-enabled yes –cluster-config-file node-$port}.conf –port $port} –daemonize yesdone 创建集群redis-cli –cluster create 127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006 –cluster-replicas 1

    在上面的脚本中,node-$port}.conf是 Redis 集群模式下每个节点的配置文件,用于指定节点的运行参数。如果这些配置文件不存在,Redis 会自动生成一个默认的配置文件,但为了确保集群部署的正确性,最好手动创建这些配置文件。

    例如:

    node-30001.confcluster-enabled yesport 30001bind 127.0.0.1daemonize yeslogfile /var/log/redis/redis_30001.logdir ./data/30001save 60 1appendonly yes

    解释:

    • cluster-enabled yes: 启用集群模式。
    • port: 指定当前节点的端口。
    • bind: 绑定主机地址。
    • daemonize yes: 后台运行。
    • logfile: 指定日志文件路径。
    • dir: 指定数据文件存储路径。
    • save: 配置数据持久化策略。
    • appendonly: 启用 AOF 持久化。

    接着给脚本赋予执行权限并运行:

    chmod +x start_cluster.sh./start_cluster.sh

    连接示例

    package mainimport ( “context” “fmt” “github.com/go-redis/redis/v9”)func main() // 集群节点地址 addresses := []string “localhost:30001”, “localhost:30002”, “localhost:30003”, “localhost:30004”, “localhost:30005”, “localhost:30006”, } clusterClient := redis.NewClusterClient(&redis.ClusterOptions Addrs: addresses, }) pong, err := clusterClient.Ping(context.Background()).Result() if err != nil fmt.Printf(“连接失败:%vn”, err) return } fmt.Println(pong) // 设置键值对 if err := clusterClient.Set(context.Background(), “key”, “value”, 0).Err(); err != nil fmt.Printf(“设置失败:%vn”, err) return } // 获取值 val, err := clusterClient.Get(context.Background(), “key”).Result() if err != nil fmt.Printf(“获取失败:%vn”, err) return } fmt.Printf(“值:%vn”, val)}

    说明

    • 使用redis.NewClusterClient创建集群客户端。
    • 初始化时提供所有节点地址。
    • 集群模式下,Redis自动处理数据分片和请求路由。

    四、常用数据结构与操作

    1. 字符串(String)

    // 设置过期时刻err = client.Set(context.Background(), “key”, “value”, 10*time.Second).Err()// 递增计数器num, err := client.Incr(context.Background(), “counter”).Result()// 递减计数器num, err := client.Decr(context.Background(), “counter”).Result()

    2. 哈希(Hash)

    // 设置字段值err = client.HSet(context.Background(), “hashKey”, “field”, “value”).Err()// 获取字段值value, err := client.HGet(context.Background(), “hashKey”, “field”).Result()

    3. 列表(List)

    // 从左边推入元素err = client.LPush(context.Background(), “listKey”, “value”).Err()// 弹出左边第一个元素value, err := client.LPop(context.Background(), “listKey”).Result()

    4. 集合(Set)

    // 添加元素err = client.SAdd(context.Background(), “setKey”, “element”).Err()// 移除元素err = client.SRem(context.Background(), “setKey”, “element”).Err()// 获取所有元素members, err := client.SMembers(context.Background(), “setKey”).Result()

    5. 有序集合(ZSet)

    // 添加元素并设置分数err = client.ZAdd(context.Background(), “zsetKey”, &redis.ZMember: “element”, Score: 100}).Err()// 获取元素的分数score, err := client.ZScore(context.Background(), “zsetKey”, “element”).Result()// 获取排名rank, err := client.ZRank(context.Background(), “zsetKey”, “element”).Result()

    五、事务与批量操作

    1. 事务

    // 开始事务ctx := context.Background()tx, err := client.Tx(ctx)// 执行事务中的操作_, err = tx.Pipeline()( function(ctx context.Context) (_redis.CMDCb, error) _, err := tx.Get(ctx, “balance”).Result() if err != nil return nil, err } _, err := tx.Incr(ctx, “balance”).Result() if err != nil return nil, err } return nil, nil },)if err != nil fmt.Printf(“事务执行失败:%vn”, err)}

    2. 管道技术

    // 创建管道pipe := client.Pipeline()// 执行多个命令cmds, err := pipe.Set(context.Background(), “key1”, “value1”, 0). Set(context.Background(), “key2”, “value2”, 0). Exec(context.Background())if err != nil fmt.Printf(“管道执行失败:%vn”, err) return}// 打印结局for _, cmd := range cmds fmt.Printf(“%vn”, cmd)}

    六、高可用性

    1. 复制(主从)

    • 设置主从复制,确保数据安全。
    • 主库写入,数据同步到从库。
    • 从库可用于读分离,进步读性能。

    2. 故障转移

    • 使用哨兵模式实现自动故障转移。
    • 集群模式下,节点故障自动迁移。

    3. 连接池

    // 配置连接池pool := &redis.Pool Dial: func(context.Context) (redis.Conn, error) return client.DialContext(context.Background()) }, MaxActive: 10, // 最大活跃连接数 MaxIdle: 5, // 最大空闲连接数 IdleTimeout: 5 * time.Minute,}// 使用连接池conn := pool.Get(context.Background())defer conn.Close()

    七、监控与性能调优

    1. 内置工具

    • redis-cli: 命令行工具,执行各种Redis命令。
    • redis-benchmark: 性能基准测试工具。

    基准测试redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -n 10000 -q

    2. 性能指标

    • 内存使用: 使用info memory查看内存情形。
    • 拒绝策略: 配置maxmemory-policy避免内存溢出。
    • 过期时刻: 设置合理的expire,控制键生活周期。

    3. 调试

    • 使用slowlog记录慢查询。
    • 监控blocked clientsmaster_repl_offset

    八、实际案例

    1. 高并发秒杀体系

    需求:在高并发下,确保商品库存正确。

    解决方案

    • 使用Redis的事务和分布锁。
    • 数据结构:Hash存储商品库存。

    package mainimport ( “context” “fmt” “sync” “time” “github.com/go-redis/redis/v9”)// 秒杀函数func doSecKill(ctx context.Context, client *redis.Client, productId string, userId string) (bool, error) // 锁名称:秒杀锁 lockKey := “lock:sec:kill” // 商品库存Key stockKey := “stock:” + productId // 尝试获取锁,防止超卖 lock, err := client.LockNew(lockKey, 100*time.Millisecond).Acquire(ctx, time.Second*5).Result() if err != nil return false, err } defer lock.Release(ctx) // 检查库存是否充足 currentStock, err := client.HGet(ctx, stockKey, “quantity”).Int64() if err != nil || currentStock <= 0 return false, fmt.Errorf(“库存不足”) } // 减少库存 _, err = client.HIncrBy(ctx, stockKey, “quantity”, -1).Result() if err != nil return false, fmt.Errorf(“秒杀失败:%v”, err) } return true, nil}func main() client := redis.NewClient(&redis.Options Addr: “localhost:6379”, Password: “”, DB: 0, }) var wg sync.WaitGroup for i := 0; i < 100; i++ wg.Add(1) go func(userId int) defer wg.Done() ctx := context.Background() success, err := doSecKill(ctx, client, “product001”, fmt.Sprintf(“user%d”, userId)) if success fmt.Printf(“用户%d秒杀成功n”, userId) } else fmt.Printf(“用户%d秒杀失败:%vn”, userId, err) } }(i) } wg.Wait()}

    说明

    • 使用Redis的分布锁确保秒杀经过的原子性。
    • 使用Hash结构存储库存信息,实现并发安全的扣减操作。

    九、最佳操作

    1. 数据过期时刻

    • 为键设置合理的TTL,避免内存膨胀。

    2. 内存管理

    • 监控used_memory,确保内存使用在可控范围内。
    • 配置maxmemorymaxmemory-policy

    3. 日志配置

    • 开启Redis日志,记录操作和错误信息。
    • 使用slowlog跟踪慢查询。

    4. 安全性

    • 设置强密码。
    • 配置防火墙,限制访问来源。

    5. 监控

    • 使用Prometheus、Grafana监控Redis性能。
    • AlertManager配置告警制度。

    6. 备份恢复

    • 定期备份RDB或AOF文件。
    • 配置主从复制,确保数据安全。

    7. 连接池管理

    • 合理配置连接池参数,避免连接耗尽。

    8. 数据持久化

    • 选择RDB或AOF,根据需求配置持久化策略。

    十、拓展资料

    在Go语言中使用Redis,特别是结合哨兵和集群模式,可以实现高可用和高扩展性的体系。合理选择数据结构,使用事务和管道技术,可以提升性能。同时,注重监控和维护,确保Redis的稳定运行。

    到此这篇关于go中redis使用的示例代码的文章就介绍到这了,更多相关go redis使用内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

    无论兄弟们可能感兴趣的文章:

    • golang使用redis实现全文搜索功能详解
    • 使用Go语言启动Redis的实例详解
    • 怎样在Go语言中高效使用Redis的Pipeline
    • Go使用Redis实现分布式锁的常见技巧
    • 使用go语言实现Redis持久化的示例代码
    • Go语言使用Redis和Etcd实现高性能分布式锁
    • 重学Go语言之怎样使用Redis
    • Go?Redis客户端使用的两种对比
    • golangredis中Pipeline通道的使用详解