Redis的简单用法

本文最后更新于:2020年5月17日 晚上

概览:Redis介绍、Redis应用场景、Redis的安装与配置、Redis常用语法。

教程视频链接:2020最新Python(MySQL_SQL_Redis)数据库详解【千锋】50集到60集

Redis命令: http://redisdoc.com/

预警:本文仅作为Redis的简单了解。

NoSQL

非关系型数据库。

常见的几个数据库

  • 列族数据库:HBase
  • 文档数据库:MongoDB
  • KV数据库:Redis

数据库指标 qps:

Redis

一种基于键值对的NoSQL数据库

  • 将数据存放于内存,读写性能极高,并具有丰富的特性(发布/订阅、事务、通知等)。
  • 适用于项目中的高速缓存与消息队列这样的服务。
  • 支持数据的持久化,可将内存中的数据保存在磁盘中,重启时可再次加载使用。
  • 支持多种数据类型,包括:string、hash、list、set、zset(有序集合)、bitmap、hyperloglog等。
  • Redis支持主从复制(实现读写分析)以及哨兵模式(监控master是否宕机并自动调整配置)。
  • Redis支持分布式集群,可以很容易的通过水平扩展来提升系统的整体性能。
  • Redis基于TCP提供的可靠传输服务进行通信,很多编程语言都提供了Redis客户端支持。

Redis应用场景

  1. 高速缓存:将不常变化但又经常被访问的热点数据放到Redis数据库中,可以大大降低关系型数据库的压力,从而提升系统的响应性能。
  2. 排行榜:很多网站都有排行榜功能,利用Redis中的列表和有序集合可以非常方便的构造各种排行榜系统。
  3. 商品秒杀/投票点赞:Redis提供了对计数操作的支持,网站上常见的秒杀、点赞等功能都可以利用Redis的计数器通过+1或1的操作来实现,从而避免了使用关系型数据的update操作。
  4. 分布式锁:利用Redis可以跨多台服务器实现分布式锁(类似于线程锁,但是能够被多台机器上的多个线程或进程共享)的功能,用于实现一个阻塞式操作。
  5. 消息队列:消息队列和高速缓存一样, 是一个大型网站不可缺少的基础服务,可以实现业务解耦和非实时业务削峰等特性。

安装

1
2
3
4
5
6
7
wget http://download.redis.io/releases/redis-6.0.1.tar.gz

tar -zxvf redis-6.0.1.tar.gz

cd redis-6.0.1/

sudo make && sudo make install

Redis的配置

1
2
3
cd redis-6.0.1/

vim redis.conf #配置文件

1.配置Redis服务绑定到指定的IP地址和端口

1
2
bind 127.0.0.1
port 6379

2.配置后台运行(以守护进程方式运行)

1
daemonize yes

3.设置日志级别,可选值(debug:调试,verbose:详细,notice:通知,warning:警告)

1
loglevel warning

4.配置数据库的数量,默认16个

1
databases 16

5.配置数据写入规则

1
2
3
save 900 1		# 900秒内修改过1个key,写入一次数据库
save 300 10 # 300秒内修改过10个key,写入一次数据库
save 60 1000 # 60秒内修改过10000个key,写入一次数据库

6.配置Redis的持久化机制 - RDB.

1
2
3
4
rdbcompression yes		# 压缩RDB文件
rdbchecksum yes # 对RDB文件进行校验
dbfilename dump.rdb # RDB数据库文件的文件名
dir /var/local/redis # RDB文件保存的目录

7.配置Redis的持久化机制 - AOF.

1
2
appendonly no
appendfilename "appendonly.aof"

8.配置Redis的主从复制,通过主从复制可以实现读写分离

1
replicaof 主机IP地址 主机端口

9.配置慢查询

1
2
slowlog-log-slower-than 10000 	# 一次操作超过10000毫秒被视作一次慢查询
slowlog-max-len 128 # 最多记录128次慢查询

修改完配置项目后,建议将配置项目拷贝到一个地方,记住路径!

Redis启动

1
2
3
4
5
6
7
8
9
# 服务端启动
redis-server

redis-server /usr/local/etc/redis.conf #指定配置项,建议这种方式

# 客户端启动
redis-cli

redis-cli -h localhost -p 6379

linux查询进程

1
ps aux|grep redis

Redis持久化

Redis运行时,所有数据都保存在内存中,进程结束以后,会将数据写入硬盘中,启动Redis时,会读取硬盘中的内容,并将内容全部加载到内存中(会大量占用内存)。

Redis持久化两种方式:

  • RDB方式:默认的方式,对内存中的数据进行镜像,并以二进制的形式保存到dump.rdb文件中,会根据配置文件中的填写的时间节点对文件进行持久化。

    1
    2
    3
    4
    # 这个就是时间节点
    save 900 1 # 900秒内修改过1个key,写入一次数据库
    save 300 10 # 300秒内修改过10个key,写入一次数据库
    save 60 1000 # 60秒内修改过10000个key,写入一次数据库
    • 优点:速度快,直接镜像内存中的数据,文件小。
    • 缺点:数据可能会丢失,在两次保存间隔内的数据,有可能会丢失。
  • AOF方式:将修改的每一条指令记录进appendonly.aof中。

    • appendfsync always:每次有新命令追加到aof文件时就执行一个持久化,非常慢但是安全。
    • appendfsync everysec:每秒执行一次持久化,足够快(和rdb差不多),并且在故障时只会丢失一秒的数据。
    • appendsync no:从不持久化,将数据交给操作系统来处理,redis处理命令速度快但不安全。
    • 优点:适合保存增量数据,数据不丢失
    • 缺点:文件体积大,恢复时间长。

Redis字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#set key values [ex seconds|px millinsecond]
set name zhnagsan # "name':"zhangsan"

set name colourso # "name":"colourso" 会覆盖上一条

127.0.0.1:6379> setnx name wangwu # setnx 如果key存在则不进行操作
(integer) 0

127.0.0.1:6379> get name
"colourso"

127.0.0.1:6379> strlen name # 获取key对应value的长度
(integer) 8
---
127.0.0.1:6379> set x 23 # 虽然存储的是字符串但是能够像数字一样操作

127.0.0.1:6379> get x
"23"
---
127.0.0.1:6379> keys * # 获取所有的key
1) "name"
2) "x"
---
127.0.0.1:6379> set keywords IOU ex 20 # ex后接秒数,表示存在时间

127.0.0.1:6379> get keywords
"IOU"

127.0.0.1:6379> ttl keywords # ttl 可查看过期剩余时间
(integer) 12 # ttl查询结果为-1表示永不过期

--- 等待15秒后
127.0.0.1:6379> get keywords
(nil)

---
127.0.0.1:6379> mset p 10 q 30 #一次设置多个值
---
127.0.0.1:6379> set nu 1

127.0.0.1:6379> incr nu
(integer) 2
127.0.0.1:6379> set nn 1.1

127.0.0.1:6379> incr nn
(error) ERR value is not an integer or out of range

127.0.0.1:6379> incrby nu 11
(integer) 13

127.0.0.1:6379> decr nu
(integer) 12
  • set :设置key value
  • setnx : 如果key不存在就设置
  • mset:一次设置多个值
  • get:获取key对应的value
  • mget:一次获取多个值
  • strlen :获取key对应value的长度
  • incr:自增,非整数数字无法自增,会报错
  • incrby:key对应的value值增加一定的量
  • decr:减一

Redis哈希表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
127.0.0.1:6379> hset dog name kelly color white
(integer) 2

127.0.0.1:6379> hget dog name
"kelly"

127.0.0.1:6379> hset dog age 3 gender female #继续向dog中添加
(integer) 2

127.0.0.1:6379> HEXISTS dog color #查看dog是否有color属性,有为1,没有为0
(integer) 1

127.0.0.1:6379> HEXISTS dog height
(integer) 0

127.0.0.1:6379> hdel dog gender #删除一个属性
(integer) 1

127.0.0.1:6379> hget dog gender
(nil)

127.0.0.1:6379> hlen dog #查看有几个属性
(integer) 3

127.0.0.1:6379> hstrlen dog name #查看属性的具体长度
(integer) 5

127.0.0.1:6379> hkeys dog #拿到dog所有的属性名
1) "name"
2) "color"
3) "age"

127.0.0.1:6379> hvals dog #拿到dog所有的属性值
1) "kelly"
2) "white"
3) "3"

127.0.0.1:6379> hgetall dog #拿到全部
1) "name"
2) "kelly"
3) "color"
4) "white"
5) "age"
6) "3"
  • hset key [field value]:创建一个hash形式大致如下:

    “dog”:{

    “name”:”kelly”,

    “color”:”white”,

    “age”:3,

    “gender”:”female”

    }

Redis列表

Redis中的列表可以实现类似于队列与栈的结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
127.0.0.1:6379> lpush names zhangsan lisi wangwu #依次往左插入数据!
(integer) 3

127.0.0.1:6379> lrange names 0 -1 # 获取一个范围的元素,-1表示最后一个元素
1) "wangwu" # 按照顺序获得元素
2) "lisi"
3) "zhangsan"

127.0.0.1:6379> rpush english bob kelly tom kelly # 依次往右插入数据,列表值允许重复
(integer) 4

127.0.0.1:6379> lrange english 0 -1 # 按照顺序获得元素
1) "bob"
2) "kelly"
3) "tom"
4) "kelly"

127.0.0.1:6379> lpop english # 取走最左侧数据,不再保留
"bob"

127.0.0.1:6379> lrange english 0 -1
1) "kelly"
2) "tom"
3) "kelly"

127.0.0.1:6379> lset english 2 carry # 修改index对应的值,下标从0开始
OK

127.0.0.1:6379> lrange english 0 -1
1) "kelly"
2) "tom"
3) "carry"

127.0.0.1:6379> llen english #获取长度
(integer) 3

127.0.0.1:6379> lindex english 1 # 获取下标对应的值
"tom"

Redis集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
127.0.0.1:6379> sadd player liubei guanyu zhangfei
(integer) 3

127.0.0.1:6379> sadd player caocao sunquan # 往player集合中添加成员
(integer) 2

127.0.0.1:6379> sismember player liubei
(integer) 1

127.0.0.1:6379> sismember player machao # 判断machao是都是集合Player的成员,是的话输出1,不是输出0
(integer) 0

127.0.0.1:6379> srandmember player 3 #随机取三个成员
1) "caocao"
2) "zhangfei"
3) "sunquan"

127.0.0.1:6379> smembers player #查看全部成员
1) "guanyu"
2) "liubei"
3) "caocao"
4) "zhangfei"
5) "sunquan"

127.0.0.1:6379> sadd superplayer caocao liubei sunquan
(integer) 3

127.0.0.1:6379> sdiff player superplayer # 返回player中与superplayer中不一样的部分
1) "guanyu"
2) "zhangfei"

127.0.0.1:6379> sunion player superplayer # 两个集合的并集
1) "guanyu"
2) "liubei"
3) "caocao"
4) "zhangfei"
5) "sunquan"

127.0.0.1:6379> sinter player superplayer # 两个集合的交集
1) "liubei"
2) "sunquan"
3) "caocao"

Redis有序集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
127.0.0.1:6379> zadd score 100 liubang 90 xiangyu 80 hanxin # score是key
(integer) 3

127.0.0.1:6379> zrange score 0 -1 # 顺序输出,由小到大
1) "hanxin"
2) "xiangyu"
3) "liubang"

127.0.0.1:6379> zrank score xiangyu # 查看xiangyu的排序
(integer) 1

127.0.0.1:6379> ZREVRANGE score 0 -1 # 逆序输出
1) "liubang"
2) "xiangyu"
3) "hanxin"

127.0.0.1:6379> ZREVRANGE score 0 -1 withscores # 逆序输出,并打印数据
1) "liubang"
2) "100"
3) "xiangyu"
4) "90"
5) "hanxin"
6) "80"

127.0.0.1:6379> zincrby score 5 xiangyu #给xiangyu增加5
"95"

在Python中安装与使用Redis

安装:pip3 install redis

1
2
3
4
5
6
7
8
9
10
11
12
13
import redis

client = redis.Redis()#不写参数就使用其默认配置

client.get("name")
# b'colourso'
# b表示为二进制

client.hget("dog","name")
# {b'name': b'kelly', b'color': b'white', b'age': b'3'}

client.zrange("score",0,-1)
# [b'hanxin', b'xiangyu', b'liubang']

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!