Redis

Redis学习

Redis是什么?有什么特点?

是什么:
Redis是一个开源的,基于内存亦可持久化的日志型、高性能Key-Value数据库,并提供多种语言的API

干什么:
性能极高 –redis读写性能测试redis官网测试读写能到10万左右,redis读写能力为2W/s,mysql读能力5K/s、写能力为3K/s,数据上看redis性能碾压mysql

丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过8和EXEC指令包起来。 但是Redis 事务的执行并不是原子性的。

redis事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

什么是Nosql

NoSQL = Not Only SQL(不仅仅是SQL)

Not Only Structured Query Language

关系型数据库:列+行,同一个表下数据的结构是一样的。

非关系型数据库:数据存储没有固定的格式,并且可以进行横向扩展。

NoSQL泛指非关系型数据库,随着web2.0互联网的诞生,传统的关系型数据库很难对付web2.0时代!尤其是超大规模的高并发的社区,暴露出来很多难以克服的问题,NoSQL在当今大数据环境下发展的十分迅速,Redis是发展最快的。

Nosql特点

  1. 方便扩展(数据之间没有关系,很好扩展!)

  2. 大数据量高性能(Redis一秒可以写8万次,读11万次,NoSQL的缓存记录级,是一种细粒度的缓存,性能会比较高!)

  3. 数据类型是多样型的!(不需要事先设计数据库,随取随用)

  4. 传统的 RDBMS 和 NoSQL

    传统的 RDBMS(关系型数据库)
    - 结构化组织
    - SQL
    - 数据和关系都存在单独的表中 row col
    - 操作,数据定义语言
    - 严格的一致性
    - 基础的事务
    - ...
    
    Nosql
    - 不仅仅是数据
    - 没有固定的查询语言
    - 键值对存储,列存储,文档存储,图形数据库(社交关系)
    - 最终一致性
    - CAP定理和BASE
    - 高性能,高可用,高扩展
    - ...
    

一.Redis安装

1.linux安装Redis

第一步:下载redis安装包
wget http://download.redis.io/releases/redis-4.0.6.tar.gz

第二步:解压压缩包
tar -zxvf redis-4.0.6.tar.gz

第三步:yum安装gcc依赖
yum install gcc

第四步:跳转到redis解压目录下
cd redis-4.0.6

第五步:编译安装
make MALLOC=libc

将/usr/local/redis-4.0.6/src目录下的文件加到/usr/local/bin目录
cd src && make install

2.window安装

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VUEgwWCn-1611141871860)(C:\Users\dong\AppData\Roaming\Typora\typora-user-images\image-20210110134354488.png)]

第一步:启动服务端

第二步:启动客户端进行连接测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CNFN4R0G-1611141871863)(C:\Users\dong\AppData\Roaming\Typora\typora-user-images\image-20210110134554492.png)]

连接成功

3.性能测试

redis-benchmark:**Redis官方提供的性能测试工具,参数选项如下:

img

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bdPFkb7a-1611141871864)(C:\Users\dong\AppData\Roaming\Typora\typora-user-images\image-20210110135124569.png)]

依次是

10万个请求进行写入测试

50个并发客户端

每次写入3个字节

只有一台服务器处理,单机性能

所有请求1毫秒内完成

每秒处理93129次请求

二.配置文件

port 6379 --端口号

bind 127.0.0.1 --这个配置是只允许本地客户端访问

protected-mode yes --是否开启保护模式。默认开启,如果没有设置bind项的ip和redis密码的话,服务将只允许本地访 问

loglevel notice – 配置日志级别。选项有debug, verbose, notice, warning

logfile “” --日志名称。空字符串表示标准输出。注意如果redis配置为后台进程,标准输出中信息会发送到/dev/null

databases 16 --设置数据库个数。默认数据库是 DB 0,可以通过SELECT where dbid is a number between 0 and ‘databases’-1为每个连接使用不同的数据库。

**save 900 1 # 持久化设置:
save 300 10 # 下面的例子将会进行把数据写入磁盘的操作:
save 60 10000
# 900秒(15分钟)之后,且至少1次变更
\ # 300秒(5分钟)之后,且至少10次变更
\ # 60秒之后,且至少10000次变更
\ # 不写磁盘的话就把所有 “save” 设置注释掉就行了。
\ # 通过添加一条带空字符串参数的save指令也能移除之前所有配置的save指令,如: save “”

配置文件详解:https://www.jianshu.com/p/41f393f594e8

三.基本数据类型

在redis中无论什么数据类型,在数据库中都是以key-value形式保存,通过进行对Redis-key的操作,来完成对数据库中数据的操作。

常用命令

  • exists key:判断键是否存在
  • del key:删除键值对
  • move key db:将键值对移动到指定数据库
  • expire key second:设置键值对的过期时间
  • type key:查看value的数据类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ngR0Wpd8-1611141871866)(C:\Users\dong\AppData\Roaming\Typora\typora-user-images\image-20210110142137970.png)]

关于TTL命令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8gJn9zVT-1611141871868)(C:\Users\dong\AppData\Roaming\Typora\typora-user-images\image-20210110142718592.png)]

Redis的key,通过TTL命令返回key的过期时间,一般来说有3种:

  1. 当前key没有设置过期时间,所以会返回-1.
  2. 当前key有设置过期时间,而且key已经过期,所以会返回-2.
  3. 当前key有设置过期时间,且key还没有过期,故会返回key的正常剩余时间.

关于重命名RENAMERENAMENX

  • RENAME key newkey修改 key 的名称
  • RENAMENX key newkey仅当 newkey 不存在时,将 key 改名为 newkey 。

String(字符串)

命令 描述 示例
APPEND key value 向指定的key的value后追加字符串 127.0.0.1:6379> set msg hello OK 127.0.0.1:6379> append msg " world" (integer) 11 127.0.0.1:6379> get msg “hello world”
DECR/INCR key 将指定key的value数值进行+1/-1(仅对于数字) 127.0.0.1:6379> set age 20 OK 127.0.0.1:6379> incr age (integer) 21 127.0.0.1:6379> decr age (integer) 20
INCRBY/DECRBY key n 按指定的步长对数值进行加减 127.0.0.1:6379> INCRBY age 5 (integer) 25 127.0.0.1:6379> DECRBY age 10 (integer) 15
INCRBYFLOAT key n 为数值加上浮点型数值 127.0.0.1:6379> INCRBYFLOAT age 5.2 “20.2”
STRLEN key 获取key保存值的字符串长度 127.0.0.1:6379> get msg “hello world” 127.0.0.1:6379> STRLEN msg (integer) 11
GETRANGE key start end 按起止位置获取字符串(闭区间,起止位置都取) 127.0.0.1:6379> get msg “hello world” 127.0.0.1:6379> GETRANGE msg 3 9 “lo worl”
SETRANGE key offset value 用指定的value 替换key中 offset开始的值 127.0.0.1:6379> SETRANGE msg 2 hello (integer) 7 127.0.0.1:6379> get msg “tehello”
GETSET key value 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 127.0.0.1:6379> GETSET msg test “hello world”
SETNX key value 仅当key不存在时进行set 127.0.0.1:6379> SETNX msg test (integer) 0 127.0.0.1:6379> SETNX name sakura (integer) 1
SETEX key seconds value set 键值对并设置过期时间 127.0.0.1:6379> setex name 10 root OK 127.0.0.1:6379> get name (nil)
MSET key1 value1 [key2 value2…] 批量set键值对 127.0.0.1:6379> MSET k1 v1 k2 v2 k3 v3 OK
MSETNX key1 value1 [key2 value2…] 批量设置键值对,仅当参数中所有的key都不存在时执行 127.0.0.1:6379> MSETNX k1 v1 k4 v4 (integer) 0
MGET key1 [key2…] 批量获取多个key保存的值 127.0.0.1:6379> MGET k1 k2 k3 1) “v1” 2) “v2” 3) “v3”
PSETEX key milliseconds value 和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,
getset key value 如果不存在值,则返回nil,如果存在值,获取原来的值,并设置新的值

String类似的使用场景:value除了是字符串还可以是数字,用途举例:

  • 计数器
  • 统计多单位的数量:uid:123666:follow 0
  • 对象存储缓存

List(列表)

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)

一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

首先我们列表,可以经过规则定义将其变为队列、栈、双端队列等

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VPvbIltc-1597890996518)(狂神说 Redis.assets/image-20200813114255459.png)]

正如图Redis中List是可以进行双端操作的,所以命令也就分为了LXXX和RLLL两类,有时候L也表示List例如LLEN

命令 描述
LPUSH/RPUSH key value1[value2..] 从左边/右边向列表中PUSH值(一个或者多个)。
LRANGE key start end 获取list 起止元素==(索引从左往右 递增)==
LPUSHX/RPUSHX key value 向已存在的列名中push值(一个或者多个)
LINSERT key BEFORE|AFTER pivot value 在指定列表元素的前/后 插入value
LLEN key 查看列表长度
LINDEX key index 通过索引获取列表元素
LSET key index value 通过索引为元素设值
LPOP/RPOP key 从最左边/最右边移除值 并返回
RPOPLPUSH source destination 将列表的尾部(右)最后一个值弹出,并返回,然后加到另一个列表的头部
LTRIM key start end 通过下标截取指定范围内的列表
LREM key count value List中是允许value重复的 count > 0:从头部开始搜索 然后删除指定的value 至多删除count个 count < 0:从尾部开始搜索… count = 0:删除列表中所有的指定value。
BLPOP/BRPOP key1[key2] timout 移出并获取列表的第一个/最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
BRPOPLPUSH source destination timeout RPOPLPUSH功能相同,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
---------------------------LPUSH---RPUSH---LRANGE--------------------------------

127.0.0.1:6379> LPUSH mylist k1 # LPUSH mylist=>{1}
(integer) 1
127.0.0.1:6379> LPUSH mylist k2 # LPUSH mylist=>{2,1}
(integer) 2
127.0.0.1:6379> RPUSH mylist k3 # RPUSH mylist=>{2,1,3}
(integer) 3
127.0.0.1:6379> get mylist # 普通的get是无法获取list值的
(error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> LRANGE mylist 0 4 # LRANGE 获取起止位置范围内的元素
1) "k2"
2) "k1"
3) "k3"
127.0.0.1:6379> LRANGE mylist 0 2
1) "k2"
2) "k1"
3) "k3"
127.0.0.1:6379> LRANGE mylist 0 1
1) "k2"
2) "k1"
127.0.0.1:6379> LRANGE mylist 0 -1 # 获取全部元素
1) "k2"
2) "k1"
3) "k3"

---------------------------LPUSHX---RPUSHX-----------------------------------

127.0.0.1:6379> LPUSHX list v1 # list不存在 LPUSHX失败
(integer) 0
127.0.0.1:6379> LPUSHX list v1 v2  
(integer) 0
127.0.0.1:6379> LPUSHX mylist k4 k5 # 向mylist中 左边 PUSH k4 k5
(integer) 5
127.0.0.1:6379> LRANGE mylist 0 -1
1) "k5"
2) "k4"
3) "k2"
4) "k1"
5) "k3"

---------------------------LINSERT--LLEN--LINDEX--LSET----------------------------

127.0.0.1:6379> LINSERT mylist after k2 ins_key1 # 在k2元素后 插入ins_key1
(integer) 6
127.0.0.1:6379> LRANGE mylist 0 -1
1) "k5"
2) "k4"
3) "k2"
4) "ins_key1"
5) "k1"
6) "k3"
127.0.0.1:6379> LLEN mylist # 查看mylist的长度
(integer) 6
127.0.0.1:6379> LINDEX mylist 3 # 获取下标为3的元素
"ins_key1"
127.0.0.1:6379> LINDEX mylist 0
"k5"
127.0.0.1:6379> LSET mylist 3 k6 # 将下标3的元素 set值为k6
OK
127.0.0.1:6379> LRANGE mylist 0 -1
1) "k5"
2) "k4"
3) "k2"
4) "k6"
5) "k1"
6) "k3"

---------------------------LPOP--RPOP--------------------------

127.0.0.1:6379> LPOP mylist # 左侧(头部)弹出
"k5"
127.0.0.1:6379> RPOP mylist # 右侧(尾部)弹出
"k3"

---------------------------RPOPLPUSH--------------------------

127.0.0.1:6379> LRANGE mylist 0 -1
1) "k4"
2) "k2"
3) "k6"
4) "k1"
127.0.0.1:6379> RPOPLPUSH mylist newlist # 将mylist的最后一个值(k1)弹出,加入到newlist的头部
"k1"
127.0.0.1:6379> LRANGE newlist 0 -1
1) "k1"
127.0.0.1:6379> LRANGE mylist 0 -1
1) "k4"
2) "k2"
3) "k6"

---------------------------LTRIM--------------------------

127.0.0.1:6379> LTRIM mylist 0 1 # 截取mylist中的 0~1部分
OK
127.0.0.1:6379> LRANGE mylist 0 -1
1) "k4"
2) "k2"

# 初始 mylist: k2,k2,k2,k2,k2,k2,k4,k2,k2,k2,k2
---------------------------LREM--------------------------

127.0.0.1:6379> LREM mylist 3 k2 # 从头部开始搜索 至多删除3个 k2
(integer) 3
# 删除后:mylist: k2,k2,k2,k4,k2,k2,k2,k2

127.0.0.1:6379> LREM mylist -2 k2 #从尾部开始搜索 至多删除2个 k2
(integer) 2
# 删除后:mylist: k2,k2,k2,k4,k2,k2


---------------------------BLPOP--BRPOP--------------------------

mylist: k2,k2,k2,k4,k2,k2
newlist: k1

127.0.0.1:6379> BLPOP newlist mylist 30 # 从newlist中弹出第一个值,mylist作为候选
1) "newlist" # 弹出
2) "k1"
127.0.0.1:6379> BLPOP newlist mylist 30
1) "mylist" # 由于newlist空了 从mylist中弹出
2) "k2"
127.0.0.1:6379> BLPOP newlist 30
(30.10s) # 超时了

127.0.0.1:6379> BLPOP newlist 30 # 我们连接另一个客户端向newlist中push了test, 阻塞被解决。
1) "newlist"
2) "test"
(12.54s)

小结

  • list实际上是一个链表,before Node after , left, right 都可以插入值
  • 如果key不存在࿰
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值