初识Redis|青训营

69 阅读3分钟

1. redis简介

目前,数据库按照不同的分类标准进行划分,主要包括SQL和NoSQL,其中又包括关系数据库、键值数据库等多种类型。在这些分类中,Redis作为一种键值数据库,虽然保留了键值数据库的简单和快捷特性,但同时也吸收了部分关系数据库的优点,使其处于关系数据库和键值数据库之间的位置。Redis不仅可以存储字符串类型的数据,还支持有序的列表和无序的集合类型数据,同时具备排序和高级功能,如实现INCR和SETNX等操作时的原子性。此外,Redis还支持主从复制等功能。

2. Redis的应用领域是什么?

在实际应用中,Redis具有多种用途,其中之一是作为消息队列存在,以内嵌的列表形式支持高并发实时需求。在电商数据处理中,与商品、热销、推荐排序相关的队列通常存储在Redis中,并且Storm也可以用于对Redis列表进行读取和更新操作。

3. Redis的优点有哪些?

  • 高性能:Redis支持超过每秒100K+的读写频率。
  • 丰富的数据类型:Redis支持多种数据类型操作,包括二进制数据的字符串、列表、哈希、集合和有序集合。
  • 原子性:所有Redis操作都是原子性的,还支持多个操作合并后的原子性执行。
  • 丰富的特性:Redis支持发布/订阅、通知、键过期等特性。

4. Redis的局限性是什么?

  • 数据库容量受物理内存限制:无法用于海量数据的高性能读写,适用于较小数据量的高性能操作。
  • 适用特定场景:Redis专注于特定领域,速度极快,但并不适用于所有场景。

5. Redis的基本操作

  • GET key: 获取指定键的值。

  • SET key value: 设置键的值。

  • DEL key [key ...] : 删除一个或多个键。

  • INCR key: 将键的值递增1。

  • SETNX key value: 如果键不存在,则设置键的值为指定值。

  • HSET key field value: 在哈希数据结构中,设置指定键的指定字段的值。

  • HGET key field: 获取哈希键中指定字段的值。

  • HINCRBY key field increment: 在哈希键中,将指定字段的值增加给定的增量。

  • LPUSH key value [value ...] : 在列表的左侧插入一个或多个值。

  • RPOP key: 从列表的右侧弹出一个值并返回。

  • LRANGE key start stop: 获取列表中指定范围的值。

  • ZADD key [NX|XX] [CH] [INCR] score member [score member ...] : 向有序集合中添加一个或多个成员,可以设置参数来控制是否更新现有成员。

  • ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] : 根据分数范围获取有序集合中的成员。

  • ZREVRANGE key start stop [WITHSCORES] : 根据索引范围从有序集合的末尾获取成员。

  • ZINCRBY key increment member: 增加有序集合中成员的分数。

  • ZSCORE key member: 获取有序集合中成员的分数。

6. pipeline的概念

是一种优化技术,用于在一次通信中发送多个请求,从而减少网络延迟并提高性能。在Redis中,使用Pipeline可以将多个命令一次性发送到服务器,然后一次性接收所有响应,而不是逐个发送和接收。

package main

import (
	"context"
	"fmt"
	"time"

	"github.com/go-redis/redis/v8"
)

func main() {
	// 创建Redis客户端
	client := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379", // Redis服务器地址
		Password: "",              // Redis密码
		DB:       0,               // 使用默认的数据库
	})

	// 创建上下文
	ctx := context.Background()

	// 使用Pipeline发送多个命令
	pipe := client.Pipeline()
	pipe.Incr(ctx, "counter")
	pipe.Set(ctx, "name", "John", 0)
	pipe.Get(ctx, "name")
	pipe.Exec(ctx)

	// 执行Pipeline并获取结果
	results, err := pipe.Exec(ctx)
	if err != nil {
		fmt.Println("Pipeline error:", err)
		return
	}

	// 获取每个命令的结果
	for _, result := range results {
		switch result.(type) {
		case *redis.IntCmd:
			fmt.Println("Increment result:", result.(*redis.IntCmd).Val())
		case *redis.StatusCmd:
			fmt.Println("Set result:", result.(*redis.StatusCmd).Val())
		case *redis.StringCmd:
			fmt.Println("Get result:", result.(*redis.StringCmd).Val())
		}
	}
}

在上述代码中创建了一个Pipeline,并将多个命令添加到Pipeline中,然后一次性执行这些命令,最后获取每个命令的结果。