Redis实践|青训营笔记

315 阅读2分钟

Redis

Redis 是一个在内存中的VK数据结构存储系统。是目前使用最流行的NoSQL之一。总的来说,Redis这类非关系型数据库,是计算机的一大里程碑。今天我们的主角也就是他。

1. 什么是Redis

为什么需要Redis

  • 数据从单表,演进出了分库分表

  • MySQL从单机演进出了集群

    • 数据量增长
    • 读写数据压力不断增加

数据也分冷数据和热数据

热数据是经常被访问到的数据,将热数据存储到内存中。

例如在读场景中,Server会先访问Redis读取数据,如果读不到再去读mySQL.

写场景是先访问MySQL集群,然后 监听 binlog,修改Redis

Redis 基本工作原理

redis-server-service.jpeg

  • 数据从内存中读写

  • 数据保存到硬盘上防止重启数据丢失

    • 增量数据保存到AOF文件
    • 全量数据保存到RDB文件
  • 单线程处理所有操作命令

Redis-single-threaded-process.jpeg

2. Redis 应用案例

最常见的案例是:

  • 连续签到
  • 消息通知
  • 计数
  • 排行榜
  • 限流
  • 分布式锁

连续签到

最常用的是 String 数据结构 sds

  • 可以存储 字符串、数字、二进制数据
  • 通常和expire配合使用
  • 场景:存储计数、Session

消息通知

用list 作为消息队列

  • 使用场景:消息通知。

例如当文章更新时,将更新后的文章推送到ES,用户就能搜索到最新的文章数据

用List 数据结构 QuickList 实现

QuickList由一个双向链表和listpack实现。


Redis项目实践

我们本次使用的是Kratos框架,在和Redis的连接上使用的是 Go-Redis 。在项目中结合 Kratos, 上手非常简单。

首先用go get github.com/redis/go-redis/v9 引入go-redis。然后在对应的文件里引入。例如:

import "github.com/redis/go-redis/v9"

rdb := redis.NewClient(&redis.Options{
    Addr:      "localhost:6379",
    Password: "", // no password set
    DB:          0,  // use default DB
})

在 Kratos 中,只需在yaml内定义redis的配置,然后用 proto生成对应的 message字段 即可使用。

config.yaml

  data:
  redis:
    comment_db: 1
    addr: 127.0.0.1:6379
    read_timeout: 0.2s
    write_timeout: 0.2s

conf.proto

message Data {
  message Mysql {
    string driver = 1;
    string dsn = 2;
  }
   message Redis {
    int32 comment_db = 1;
    string addr = 2;
    string password = 3;
    string username = 4;
    google.protobuf.Duration read_timeout = 5;
    google.protobuf.Duration write_timeout = 6;
   }
  Mysql mysql = 1;
  Redis redis = 2;
}

然后在Data层中的 data.go 创建Redis的连接,在创建时需要用Ping 判断连接是否存在。

实现如下:

// NewRedisConn Redis数据库连接
func NewRedisConn(c *conf.Data, l log.Logger) *redis.Client {
    logs := log.NewHelper(log.With(l, "module", "data/redis"))
    client := redis.NewClient(&redis.Options{
        DB:           int(c.Redis.CommentDb),
        Addr:         c.Redis.Addr,
        WriteTimeout: c.Redis.WriteTimeout.AsDuration(),
        ReadTimeout:  c.Redis.ReadTimeout.AsDuration(),
        Password:     c.Redis.Password,
    })

    // ping Redis客户端,判断连接是否存在
    _, err := client.Ping(context.Background()).Result()
    if err != nil {
        logs.Fatalf("Redis database connection failure, err : %v", err)
    }
    logs.Info("Cache enabled successfully!")
    return client
}

最后在data层对应服务的go文件中实现其方法。常用的有HGetALLHSet等。

通过这些实现就可以连接到 Redis服务器进行使用了!