一、redis搭建
1.下载软件包
下载Redis可以去Redis官网获取源码包,下载到服务器上编译。Redis官网(https://redis.io/)。进入下载页面(https://redis.io/download),从左到右分别是最新版、最新稳定版和容器版,我们可以下载最新稳定版的源码包(https://download.redis.io/releases/redis-6.0.9.tar.gz)。
[root@db01 ~]# rz redis-6.0.9.tar.gz
或者
[root@redis01 ~]# wget https://download.redis.io/releases/redis-6.0.9.tar.gz
2.安装依赖
[root@redis01 ~]# yum install -y cpp binutils glibc glibc-kernheaders glibc-common glibc-devel gcc make tcl
3 更新gcc版本
centos7 默认的 gcc 版本小于 5.3 无法编译,需要先安装gcc新版才能编译
[root@redis01 ~]# yum -y install centos-release-scl
[root@redis01 ~]# yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
#临时生效,退出 shell 或重启会恢复原 gcc 版本
[root@redis01 ~]# scl enable devtoolset-9 bash
#永久生效
[root@redis01 ~]# echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
4 .编译安装
[root@redis01 ~]# tar -zxvf redis-6.0.9.tar.gz
[root@redis01 ~]# mv redis-6.0.9 /usr/local/
[root@redis01 ~]# cd /usr/local/redis-6.0.9
[root@redis01 /usr/local/redis-6.0.9]# make &&make install #默认安装
或者
[root@redis01 ~]# make PREFIX=/usr/local/redis-6.0.9 install #指定目录安装
5.做软连接
[root@redis01 /usr/local/redis-6.0.9]# cd ..
[root@redis01 /usr/local]# ln -s /usr/local/redis-6.0.9 /usr/local/redis
6.修改redis.conf
[root@redis01 /usr/local]# cd redis
[root@redis01 /usr/local/redis]# mkdir /etc/redis/
[root@redis01 /usr/local/redis]# cp redis.conf /etc/redis/
[root@redis01 ~/redis-6.0.9]# vim /etc/redis/redis.conf
bind 127.0.0.1 #根据情况是否需要远程访问去掉注释
requirepass 123456 #修改密码
protected-mode no # 关闭protected-mode模式,此时外部网络可以直接访问
daemonize no #以守护进程模式启动,指定目录安装时改为yes
7. 配置system启动
[root@redis01 /usr/local/redis]# vim /etc/systemd/system/redis.service
[Unit]
Description=Redis
After=network.target
[Service]
#Type=forking
ExecStart=/usr/local/redis-6.0.9/src/redis-server /etc/redis/redis.conf
ExecReload=/usr/local/redis-6.0.9/src/redis-server -s reload
ExecStop=/usr/local/redis-6.0.9/src/redis-server -s stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target
注意Type=forking不注释掉 服务无法启动
使服务自动运行
[root@redis01 ~]# systemctl daemon-reload
[root@redis01 ~]# systemctl enable redis
启动服务
[root@redis01 ~]# systemctl restart redis
[root@redis01 ~]# systemctl status redis
验证服务
[root@redis01 /usr/local/redis]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 12768/redis-server
8.连接redis
#连接
[root@redis01 /usr/local/redis]# redis-cli -p 6379
127.0.0.1:6379> auth 123456 #验证密码
127.0.0.1:6379>
9.关闭redis
[root@redis01 /usr/local/redis]# redis-cli shutdown
或
[root@db01 redis]# redis-cli
127.0.0.1:6379> shutdown
二、redis配置文件
1.配置
#默认的配置文件
[root@redis01 redis]# pwd
/usr/local/redis
[root@redis01 redis]# ll
-rw-rw-r-- 1 root root 46695 Jun 13 2018 redis.conf
#创建reids配置文件目录
[root@redis01 redis]# mkdir /service/redis/6379 -p
#编写配置文件
[root@redis01 redis]# vim /service/redis/6379/redis.conf
bind 172.16.1.51 127.0.0.1 #监听地址
port 6379 #端口
daemonize no #后台启动
pidfile /service/redis/6379/redis_6379.pid #指定pid文件
loglevel notice #指定日志级别
logfile /service/redis/6379/redis_6379.log #指定日志文件
2.指定配置文件启动
[root@redis01 redis]# redis-server /service/redis/6379/redis.conf
三、redis操作
1.基本操作
1.连接redis
[root@db01 redis]# redis-cli
127.0.0.1:6379>
2.查看所有数据
127.0.0.1:6379> keys *
(empty list or set)
#查看时注意不要轻易使用,如想查看数据,先查看数据量DBSIZE
127.0.0.1:6379> DBSIZE
(integer) 2018041
3.添加数据
127.0.0.1:6379> set k1 v1
OK
4.查看数据
127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379> get k1
"v1"
5.删除数据
127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379> DEL k1
(integer) 1
127.0.0.1:6379> keys *
(empty list or set)
6.修改数据
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k1 v11111
OK
127.0.0.1:6379> get k1
"v11111"
7.追加数据
127.0.0.1:6379> APPEND k1 000000
(integer) 12
127.0.0.1:6379> get k1
"v11111000000"
8.切换库
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> SELECT 2
OK
127.0.0.1:6379[2]> SELECT 3
OK
127.0.0.1:6379> SELECT 16
(error) ERR invalid DB index
2.密码的设置
1.配置文件配置密码
[root@db01 redis]# vim redis.conf
requirepass 123
2.使用密码连接
[root@db01 redis]# redis-cli -a 123
3.登陆后输入密码
[root@db01 redis]# redis-cli
127.0.0.1:6379> AUTH 123
OK
127.0.0.1:6379> DBSIZE
(integer) 2018041
4.redis连接后获取密码
127.0.0.1:6379> CONFIG GET requirepass
1) "requirepass"
2) "123"
5.redis连接后修改密码
127.0.0.1:6379> CONFIG set requirepass 234
OK
[root@db01 redis]# redis-cli
127.0.0.1:6379> DBSIZE
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth 123
(error) ERR invalid password
127.0.0.1:6379> auth 234
OK
3.通用操纵
1.判断key是否存在
127.0.0.1:6379> EXISTS k1
(integer) 1 #存在则返回1
127.0.0.1:6379> EXISTS k2
(integer) 0 #不存在则返回0
2.修改key的名字
127.0.0.1:6379> KEYS *
1) "k1"
127.0.0.1:6379> RENAME k1 k100
OK
127.0.0.1:6379> KEYS *
1) "k100"
3.查看数据类型
127.0.0.1:6379> TYPE k100
string
4.设置生存时间
#以秒为单位
127.0.0.1:6379> EXPIRE qiudao 10
(integer) 1
#以毫秒为单位
127.0.0.1:6379> PEXPIRE k100 10000
(integer) 1
5.查看生存时间
127.0.0.1:6379> TTL k100
(integer) 1 #正整数生存时间倒计时
127.0.0.1:6379> TTL k100
(integer) -1 #-1代表没有设置生存时间
127.0.0.1:6379> TTL k100
(integer) -2 #代表设置过生存时间已删除,已过期
6.取消生存时间
127.0.0.1:6379> TTL qiudao
(integer) 93
127.0.0.1:6379> PERSIST qiudao
(integer) 1
127.0.0.1:6379> TTL qiudao
(integer) -1
四、Redis数据持久化
1.Redis数据安全问题
前面我们提到,Redis是一个缓存中间件,它的最大特点是使用内存从而使其性能强悍。但是使用内存的方式有一个致命的特点就是数据没办法持久化保存。然而Redis持久化存储有两种持久化方案,RDB(Redis DataBase)和 AOF(Append-Only File)。其中RDB是将内存中的数据进行快照存储到磁盘,AOF则为可回放的命令日志记录redis内的所有操作。它们各有特点也相互独立。Redis4之后支持RDB-AOF混合持久化的方式,结合了两者的优点,可以通过 aof-use-rdb-preamble 配置项可以打开混合开关。
2.什么是持久化
将内存中的数据写入到磁盘,永久保存
3.持久化的模式
1.RDB模式
2.AOF模式
4.快照持久化(RDB)
1) RDB概述
RDB(Redis DataBase)是将Redis内存中的数据进行Snaptshot快照存储在磁盘内,是Redis的默认持久化方案。使用RDB持久化默认有三种策略,该持久化策略在redis.conf中可配置,会以一段时间内有指定次数据修改的规则触发快照动作,快照文件名为dump.rdb,该文件默认使用LZF压缩算法 。每当Redis服务重启的时候会从该文件中加载数据进内存。
RDB持久化除了可以根据配置中的策略触发,也可以手动触发,使用save和bgsave命令即可。这两个命令的区别的save会阻塞服务器进程,在进行save的过程中,服务器不能处理任何请求,而bgsave会通过一个子进程在后台处理rdb持久化。事实上save和bgsave调用的都是rdbSave函数,因此Redis不允许save和bgsave同时运行,这也是为了避免出现竞争导致rdb文件数据不准确。
bgsave操作使用CopyOnWrite机制进行写时复制,是由一个子进程将内存中的最新数据遍历写入临时文件,此时父进程仍旧处理客户端的操作,当子进程操作完毕后再将该临时文件重命名为dump.rdb替换掉原来的dump.rdb文件,因此无论bgsave是否成功,dump.rdb都不会受到影响。
另外在主从全量同步、debug reload以及shutdown的情况下也会触发RDB数据持久化。
2)RDB模式
可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)
3)RDB工作模式
1.默认情况下,Redis保存数据集快照到磁盘,名为dump.rdb的二进制文件。你可以设置让Redis在N秒内至少有M次数据集改动时保存数据集,或者你也可以手动调用SAVE或者BGSAVE命令。
2.在上文中我们已经在配置文件中做过对应的配置:
例如,这个配置会让Redis在每个60秒内至少有1000次键改动时自动转储数据集到磁盘:
save 60 1000
3.当 Redis 需要保存 dump.rdb 文件时,服务器执行以下操作:
Redis 调用 fork() ,同时拥有父进程和子进程。
子进程将数据集写入到一个临时的 RDB 文件中。当子进程完成对新 RDB 文件的写入时, Redis 用新RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
4.这种方式使得 Redis 可以从写时复制机制中获益。
4) 快照持久化快照相关配置
#编辑配置文件
[root@db01 ~]# vim /service/redis/6379/redis.conf
bind 172.16.1.51 127.0.0.1
port 6379
daemonize yes
pidfile /service/redis/6379/redis_6379.pid
loglevel notice
logfile /service/redis/6379/redis_6379.log
requirepass 123
dir "/etc/redis"
dbfilename dump.rdb
stop-write-on-bgsave-error yes
rdbchecksum yes
rdbcompression yes
save 900 1
save 300 10
save 60 10000
save m n
#配置快照(rdb)促发规则,格式:save <seconds> <changes>
#save 900 1 900秒内至少有1个key被改变则做一次快照
#save 300 10 300秒内至少有300个key被改变则做一次快照
#save 60 10000 60秒内至少有10000个key被改变则做一次快照
#关闭该规则使用svae “”
dbfilename dump.rdb
#rdb持久化存储数据库文件名,默认为dump.rdb
stop-write-on-bgsave-error yes
#yes代表当使用bgsave命令持久化出错时候停止写RDB快照文件,no表明忽略错误继续写文件。
rdbchecksum yes
#在写入文件和读取文件时是否开启rdb文件检查,检查是否有无损坏,如果在启动是检查发现损坏,则停止启动。
dir "/etc/redis"
#数据文件存放目录,rdb快照文件和aof文件都会存放至该目录,请确保有写权限
rdbcompression yes
#是否开启RDB文件压缩,该功能可以节约磁盘空间、
5)使用RDB文件
1.先停止redis
2.将rdb文件放到指定目录下
3.启动redis
6) RDB优点
1.RDB是一种表示某个即时点的Redis数据的紧凑文件。RDB文件适合用于备份。例如,你可能想要每小时归档最近24小时的RDB文件,每天保存近30天的RDB快照。这允许你很容易的恢复不同版本的数据集以容灾。
2.RDB非常适合于灾难恢复,作为一个紧凑的单一文件,可以被传输到远程的数据中心。
3.RDB最大化了Redis的性能,因为Redis父进程持久化时唯一需要做的是启动(fork)一个子进程,由子进程完成所有剩余工作。父进程实例不需要执行像磁盘IO这样的操作。
4.RDB在重启保存了大数据集的实例时比AOF要快。
7)RDB缺点
1.当你需要在Redis停止工作(例如停电)时最小化数据丢失,RDB可能不太好。你可以配置不同的保存点(save point)来保存RDB文件(例如,至少5分钟和对数据集100次写之后,但是你可以有多个保存点)。然而,你通常每隔5分钟或更久创建一个RDB快照,所以一旦Redis因为任何原因没有正确关闭而停止工作,你就得做好最近几分钟数据丢失的准备了。
2.RDB需要经常调用fork()子进程来持久化到磁盘。如果数据集很大的话,fork()比较耗时,结果就是,当数据集非常大并且CPU性能不够强大的话,Redis会停止服务客户端几毫秒甚至一秒。AOF也需要fork(),但是你可以调整多久频率重写日志而不会有损(trade-off)持久性(durability)。
8) RDB优缺点总结
优点:速度快,适合于用作备份,主从复制也是基于RDB持久化功能实现的。
缺点:会有数据丢失、导致服务停止几秒
9)停止备份
在配置文件中就设置save “”或在命令行中 config set save “”。
10) 手动开始备份
save:会立即生成dump.rdb,但是会阻塞往redis内存中写入数据。
bgsave:后台异步备份。
如果是使用flushdb命令,会把之前的快照更新成当前的空状态,所以执行了flushdb后更新的快照是没有数据的。
11) save与bgsave对比
命令 |
save |
bgsave |
IO类型 |
同步 |
异步 |
是否阻塞 |
是 |
否(阻塞发生在fork) |
优点 |
不会消耗额外内存 |
不阻塞客户端命令 |
缺点 |
阻塞客户端命令 |
创建fork,消耗内存 |
5. AOF持久化
AOF(Append-Only File)记录Redis中每次的写命令,类似mysql中的binlog,服务重启时会重新执行AOF中的命令将数据恢复到内存中,RDB(按策略持久化)持久化方式记录的粒度不如AOF(记录每条写命令),因此很多生产环境都是开启AOF持久化。AOF中记录了操作和数据,在日志文件中追加完成后才会将内存中的数据进行变更。
AOF(append only file)只追加文件,记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。
1)AOF原理
1.客户端的请求写命令会被append追加到AOF缓冲区内;
2.AOF缓冲区根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中;
3.AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量;
4.Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的;
2) AOF配置
开启了AOF之后,RDB就默认不使用了。使用下面的配置开启AOF以及策略。(如果使用AOF,推荐选择always方式持久化,否则在高并发场景下,每秒钟会有几万甚至百万条请求,如果使用everysec的方式的话,万一服务器挂了那几万条数据就丢失了)。
#开启AOF持久化
appendonly yes
#AOF文件名
appendfilename "appendonly.aof"
#AOF文件存储路径 与RDB是同一个参数
dir "/opt/app/redis6/data"
#AOF策略,一般都是选择第一种[always:每个命令都记录],[everysec:每秒记录一次],[no:看机器的心情高兴了就记录]
appendfsync always
#appendfsync everysec
# appendfsync no
#aof文件大小比起上次重写时的大小,增长100%(配置可以大于100%)时,触发重写。[假如上次重写后大小为10MB,当AOF文件达到20MB时也会再次触发重写,以此类推]
auto-aof-rewrite-percentage 100
#aof文件大小超过64MB时,触发重写
auto-aof-rewrite-min-size 64mb
#是否在后台写时同步单写,默认值no(表示需要同步).这里的后台写,表示后台正在重写文件(包括bgsave和bgrewriteaof.bgrewriteaof网上很多资料都没有涉及到。其实关掉bgsave之后,主要的即是aof重写文件了).no表示新的主进程的set操作会被阻塞掉,而yes表示新的主进程的set不会被阻塞,待整个后台写完成之后再将这部分set操作同步到aof文件中。但这可能会存在数据丢失的风险(机率很小),如果对性能有要求,可以设置为yes,仅在后台写时会异步处理命令.
no-appendfsync-on-rewrite no
# 指redis在恢复时,会忽略最后一条可能存在问题的指令。默认值yes。即在aof写入时,可能存在指令写错的问题(突然断电,写了一半),这种情况下,yes会log并继续,而no会直接恢复失败.
aof-load-truncated
3)AOF持久化策略
AOF分别有三种备份策略,分别是[always:每个命令都记录],[everysec:每秒记录一次],[no:看机器的心情高兴了就记录],针对这三种策略给出如下说明。
4)策略说明
策略 |
说明 |
优点 |
always |
每次执行,都会持久化到AOF文件中 |
不丢失数据 |
everysec |
每秒持久化一次 |
减少IO |
no |
根据服务器性能持久化 |
全自动 |
5)策略抉择
命令 |
Always |
Everysec |
no |
优点 |
不丢失数据 |
每秒一次fsync,减少IO |
不用管,全自动 |
缺点 |
IO开销大 |
丢1秒钟的数据 |
不可控 |
6)AOF模式的优点
1.使用AOF Redis会更具有可持久性(durable):你可以有很多不同的fsync策略:没有fsync,每秒fsync,每次请求时fsync。使用默认的每秒fsync策略,写性能也仍然很不错(fsync是由后台线程完成的,主线程继续努力地执行写请求),即便你也就仅仅只损失一秒钟的写数据。
2.AOF日志是一个追加文件,所以不需要定位,在断电时也没有损坏问题。即使由于某种原因文件末尾是一个写到一半的命令(磁盘满或者其他原因),redis-check-aof工具也可以很轻易的修复。
3.当AOF文件变得很大时,Redis会自动在后台进行重写。重写是绝对安全的,因为Redis继续往旧的文件中追加,使用创建当前数据集所需的最小操作集合来创建一个全新的文件,一旦第二个文件创建完毕,Redis就会切换这两个文件,并开始往新文件追加。
4.AOF文件里面包含一个接一个的操作,以易于理解和解析的格式存储。你也可以轻易的导出一个AOF文件。例如,即使你不小心错误地使用FLUSHALL命令清空一切,如果此时并没有执行重写,你仍然可以保存你的数据集,你只要停止服务器,删除最后一条命令,然后重启Redis就可以。
7)AOF重写
1.因为 AOF 的运作方式是不断地将命令追加到文件的末尾,所以随着写入命令的不断增加, AOF 文件的体积也变得越来越大。举个例子,如果你对一个计数器调用了 100 次 INCR ,那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录。然而在实际上,只使用一条 SET 命令已经足以保存计数器的当前值了,其余 99 条记录实际上都是多余的。
2.为了处理这种情况, Redis 支持一种有趣的特性:可以在不断服务客户端的情况下,对 AOF 文件进行重建。执行 BGREWRITEAOF 命令, Redis 将生产一个新的 AOF 文件,这个文件包含重建当前数据集所需的最少命令。
8) AOF重写配置
配置名 |
含义 |
appendonly |
开启AOF持久化功能 |
auto-aof-rewrite-min-size |
触发重写的最小尺寸 |
auto-aof-rewrite-percentage |
AOF文件增长率 |
aof_current_size |
AOF当前尺寸 |
aof_base_size |
AOF上次启动和重写的尺寸(单位:字节) |
9) AOF重写触发机制
根据配置,AOF持久化触发机制如下:
1.aof_current_size > auto-aof-rewrite-min-size
2.(aof_current_size - aof_base_size) / aof_base_size > auto-aof-rewrite-percentage
10) AOF重写流程
12)AOF持久化缺点
1.对同样的数据集,AOF文件通常要大于等价的RDB文件。
2.AOF可能比RDB慢,这取决于准确的fsync策略。通常fsync设置为每秒一次的话性能仍然很高,如果关闭fsync,即使在很高的负载下也和RDB一样的快。不过,即使在很大的写负载情况下,RDB还是能提供能好的最大延迟保证。
3.在过去,我们经历了一些针对特殊命令(例如,像BRPOPLPUSH这样的阻塞命令)的罕见bug,导致在数据加载时无法恢复到保存时的样子。这些bug很罕见,我们也在测试套件中进行了测试,自动随机创造复杂的数据集,然后加载它们以检查一切是否正常,但是,这类bug几乎不可能出现在RDB持久化中。为了说得更清楚一点:Redis AOF是通过递增地更新一个已经存在的状态,像MySQL或者MongoDB一样,而RDB快照是一次又一次地从头开始创造一切,概念上更健壮。
但是,
1)要注意Redis每次重写AOF时都是以当前数据集中的真实数据从头开始,相对于一直追加的AOF文件(或者一次重写读取老的AOF文件而不是读内存中的数据)对bug的免疫力更强。
2)我们还没有收到一份用户在真实世界中检测到崩溃的报告。
13)AOF持久化优缺点总结
优点:可以最大程度保证数据不丢失
缺点:日志记录量级比较大
6.RDB与AOF抉择
1) RDB与AOF比较
命令 |
RDB |
AOF |
启动优先级 |
低 |
高 |
体积 |
小 |
大 |
恢复速度 |
快 |
慢 |
数据安全性 |
丢数据 |
根据策略的不同,丢数据的情况也不同 |
轻重 |
重 |
轻 |
2) RDB与AOF之间的优劣势
#1.RDB的优点
1.压缩后的二进制文件,适用于备份、全量复制及灾难恢复。
2.RDB恢复数据性能优于AOF方式。
#2.RDB的缺点
1.无法做到实时持久化,每次都要创建子进程,频繁操作成本过高
2.保存后的二进制文件,不同版本直接存在兼容性问题
#3.AOF的优点
1.以文本形式保存,易读
2.记录写操作保证数据不丢失
#4.AOF的缺点
1.存储所有写操作命令,且文件为文本格式保存,未经压缩,文件体积高。
2.恢复数据时重放AOF中所有代码,恢复性能弱于RDB方式。
7. AOF与RDB混合
看了上面的RDB和AOF的介绍后,我们可以发现,使用RDB持久化会有数据丢失的风险,但是恢复速度快,而使用AOF持久化可以保证数据完整性,但恢复数据的时候会很慢。于是从Redis4之后新增了混合AOF和RDB的模式,先使用RDB进行快照存储,然后使用AOF持久化记录所有的写操作,当重写策略满足或手动触发重写的时候,将最新的数据存储为新的RDB记录。这样的话,重启服务的时候会从RDB何AOF两部分恢复数据,即保证了数据完整性,又提高了恢复的性能。
开启混合模式后,每当bgrewriteaof命令之后会在AOF文件中以RDB格式写入当前最新的数据,之后的新的写操作继续以AOF的追加形式追加写命令。当redis重启的时候,加载 aof 文件进行恢复数据:先加载 rdb 的部分再加载剩余的 aof部分。
1)混合配置
修改下面的参数即可开启AOF,RDB混合持久化
aof-use-rdb-preamble yes
2) 混合模式的使用
开启混合持久化模式后,重写之后的aof文件里和rdb一样存储二进制的快照数据,继续往redis中进行写操作,后续操作在aof中仍然是以命令的方式追加。因此重写后aof文件由两部分组成,一部分是类似rdb的二进制快照,另一部分是追加的命令文本。
# step: 进入Redis, 写入数据
[root@alvin-test-os redis]# redis-cli --raw
127.0.0.1:6379> set name alvin
OK
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> set add 上海
OK
127.0.0.1:6379> exit
# Step 2: 查看备份文件
[root@alvin-test-os redis]# ll data/
总用量 8
-rw-r--r--. 1 root root 121 11月 24 15:39 appendonly.aof
-rw-r--r--. 1 root root 116 11月 24 15:39 dump.rdb
[root@alvin-test-os redis]# cat data/appendonly.aof | grep add
add
[root@alvin-test-os redis]# cat data/appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$4
name
$5
alvin
*3
$3
set
$3
age
$2
18
*3
$3
set
$3
add
$6
上海
# Step 3: 启动备份
[root@alvin-test-os redis]# redis-cli --raw
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
127.0.0.1:6379> exit
# Step 4: 查看配置文件发现AOF备份文件变成了二进制文件
[root@alvin-test-os redis]# cat data/appendonly.aof
REDIS0009� redis-ver6.0.9�
�edis-bits�@�ctime��_used-mem��4
aof-preamble���namealvinadd上海age���6����&[root@alvin-test-os redis]#
# Step 5: 再次写入文件
[root@alvin-test-os redis]# redis-cli --raw
127.0.0.1:6379> set company 上海
OK
127.0.0.1:6379> exit
# Step 6:再次查看备份文件发现被分成了两份,一份二进制,一份AOF备份
[root@alvin-test-os redis]# cat data/appendonly.aof
REDIS0009� redis-ver6.0.9�
�edis-bits�@�ctime��_used-mem��4
aof-preamble���namealvinadd上海age���6����&*2
$6
SELECT
$1
0
*3
$3
set
$7
company
$15
上海
[root@alvin-test-os redis]#
3)备份Redis数据
1.Redis 对于数据备份是非常友好的,因为你可以在服务器运行的时候对 RDB 文件进行复制: RDB 文件一旦被创建,就不会进行任何修改。
2.当服务器要创建一个新的 RDB 文件时,它先将文件的内容保存在一个临时文件里面,当临时文件写入完毕时,程序才使用临时文件替换原来的 RDB 文件。
3.这也就是说,无论何时, 复制 RDB 文件都是绝对安全的。
#以下是我们的建议:
1.创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个 RDB 文件备份到另一个文件夹。
2.确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照: 比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。
3.至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外。
4)RDB持久化高级配置
#编辑配置文件
[root@db01 redis]# vim /etc/redis/6379/redis.conf
#后台备份进程出错时,主进程停不停止写入? 主进程不停止容易造成数据不一致
stop-writes-on-bgsave-error yes
#导出的rdb文件是否压缩 如果rdb的大小很大的话建议这么做
rdbcompression yes
#导入rbd恢复时数据时,要不要检验rdb的完整性 验证版本是不是一致
rdbchecksum yes
5)AOF持久化高级配置
#编辑配置文件
[root@db01 redis]# vim /etc/redis/6379/redis.conf
#正在导出rdb快照的过程中,要不要停止同步aof
no-appendfsync-on-rewrite yes
#aof文件大小比起上次重写时的大小,增长率100%时重写,缺点:业务开始的时候,会重复重写多次
auto-aof-rewrite-percentage 100
#aof文件,至少超过64M时,重写
auto-aof-rewrite-min-size 64mb
五、数据类型
1.Redis数据结构之字符串
Redis的String类型可以是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字(整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能超过512MB。
1) 命令行模式
进入命令行模式:
#a 输入密码
redis-cli -a password_value
#raw 避免中文显示乱码
redis-cli -a password_value --raw
2) 查看命令帮助
127.0.0.1:6379> help @string
APPEND key value
summary: Append a value to a key
since: 2.0.0
BITCOUNT key [start end]
summary: Count set bits in a string
since: 2.6.0
BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]
3) Exists
#查看key是否存在,返回true / false(0/1)
127.0.0.1:6379> EXISTS a
1
127.0.0.1:6379> EXISTS b
0
4)TTL
#查看数据过期时间
127.0.0.1:6379> ttl a
-1 # 永不过期
127.0.0.1:6379> ttl b
(integer) 2 # 过期时间还有2个单位
5)增加数据
增加数据的命令有以下几个:set,setex,psetex,setnx。
#ex为多少秒过期 px为多少毫秒过期,nx为若不存在才创建,xx为若存在才覆盖创建
set key value [ex seconds] [px milliseconds] [nx|xx]
1.使用set命令新增一个键值对及其EX,PX用法
# 设置
127.0.0.1:6379> set name 金辉
OK
127.0.0.1:6379> get name
金辉
# 设置过期时间为秒
127.0.0.1:6379> set name 金辉 ex 10
OK
127.0.0.1:6379> ttl name
6
127.0.0.1:6379> ttl name
-2
# set 和 ex合并成setex
127.0.0.1:6379> SETEX name 10 金辉
OK
127.0.0.1:6379> ttl name
5
127.0.0.1:6379> ttl name
-2
# 设置过期时间为毫秒
127.0.0.1:6379> set name 金辉 px 10
OK
127.0.0.1:6379> TTL name
-2
# set 和 px 合并使用
127.0.0.1:6379> PSETEX name 100 金辉
OK
127.0.0.1:6379> ttl name
-2
2.使用set命令新增一个键值对及其NX,XX用法
Nx:当key不存在时创建,已存在则忽略。
Xx:当key存在则更新,不存在则忽略。
# nx
127.0.0.1:6379> set name alvin nx
OK
127.0.0.1:6379> get name
alvin
127.0.0.1:6379> set name 金辉
OK
127.0.0.1:6379> get name
金辉
127.0.0.1:6379> set name alvin nx
127.0.0.1:6379> get name
金辉
# set 与 nx 合并使用
127.0.0.1:6379> setnx name alvin
(integer) 0
127.0.0.1:6379> get name
金辉
3.批量增加
同时定义多个键值对,mset也可以和nx一起用。
mset key1 value1 [key2 value2...] #批量创建kv,已存在的会被更新
msetnx key1 value1 [key2 value2...] #批量创建kv,所有key不存在才会创建
127.0.0.1:6379> mset k1 a k2 b k3 c
OK
127.0.0.1:6379> mget k1 k2 k3
1) "a"
2) "b"
3) "c"
6) 删除数据
DDL #删除数据
使用del命令删除数据,可批量可单个删除。
#格式
del key1 [key2 key3...]
#案例
127.0.0.1:6379> del k1 k2 k3
(integer) 3
127.0.0.1:6379> del name_xx
(integer) 1
127.0.0.1:6379> mget k1 k2 k3 name_xx name_nx
1) (nil)
2) (nil)
3) (nil)
4) (nil)
5) "wyk"
7)更改数据
#1.使用set命令修改数据
127.0.0.1:6379> set name alvin
OK
127.0.0.1:6379> get name
"alvin"
127.0.0.1:6379> set name alvin
OK
127.0.0.1:6379> get name
"alvin"
#2.使用getset命令修改数据
等同于get+set,执行此命令返回get的结果,然后将该key更新为新的value,下次再get的时候查到的就是新的value。
127.0.0.1:6379> GETSET name alvin
金辉
127.0.0.1:6379>
#3.使用setrange按下标更新数据
对指定下标的字符串进行更新,下标从0开始算起。
127.0.0.1:6379> SETRANGE name 5 alvin
10
127.0.0.1:6379> get name
alvinalvin
8)查找数据
#1.查看所有的key
查看所有的Key,在数据量大的Redis中慎用,容易卡死。
127.0.0.1:6379> KEYS *
1) "name"
2) "a"
#2.根据key获取数据
使用get获得指定key的value。
127.0.0.1:6379> get key
#3.批量获得指定keys的values
mget key1 [key2 key3...]
127.0.0.1:6379> MGET a name
b
alvinalvin
127.0.0.1:6379>
#4.从字符串的指定开始结束下标截取字符串
getrange key start end
127.0.0.1:6379> GETRANGE name 1 4
lvin
127.0.0.1:6379>
9)计数
#1.指定key递增
对指定的key的value加1,递增步长默认1,如果key不存在,其初始值为0,在incr之后其值为1,如果value的值不能转为整型,如hello,该操作将执行失败并返回相应的错误信息。
127.0.0.1:6379> INCR num
1
127.0.0.1:6379> INCR num
2
#2.指定key递减
对指定的key的value减1,递减步长默认1,如果key不存在,其初始值为0,在decr之后其值为-1,如果value的值不能转为整型,如hello,该操作将执行失败并返回相应的错误信息。
127.0.0.1:6379> DECR num
1
127.0.0.1:6379> DECR num
0
#3.递增指定长度
对指定的key的value加指定的步长,递增步长可指定,如果key不存在,其初始值为0,在incrby之后其值为步长,如果value的值不能转为整型,如hello,该操作将执行失败并返回相应的错误信息。
$步长increment为整数,当为负数时效果等于递减
incrby key increment
#4.递减指定长度
对指定的key的value减指定的步长,递减步长可指定,如果key不存在,其初始值为0,在decrby之后其值为步长的负数,如果value的值不能转为整型,如hello,该操作将执行失败并返回相应的错误信息。
$步长increment为整数,当为负数时效果等于递増
decrby key increment
redis> SET count 100
OK
redis> DECRBY count 20
(integer) 80
10) 追加
#在字符串最后面追加子串
append key value
# 对不存在的 key 执行 APPEND
## 确保 myphone 不存在
redis> EXISTS myphone
(integer) 0
# 对不存在的 key 进行 APPEND ,等同于 SET myphone "nokia"
## 字符长度
redis> APPEND myphone "nokia"
(integer) 5
# 对已存在的字符串进行 APPEND
## 长度从 5 个字符增加到 12 个字符
redis> APPEND myphone " - 1110"
(integer) 12
redis> GET myphone
"nokia - 1110"
11) 长度
#返回字符的长度
strlen key
2.Redis数据结构之哈希
哈希类型是指键值对里的value本身存储的也是一个个的KV键值对,类似于python中的dict和java中的map集合。
1)查看命令帮助
not connected> help @hash
HDEL key field [field ...]
summary: Delete one or more hash fields
since: 2.0.0
HEXISTS key field
summary: Determine if a hash field exists
since: 2.0.0
2) 查看hash类型的key中指定的field是否存在
hexists key field
127.0.0.1:6379> HEXISTS csdn name
1
127.0.0.1:6379> HEXISTS csdn company
1
3) 设置hash类型的单个field或一次性设置多个field
HSET key field value [field value ...]
hset csdn id 1 name Alvin company 上海
4) 只有value中不存在的field才会被创建
HSETNX key field value
5) 删除数据
#使用hdel命令删除hash类型的value中的fields,可批量可单个删除
HDEL key field1 [field2 ...]
127.0.0.1:6379> HDEL csdn name
1
127.0.0.1:6379> HEXISTS csdn name
0
6)更改数据
#对hash类型中相同的field进行set操作会更新该field的值
HSET key field value [field value ...]
7) 查找数据
#1.使用hget获取指定hash类型的field对应的值
HGET key field
127.0.0.1:6379> HGET csdn company
上海
#2.使用hmget获取指定hash类型的多个field对应的值
HMGET key field [field ...]
127.0.0.1:6379> HMGET csdn company id
上海
1
#3.使用hgetall获得指定hash类型对象的全部field和对应的value值
HGETALL key
127.0.0.1:6379> HGETALL csdn
id
1
company
上海
#4.使用hkeys获得指定hash类型对象的全部field
HKEYS key
127.0.0.1:6379> HKEYS csdn
id
company
#5.使用hvals获得指定hash类型对象的全部field的values值
HVALS key
127.0.0.1:6379> HVALS csdn
1
上海
8) 计数
#1.hincrby可以对hash对象的指定的field的value做递增操作
与string类型中的incrby类似,hincrby可以对hash对象的指定的field的value做递增操作,increment必须是整数(hash类型中没有hdecrby方法,当increment为负数时为递减操作),value必须是integer类型,否则会报对应的错误。
HINCRBY key field increment
ps:filed对应的value必须是integer类型,increment必须是整数,可以为负
127.0.0.1:6379> HINCRBY csdn id 10
11
#2.hincrbyfloat可以对hash对象的指定的field的value做递增操作
与string类型中的incrbyfloat类似,hincrbyfloat可以对hash对象的指定的field的value做递增操作,increment可以是整数或浮点数(hash类型中没有hdecrbyfloat方法,当increment为负数时为递减操作),value必须是数字类型,否则会报对应的错误。
HINCRBYFLOAT key field increment
ps:filed对应的value必须是数字类型,increment可以是整数或浮点,可以为负
127.0.0.1:6379> HINCRBYFLOAT csdn id 10.9
21.9
9) 长度
#1.hlen返回hash类型中field的数量
HLEN key
127.0.0.1:6379> HLEN csdn
2
#2.hstrlen返回hash类型中指定filed对应的value的字符长度
HSTRLEN key field
127.0.0.1:6379> HSTRLEN csdn id
4
127.0.0.1:6379> HSTRLEN csdn company
15
10) 过期
#我们可以看到hash类型没有hsetex hpsetex一类的方法,想对hash对象做过期策略可以使用全局函数expire。
expire key seconds
127.0.0.1:6379> EXPIRE csdn 1000
1
127.0.0.1:6379> ttl csdn
987
3.Redis数据结构之列表
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)一个列表最多可以包含 2^32 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。
1)查看命令帮助
help @list
BLPOP key [key ...] timeout
summary: Remove and get the first element in a list, or block until one is available
since: 2.0.0
BRPOP key [key ...] timeout
summary: Remove and get the last element in a list, or block until one is available
since: 2.0.0
2)从左边插入元素
从左边插入元素,从左边依次追加进栈,先进后出,后进先出
LPUSH key element [element ...]
127.0.0.1:6379> LPUSH mylist alvin 18
3
127.0.0.1:6379> LPUSH mylist 上海
4
127.0.0.1:6379> LRANGE mylist 0 -1
上海
18
alvin
127.0.0.1:6379>
3)从左边插入元素
从右边插入元素,从右边依次追加进队列,先进先出,后进后出。
RPUSH key element [element ...]
127.0.0.1:6379> RPUSH mylist linux
5
127.0.0.1:6379> RPUSH mylist python
6
127.0.0.1:6379> LRANGE mylist 0 -1
上海
18
alvin
上海市
linux
python
4) list存在时才会从左边依次追加元素
#与sting类型中的nx类似,只有当list存在时才会从左边依次追加元素。
LPUSHX key element [element ...]
127.0.0.1:6379> LPUSHX mylist Shanghai
7
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
18
alvin
上海市
linux
python
127.0.0.1:6379> LPUSHX testlist Shanghai
0
127.0.0.1:6379> LRANGE testlist 0 -1
127.0.0.1:6379>
5)当list存在时才会从右边依次追加元素
#与lpushx类似,只有当list存在时才会从右边依次追加元素。
RPUSHX key element [element ...]
127.0.0.1:6379> RPUSHX mylist QingPu
8
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
18
alvin
上海市
linux
python
QingPu
127.0.0.1:6379> RPUSHX testlist QingPu
0
127.0.0.1:6379> LRANGE testlist 0 -1
127.0.0.1:6379>
6) 从list中指定的元素的前/后 插入一个新元素
LINSERT key BEFORE|AFTER pivot element
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
18
alvin
上海市
linux
python
QingPu
# 在某个KEY之前插入某个值
127.0.0.1:6379> LINSERT mylist before 18 17
9
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
17
18
alvin
上海市
linux
python
QingPu
# 在某个值后面添加一个值
127.0.0.1:6379> LINSERT mylist after 18 16
10
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
17
18
16
alvin
上海市
linux
python
QingPu
127.0.0.1:6379>
7) 删除数据
#1.从列表左侧开始移除
LREM key count element
127.0.0.1:6379> LINSERT mylist after 18 16
14
127.0.0.1:6379> LINSERT mylist after 18 16
15
127.0.0.1:6379> LINSERT mylist after 18 16
16
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
17
17
17
17
18
16
16
16
16
alvin
上海市
linux
python
QingPu
127.0.0.1:6379> LREM mylist 2 16
2
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
17
17
17
17
18
16
16
alvin
上海市
linux
python
QingPu
127.0.0.1:6379>
8) 修改数据
#1.修改元素内容
LSET key index element
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
17
17
17
17
18
16
16
alvin
上海市
linux
python
QingPu
127.0.0.1:6379> LSET mylist 2 19
OK
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
19
17
17
17
18
16
16
alvin
上海市
linux
python
QingPu
127.0.0.1:6379>
#2.截取为从下标start到下标stop闭区间的列表
将原列表截取为从下标start到下标stop闭区间的列表,即原列表变为一个第start+1个到第stop+1个元素的列表。
LTRIM key start stop
127.0.0.1:6379> LTRIM mylist 2 8
OK
127.0.0.1:6379> LRANGE mylist 0 -1
19
17
17
17
18
16
16
127.0.0.1:6379>
9) 查询数据
#1.查看列表中元素的个数
LLEN key
127.0.0.1:6379> LLEN mylist
7
127.0.0.1:6379>
#2.根据起止下标查询列表元素
LRANGE key start stop
lrange key 0 -1 #表示查看全部元素
lrange key -1 -1 #表示查看最右边的元素
#3.根据指定的index下标查看列表中的元素
LINDEX key index
127.0.0.1:6379> LINDEX mylist 3
17
127.0.0.1:6379>
#4.从左边消费列表中的元素
从左边消费列表中的元素,消费完之后从列表中删除。
LPOP key
127.0.0.1:6379> LRANGE mylist 0 -1
17
17
17
18
16
16
127.0.0.1:6379> LPOP mylist
17
127.0.0.1:6379> LRANGE mylist 0 -1
17
17
18
16
16
127.0.0.1:6379>
#5.从右边消费列表中的元素
从右边消费列表中的元素,消费完之后从列表中删除。
RPOP key
127.0.0.1:6379> LRANGE mylist 0 -1
17
17
18
16
16
127.0.0.1:6379> RPOP mylist
16
127.0.0.1:6379> LRANGE mylist 0 -1
17
17
18
16
127.0.0.1:6379>
#6.消费列表最右边的元素并返回
消费列表A的最右边的元素返回,然后追加到列表B的最左边。
RPOPLPUSH source destination
RPOPLPUSH List_A List_B
127.0.0.1:6379> LRANGE mylist 0 -1
17
17
18
16
127.0.0.1:6379> RPOPLPUSH mylist mylist
16
127.0.0.1:6379> LRANGE mylist 0 -1
16
17
17
18
127.0.0.1:6379>
#7.从列表中左侧查询元素
从列表中左侧查询元素,返回列表的key和左侧第一个元素,若所有查询的列表中都没有元素,则会阻塞等待至设置的timeout秒之后返回空,若在这期间,这些列表新增了元素,则会立刻消费并返回该元素。
BLPOP key [key ...] timeout
127.0.0.1:6379> BLPOP mylist 10
mylist
16
127.0.0.1:6379> BLPOP mylist 10
mylist
17
127.0.0.1:6379> BLPOP mylist 10
mylist
17
127.0.0.1:6379> BLPOP mylist 10
mylist
18
127.0.0.1:6379> BLPOP mylist 10
# 从列表右侧开始消费
4.Redis数据结构之无序集合
Redis 的 Set 是 string 类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)。
1) 查看帮助命令
#使用Redis命令手册查看
127.0.0.1:6379> help @set
2) 增加数据
7.2.1、 给集合内新增成员
给集合内新增成员,若集合不存在则创建集合并新增成员。
SADD key member [member ...]
127.0.0.1:6379> sadd myset 1
1
127.0.0.1:6379> sadd myset 2
1
127.0.0.1:6379> sadd myset 3
1
127.0.0.1:6379> sadd myset 4
1
127.0.0.1:6379> sadd myset 5
1
127.0.0.1:6379> SMEMBERS myset
1
2
3
4
5
127.0.0.1:6379>
3) 删除数据
#1.从集合中删除指定的成员
从集合中删除指定的成员,返回删除的个数。
SREM key member [member ...]
127.0.0.1:6379> SREM myset 3 4
2
127.0.0.1:6379> SMEMBERS myset
1
2
5
127.0.0.1:6379>
4) 修改数据
#1.移动数据
127.0.0.1:6379> SADD myset1 1 2 3 4 5
5
127.0.0.1:6379> sadd myset2 one two three
3
127.0.0.1:6379> SMOVE myset1 myset2 4
1
127.0.0.1:6379> SMEMBERS myset1
1
2
3
5
127.0.0.1:6379> SMEMBERS myset2
4
three
two
one
127.0.0.1:6379>
5) 查看数据
#1.查看集合中所有的成员
SMEMBERS key
127.0.0.1:6379> SMEMBERS myset2
4
three
two
one
#2.返回集合中成员的个数
SCARD key
127.0.0.1:6379> SMEMBERS myset2
4
three
two
one
127.0.0.1:6379> SCARD myset2
4
#3.从集合中随机返回指定个数的成员
SRANDMEMBER key [count]
127.0.0.1:6379> SRANDMEMBER myset1 2
3
2
127.0.0.1:6379> SRANDMEMBER myset1 2
1
5
#4.判断对象是否是集合中的成员
SISMEMBER key member
127.0.0.1:6379> SISMEMBER myset1 6
0
127.0.0.1:6379> SISMEMBER myset1 3
1
#5.随机返回一个成员
从集合中随机弹出一个成员,返回该成员并从集合中删除该成员。
SPOP key
127.0.0.1:6379> SPOP myset1
2
127.0.0.1:6379> SPOP myset2
4
127.0.0.1:6379> SPOP myset2
one
127.0.0.1:6379> SPOP myset2
two
127.0.0.1:6379> SPOP myset2 2
three
6) 交集
#1.取多个集合的交集
取多个集合的交集,返回这些集合中共同拥有的成员。
SINTER key [key ...]
127.0.0.1:6379> sadd myseta 1 2 3 4 5
5
127.0.0.1:6379> sadd mysetb 4 5 6 7 8
5
127.0.0.1:6379> sadd mysetc 5 6 7 8 9
5
127.0.0.1:6379> SINTER myseta mysetb mysetc
5
#2.将多个集合的交集的结果保存为一个新的集合
将多个集合的交集的结果保存为一个新的集合destination ,返回新集合的成员个数。
SINTERSTORE destination key [key ...]
127.0.0.1:6379> SINTERSTORE mysetc mysetb myseta
4
127.0.0.1:6379> SMEMBERS mysetc
5
6
7
8
127.0.0.1:6379> SMEMBERS mysetb
4
5
6
7
8
127.0.0.1:6379> SMEMBERS myseta
5
6
7
8
127.0.0.1:6379>
7) 并集
#1.取多个集合的并集
取多个集合的并集,相同的成员会被去重。
SUNION key [key ...]
127.0.0.1:6379> SADD myset_a 1 2 3 4 5
5
127.0.0.1:6379> sadd myset_b 3 4 5 6 7
5
127.0.0.1:6379> SUNION myset_a myset_b
1
2
3
4
5
6
7
127.0.0.1:6379>
#2.将多个集合的并集的结果保存为一个新的集合
SUNIONSTORE destination key [key ...]
127.0.0.1:6379> SUNIONSTORE new_myset myset_a myset_b
7
127.0.0.1:6379> SMEMBERS new_myset
1
2
3
4
5
6
7
127.0.0.1:6379>
8) 差集
#1.取多个集合的差集
取多个集合的差集,以最左边的为主集合,返回左集合中有而其他集合没有的成员。
127.0.0.1:6379> SDIFF myset_a myset_b
1
2
127.0.0.1:6379> SMEMBERS myset_a
1
2
3
4
5
127.0.0.1:6379> SMEMBERS myset_b
3
4
5
6
7
9) 将多个集合的差集的结果保存为一个新的集合
#将多个集合的差集的结果保存为一个新的集合 ,返回新集合的成员个数 。
SDIFFSTORE destination key [key ...]
127.0.0.1:6379> SDIFFSTORE myset_sdiff myset_a myset_b
2
127.0.0.1:6379> SMEMBERS myset_sdiff
1
2
127.0.0.1:6379>
5.Redis数据结构之有序集合
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)。
1) 查看命令帮助
127.0.0.1:6379> help @sorted_set
2) 增加数据
往有序集合中新增成员,需要指定该成员的分数,分数可以是整形或浮点型,当分数相同时候,索引下标按照字典排序。
127.0.0.1:6379> ZADD myzset 1 alvin
1
127.0.0.1:6379> ZADD myzset 2 shanghai 3 beijing
2
127.0.0.1:6379> ZRANGE myzset 0 -1
alvin
shanghai
beijing
3)查询数据
#1.获取有序集合的成员数
ZCARD key
127.0.0.1:6379> ZCARD myzset
3
127.0.0.1:6379>
#2.获取指定分数区间内的成员数
从有序集合内获取指定分数区间内的成员数。
ZCOUNT key min max
127.0.0.1:6379> ZRANGE myzset 0 -1
alvin
shanghai
beijing
127.0.0.1:6379> ZCOUNT myzset 1 2
2
127.0.0.1:6379>
#3.字典排序
根据字典排序返回min ,max之间的数据量.
ZLEXCOUNT key min max
127.0.0.1:6379> ZRANGE myzset 0 -1
alvin
shanghai
beijing
127.0.0.1:6379> ZLEXCOUNT myzset [al [zzz
3
127.0.0.1:6379>
#4.获取成员的分数值
返回有序集中,成员的分数值,不存在的成员返回空。
ZSCORE key member
127.0.0.1:6379> ZRANGE myzset 0 -1
alvin
shanghai
beijing
127.0.0.1:6379> ZSCORE myzset shanghai
2
#5. 127.0.0.1:6379> ZSCAN myzset 0 match "sh*"
0
shanghai
2
127.0.0.1:6379> ZSCAN myzset 0 match "al*"
0
alvin
1
5)删除数据
#1.移除指定的成员
ZREM key member [member ...]
127.0.0.1:6379> ZRANGE myzset 0 -1
alvin
shanghai
beijing
127.0.0.1:6379> ZREM myzset shanghai
1
127.0.0.1:6379> ZRANGE myzset 0 -1
alvin
beijing
127.0.0.1:6379>
6.Redis基础命令之常用命令
1) 查看所有key
127.0.0.1:6379> KEYS *
2) 查看key的类型
127.0.0.1:6379> TYPE myset1
set
127.0.0.1:6379> TYPE a
string
3) 随机返回一个key
127.0.0.1:6379> RANDOMKEY
myset_sdiff
127.0.0.1:6379> RANDOMKEY
new_myset
127.0.0.1:6379> RANDOMKEY
myset
4) 删除key
返回删除状态1/0,True/False。
del key [key2 key3 key4...]
5) 判断一个key是否存在
返回状态1/0,True/False,当传入多个key时返回or的结果,即只要有一个存在就返回True。
exists key [key ...]
6) 重命名一个key
127.0.0.1:6379> RENAME myset mysets
OK
127.0.0.1:6379>
7) 查看key的剩余生存时间
#1.以秒为单位
ttl key
127.0.0.1:6379> ttl mysets
-1 # -1代表永不过期
#2.以毫秒为单位
Pttl key
127.0.0.1:6379> PTTL a
-1 # -1代表永不过期