Redis的基本使用

Linux中的安装

同时Redis的安装也非常简单,到Redis的官网(Download | Redis),下载对应的版本,简单几个命令安装即可。

wget https://download.redis.io/releases/redis-7.2.1.tar.gz
tar xzf redis-7.2.1.tar.gz
cd redis-7.2.1/
make

安装后源码和执行目录会混在一起,为了方便,做了一次install

make install PREFIX=/home/xx/redis/redis

 /home/xx/redis/redis仅是执行目录

 三种启动方式

# 默认启动
 ./redis-server
# 带参数启动
./redis-server --port 6380
# 指定配置文件启动
./redis-server ../conf/redis.conf

操作

1、单次操作(理解为一次性的,使用较少):redis-cli -hip {host} -p{port} {command}

./redis-cli -p 9379 set hello 111

2、命令操作(通过客户端连接之后操作):

停止

命令方式

1、./redis-cli -p 6379 shutdown

2、命令行中输入shutdown

3、kill -9 {pid}(不建议)

Redis应用场景

缓存

缓存机制几乎在所有的大型网站都有使用,合理地使用缓存不仅可以加快数据的访问速度,而且能够有效地降低后端数据源的压力。Redis提供了键值过期时间设置,并且也提供了灵活控制最大内存和内存溢出后的淘汰策略。可以这么说,一个合理的缓存设计能够为一个网站的稳定保驾护航。

一般MySQL数据库写的并发是600/s,读的2000/s,对于大型互联网项目的百万并发,根本扛不住,Redis的官方显示Redis能够单台达到10W+/s的并发。

排行榜系统

排行榜系统几乎存在于所有的网站,例如按照热度排名的排行榜,按照发布时间的排行榜,按照各种复杂维度计算出的排行榜,Redis提供了列表和有序集合数据结构,合理地使用这些数据结构可以很方便地构建各种排行榜系统。

计数器应用

计数器在网站中的作用至关重要,例如视频网站有播放数、电商网站有浏览数,为了保证数据的实时性,每一次播放和浏览都要做加1的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。

社交网络

赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太适合保存这种类型的数据,Redis提供的数据结构可以相对比较容易地实现这些功能。

消息队列系统

消息队列系统可以说是一个大型网站的必备基础组件,因为其具有业务解耦、非实时业务削峰等特性。Redis提供了发布订阅功能和阻塞队列的功能,虽然和专业的消息队列比还不够足够强大,但是对于一般的消息队列功能基本可以满足。这个是Redis的作者参考了Kafka做的拓展。

Redis全局命令

keys命令

查看所有键(支持通配符)

keys *

# 通配符,以L开头的
keys L*

dbsize命令

dbsize命令会返回当前数据库中键的总数。

dbsize命令在计算键总数时不会遍历所有键,而是直接获取 Redis内置的键总数变量,所以dbsize命令的时间复杂度是O(1)。

exists

检查键是否存在,存在返回1,不存在返回0。

del

删除键,无论值是什么数据结构类型,del命令都可以将其删除。返回删除键个数,删除不存在键返回0。同时del命令可以支持删除多个键(多个键之间空格隔开)。

expire

Redis支持对键添加过期时间,当超过过期时间后,会自动删除键,时间单位秒。

ttl命令会返回键的剩余过期时间,它有3种返回值:

大于等于0的整数:键剩余的过期时间。

-1:键没设置过期时间。

-2:键不存在。

除了expire、ttl命令以外,Redis还提供了expireat、pexpire、pexpireat、pttl、persist等一系列命令。

expireat key timestamp: 键在秒级时间截timestamp后过期。

ttl命令和pttl都可以查询键的剩余过期时间,但是pttl精度更高可以达到毫秒级别,有3种返回值:

大于等于0的整数:键剩余的过期时间(ttl是秒,pttl是毫秒)。

-1:键没有设置过期时间。

-2:键不存在。

pexpire key milliseconds:键在milliseconds毫秒后过期。

pexpireat key milliseconds-timestamp键在毫秒级时间戳timestamp后过期。

在使用Redis相关过期命令时,需要注意以下几点。

  1. 如果expire key 的键不存在,返回结果为0。
  2. 如果过期时间为负值,键会立即被删除,犹如使用del命令一样。
  3. persist命令可以将键的过期时间清除。
  4. 对于字符串类型键,执行set命令会去掉过期时间,这个问题很容易在开发中被忽视。
  5. Redis不支持二级数据结构(例如哈希、列表)内部元素的过期功能,不能对二级数据结构做过期时间设置。

type

返回键的数据结构类型,例如键lijin是字符串类型,返回结果为string。键mylist是列表类型,返回结果为list,键不存在返回none

randomkey

随机返回一个键

rename

键重命名

rename oldkey newkey

但是要注意,如果在rename之前,新键已经存在,那么它的值也将被覆盖。

为了防止被强行rename,Redis提供了renamenx命令,确保只有newKey不存在时候才被覆盖。

基本数据类型

Redis提供了一些数据结构供我们往Redis中存取数据,最常用的的有5种,字符串(String)、哈希(Hash)、列表(list)、集合(set)、有序集合(ZSET)

字符串(String)

字符串类型是Redis最基础的数据结构。首先键都是字符串类型,而且其他几种数据结构都是在字符串类型基础上构建的,所以字符串类型能为其他四种数据结构的学习奠定基础。字符串类型的值实际可以是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字(整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能超过512MB。

(虽然Redis是C写的,C里面有字符串<本质使用char数组来实现>,但是处于种种考虑,Redis还是自己实现了字符串类型)

set 设置值

set命令有几个选项:

ex seconds: 为键设置秒级过期时间。

px milliseconds: 为键设置毫秒级过期时间。

nx: 键必须不存在,才可以设置成功,用于添加(分布式锁常用)。

xx: 与nx相反,键必须存在,才可以设置成功,用于更新。

从执行效果上看,ex参数和expire命令基本一样。还有一个需要特别注意的地方是如果一个字符串已经设置了过期时间,然后你调用了set 方法修改了它,它的过期时间会消失。

除了set选项,Redis 还提供了setex和 setnx两个命令:

setex key seconds value

setnx key value

setex和 setnx的作用和ex和nx选项是一样的。也就是,setex为键设置秒级过期时间,setnx设置时键必须不存在,才可以设置成功。

get 获取值

如果要获取的键不存在,则返回nil(空)

mset 批量设置值

通过mset命令一次性设置4个键值对

mget 批量获取值

mget 批量获取值

Incr 数字运算

incr命令用于对值做自增操作,返回结果分为三种情况:

值不是整数,返回错误。

值是整数,返回自增后的结果。

键不存在,按照值为0自增,返回结果为1。

除了incr命令,Redis提供了decr(自减)、 incrby(自增指定数字)、decrby(自减指定数字)、incrbyfloat(自增浮点数)

append追加指令

append可以向字符串尾部追加值,返回追加后的字符串长度

strlen 字符串长度

返回字符串长度

getset 设置并返回原值

getset和set一样会设置值,但是不同的是,它同时会返回键原来的值

setrange 设置指定位置的字符

下标从0开始计算。

使用场景

字符串类型的使用场景很广泛:

缓存功能

Redis 作为缓存层,MySQL作为存储层,绝大部分请求的数据都是从Redis中获取。由于Redis具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用。

计数

使用Redis 作为计数的基础工具,它可以实现快速计数、查询缓存的功能,同时数据可以异步落地到其他数据源。

共享Session

一个分布式Web服务将用户的Session信息(例如用户登录信息)保存在各自服务器中,这样会造成一个问题,出于负载均衡的考虑,分布式服务会将用户的访问均衡到不同服务器上,用户刷新一次访问可能会发现需要重新登录,这个问题是用户无法容忍的。

为了解决这个问题,可以使用Redis将用户的Session进行集中管理,,在这种模式下只要保证Redis是高可用和扩展性的,每次用户更新或者查询登录信息都直接从Redis中集中获取。

限速

比如,很多应用出于安全的考虑,会在每次进行登录时,让用户输入手机验证码,从而确定是否是用户本人。但是为了短信接口不被频繁访问,会限制用户每分钟获取验证码的频率,例如一分钟不能超过5次。一些网站限制一个IP地址不能在一秒钟之内方问超过n次也可以采用类似的思路。

哈希(Hash)

Java里提供了HashMap,Redis中也有类似的数据结构,就是哈希类型。但是要注意,哈希类型中的映射关系叫作field-value,注意这里的value是指field对应的值,不是键对应的值。

hset设值

HSET user:1 name liming

如果设置成功会返回1,反之会返回0。此外Redis提供了hsetnx命令,它们的关系就像set和setnx命令一样,只不过作用域由键变为field。

hget取值

HGET user:1 name

如果键或field不存在,会返回nil。

hdel删除field

hdel会删除一个或多个field,返回结果为成功删除field的个数。

hlen计算field个数

hmset批量设值

hmget批量取值
hexists判断field是否存在

hkeys获取所有field

它返回指定哈希键所有的field

hvals获取所有value

hgetall获取所有field与value

在使用hgetall时,如果哈希元素个数比较多,会存在阻塞Redis的可能。如果只需要获取部分field,可以使用hmget,如果一定要获取全部field-value,可以使用hscan命令,该命令会渐进式遍历哈希类型

hincrby增加

hincrby和 hincrbyfloat,就像incrby和incrbyfloat命令一样,但是它们的作用域是filed。

hstrlen 计算value的字符串长度

命令的时间复杂度

哈希类型的操作命令中,hdel,hmget,hmset的时间复杂度和命令所带的field的个数相关O(k),hkeys,hgetall,hvals和存储的field的总数相关,O(N)。其余的命令时间复杂度都是O(1)。

使用场景

从前面的操作可以看出,String和Hash的操作非常类似,那为什么要弄一个hash出来存储。

哈希类型比较适宜存放对象类型的数据,我们可以比较下,如果数据库中表记录user为:

idnameage
1lijin18
2msb20

1、使用String类型

需要一条条去插入获取。

set user:1:name xiaoming;

set user:1:age 18;

set user:2:name xiaoli;

set user:2:age 20;

优点:简单直观,每个键对应一个值

缺点:键数过多,占用内存多,用户信息过于分散,不用于生产环境

2、将对象序列化存入redis

set user:1 serialize(userInfo);

优点:编程简单,若使用序列化合理内存使用率高

缺点:序列化与反序列化有一定开销,更新属性时需要把userInfo全取出来进行反序列化,更新后再序列化到redis

3、使用hash类型

hmset user:1 name lijin age 18

hmset user:2 name msb age 20

优点:简单直观,使用合理可减少内存空间消耗

缺点:要控制内部编码格式,不恰当的格式会消耗更多内存

列表(list)

列表( list)类型是用来存储多个有序的字符串,a、b、c、c、b四个元素从左到右组成了一个有序的列表,列表中的每个字符串称为元素(element),一个列表最多可以存储(2^32-1)个元素(4294967295)。

image.png

在Redis 中,可以对列表两端插入( push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等。列表是一种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用场景。

列表类型有两个特点:

第一、列表中的元素是有序的,这就意味着可以通过索引下标获取某个元素或者某个范围内的元素列表。

第二、列表中的元素可以是重复的。

操作命令
lrange 获取指定范围内的元素列表(不会删除元素)

key start end

索引下标特点:从左到右为0到N-1

lrange 0 -1命令可以从左到右获取列表的所有元素

rpush 向右插入

image.png

image.png

lpush 向左插入

image.png

image.png

linsert 在某个元素前或后插入新元素

LINSERT demolist before b hh

lpop 从列表左侧弹出(会删除元素)

请注意,弹出来元素就没了。

rpop 从列表右侧弹出

rpop将会把列表最右侧的元素d弹出。

lrem 对指定元素进行删除

image.png

lrem命令会从列表中找到等于value的元素进行删除,根据count的不同分为三种情况:

count>0,从左到右,删除最多count个元素。

count<0,从右到左,删除最多count绝对值个元素。

count=0,删除所有。

返回值是实际删除元素的个数

ltrim 按照索引范围修剪列表

例如想保留列表中第0个到第1个元素

lset修改指定索引下标的元素

lindex 获取列表指定索引下标的元素
llen 获取列表长度
blpop和brpop阻塞式弹出元素

blpop和brpop是lpop和rpop的阻塞版本,除此之外还支持多个列表类型,也支持设定阻塞时间,单位秒,如果阻塞时间为0,表示一直阻塞下去。我们以brpop为例说明。

image.png

A客户端阻塞了(因为没有元素就会阻塞)

image.png

A客户端一直处于阻塞状态。此时我们从另一个客户端B执行

image.png

A客户端则输出

image.png

注意:brpop后面如果是多个键,那么brpop会从左至右遍历键,一旦有一个键能弹出元素,客户端立即返回。

使用场景

列表类型可以用于比如:

消息队列,Redis 的 lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。

文章列表

每个用户有属于自己的文章列表,现需要分页展示文章列表。此时可以考虑使用列表,因为列表不但是有序的,同时支持按照索引范围获取元素。

实现其他数据结构

lpush+lpop =Stack(栈)

lpush +rpop =Queue(队列)

lpsh+ ltrim =Capped Collection(有限集合)

lpush+brpop=Message Queue(消息队列)

集合(set)

image.png

集合( set)类型也是用来保存多个的字符串元素,但和列表类型不一样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素。

一个集合最多可以存储2的32次方-1个元素。Redis除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集,合理地使用好集合类型,能在实际开发中解决很多实际问题。

sadd 添加元素

允许添加多个,返回结果为添加成功的元素个数

srem 删除元素

允许删除多个,返回结果为成功删除元素个数

scard 计算元素个数

sismember 判断元素是否在集合中

如果给定元素element在集合内返回1,反之返回0

srandmember 随机从集合返回指定个数元素

指定个数如果不写默认为1

spop 从集合随机弹出元素

同样可以指定个数,如果不写默认为1,注意,既然是弹出,spop命令执行后,元素会从集合中删除,而srandmember不会。

smembers 获取所有元素(不会弹出元素)

返回结果是无序的

sinter 求多个集合的交集

suinon 求多个集合的并集

sdiff 求多个集合的差集

集合间的运算在元素较多的情况下会比较耗时,所以 Redis提供了上面三个命令(原命令+store)将集合间交集、并集、差集的结果保存在destination key中,例如

使用场景

集合类型比较典型的使用场景是标签(tag)。例如一个用户可能对娱乐、体育比较感兴趣,另一个用户可能对历史、新闻比较感兴趣,这些兴趣点就是标签。有了这些数据就可以得到喜欢同一个标签的人,以及用户的共同喜好的标签,这些数据对于用户体验以及增强用户黏度比较重要。

例如一个电子商务的网站会对不同标签的用户做不同类型的推荐,比如对数码产品比较感兴趣的人,在各个页面或者通过邮件的形式给他们推荐最新的数码产品,通常会为网站带来更多的利益。

除此之外,集合还可以通过生成随机数进行比如抽奖活动,以及社交图谱等等。

有序集合(ZSET)

image.png

有序集合相对于哈希、列表、集合来说会有一点点陌生,但既然叫有序集合,那么它和集合必然有着联系,它保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个分数( score)作为排序的依据。

有序集合中的元素不能重复,但是score可以重复,就和一个班里的同学学号不能重复,但是考试成绩可以相同。

有序集合提供了获取指定分数和元素范围查询、计算成员排名等功能,合理的利用有序集合,能帮助我们在实际开发中解决很多问题。

集合内操作命令
zadd添加成员

zcard 计算成员个数

zscore 计算某个成员的分数

如果成员不存在则返回nil

zrank计算成员的排名

zrank是从分数从低到高返回排名

zrevrank反之

很明显,排名从0开始计算。

zrem 删除成员

允许一次删除多个成员。

返回结果为成功删除的个数。

zincrby 增加成员的分数

zrange和zrevrange返回指定排名范围的成员

有序集合是按照分值排名的,zrange是从低到高返回,zrevrange反之。如果加上 withscores选项,同时会返回成员的分数

zrangebyscore返回指定分数范围的成员

zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key max min [withscores][limit offset count]

其中zrangebyscore按照分数从低到高返回,zrevrangebyscore反之。例如下面操作从低到高返回200到221分的成员,withscores选项会同时返回每个成员的分数。

同时min和max还支持开区间(小括号)和闭区间(中括号),-inf和+inf分别代表无限小和无限大

zcount 返回指定分数范围成员个数

zcount key min max

zremrangebyrank 按升序删除指定排名内的元素

zremrangebyrank key start end

zremrangebyscore 删除指定分数范围的成员

zremrangebyscore key min max

集合间操作命令
zinterstore 交集

zinterstore

这个命令参数较多,下面分别进行说明

destination:交集计算结果保存到这个键。

numkeys:需要做交集计算键的个数。

key [key ...]:需要做交集计算的键。

weights weight [weight ...]:每个键的权重,在做交集计算时,每个键中的每个member 会将自己分数乘以这个权重,每个键的权重默认是1。

aggregate sum/ min |max:计算成员交集后,分值可以按照sum(和)、min(最小值)、max(最大值)做汇总,默认值是sum。

不太好理解,我们用一个例子来说明。(算平均分)

zunionstore 并集并存储到新的key

使用场景

有序集合比较典型的使用场景就是排行榜系统。例如视频网站需要对用户上传的视频做排行榜,榜单的维度可能是多个方面的:按照时间、按照播放数量、按照获得的赞数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值