青训营课程中有Redis的课程,从中间学习到了一些用法,同时我也想了一些用法(结合了这次大项目)。就此记录一下。
Redis是什么
REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。它还有一定的持久化能力。
Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。
Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型(梦回数据结构体课堂(虽然实际上我在算竞中学过相当多))。
因为它就在内存中运行,效率非常高,常常用于可用于缓存、消息等场景。由于一个数据可以设置过期时间,所以还有另外一些功能。
Redis安装
Linux中安装redis就一两行命令罢了
sudo pacman -S redis
然后启动它:
redis-server
如果说找不到命令,我估计你得加上sudo再去执行,原因是普通用户的PATH环境变量里,一般没有/usr/sbin,所以一些命令是找不到的,就比如说zerotier-cli。
启动后,你会发现你无法发送命令。为什么?
原因很简单,前面说了,它支持网络。怎么支持的?你看看你执行的不是server吗?怎么可能就没有client了?
redis-cli
如果你手抖了一下,启动server的时候输入了ip和端口,那你得给client也加上了。
Redis使用
虽然可能没人这么说,不过就我看来,redis本身就是一个超大哈希表,外加一些功能罢了,但是,你可以取其中某个键值对,当作其他数据结构使用。
- 基本用法
键值对操作
set key value
get key value
del key
集合操作
sadd key member1 ...
srem key
spop key
sismember key member
...
集合有很多命令,可以使用help @set来使用。它还有其他的数据结构,都可以使用help @数据结构名查看其用法。
前面也说了,redis本身就是一个超大哈希表,所以你可以del 集合名删除一个集合。
- 消息队列
redis可以当作消息队列使用,但是问题在于,持久化的可靠性不如专门的消息队列,比如kafka、rocketmq等。具体的还真是用队列。下面的用法相当于栈:
LPUSH key value1
LPUSH key value2
LPOP key
LPOP key
这个才是真正的队列
RPUSH key value1
RPUSH key value2
LPOP key
LPOP key
- 计数
SET key 1
INCR key
如果你设置key为队列了,这个时候队列会被删除,然后换成一个普通键值对。
- 排行榜
ZINCRBY myzset 2 "Alex"
ZSCORE myzset "Alex"
- 和GO一起使用
首先你得安装go专属的client
go get github.com/redis/go-redis/v9
建立一个client,以及基本的用法:
cli := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
cli.Set(context.Background(), key, "value")
基本和命令是一致的。
下面是使用集合的一个例子:
type Set struct {
rdb *redis.Client
name string
}
func NewSet(setName string, cli *redis.Client) *Set {
return &Set {
rdb: cli,
name: setName,
}
}
func (set *Set)Add(ctx context.Context, key string) error {
return set.rdb.SAdd(ctx, set.name, key).Err()
}
func (set *Set)Del(ctx context.Context, key string) error {
return set.rdb.SRem(ctx, set.name, key).Err()
}
func (set *Set)Exists(ctx context.Context, key string) (bool, error) {
return set.rdb.SIsMember(ctx, set.name, key).Result()
}
func (set *Set)Size(ctx context.Context) (int64, error) {
return set.rdb.SCard(ctx, set.name).Result()
}
- 存储struct。
实际上,你把struct转换为json存储即可。