Redis的下载与安装(Windows)
下载地址:https://github.com/MSOpenTech/redis/tags
解压缩即可使用!
Redis基本操作
#设置 key,value 数据
set key value
#根据 key 查询对应的 value,如果不存在,返回空(nil)
get key
#清除屏幕中的信息
clear
#退出客户端
quit
exit
<ESC>
#获取命令帮助文档,获取组中所有命令信息名称
help 命令名称
help @组名
Redis数据类型
Redis共有5种数据类型
- string
- hash
- list
- set
- sorted_set
redis 自身是一个 Map,其中所有的数据都是采用 key : value 的形式存储!
数据类型指的是存储的数据的类型,也就是 value 部分的类型,key 部分永远都是字符串!
1、String
string类型是最简单的数据存储类型,也是最常用的数据存储类型。
通常使用字符串,如果字符串以整数的形式展示,可以作为数字操作使用。
需要注意的点:
- string在redis内部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算。对于按数值进行操作的数据,如果原始数据不能转成数值,或超越了redis数值上限范围,将报错;
- 9223372036854775807(java中long型数据最大值,Long.MAX_VALUE);
- 数据最大存储量512MB;
2、Hash
一个存储空间保存多个键值对数据,底层使用哈希表结构实现数据存储!
需要注意的点:
- hash类型下的value只能存储字符串,不允许存储其他数据类型,不存在嵌套现象。如果数据未获取到,对应的值为(nil);
- 每个 hash 可以存储 2^32 - 1 个键值对;
3、List
保存多个数据,底层使用双向链表存储结构实现!
需要注意的点:
- list中保存的数据都是string类型的,数据总容量是有限的,最多2^32-1 个元素 (4294967295);
- list具有索引的概念,但是操作数据时通常以队列的形式进行入队出队操作,或以栈的形式进行入栈出栈操作;
- 获取全部数据操作结束索引设置为-1;
4、Set
与hash存储结构完全相同,仅存储键,不存储值(nil),并且值是不允许重复的。
在查询方面提供更高的效率
需要注意的点
- set 类型不允许数据重复,如果添加的数据在 set 中已经存在,将只保留一份;
- set 虽然与hash的存储结构相同,但是无法启用hash中存储值的空间;
5、Sorted_set
在set的存储结构基础上添加可排序字段!
需要注意的点
- score保存的数据存储空间是64位,如果是整数范围是-9007199254740992~9007199254740992;
- sorted_set 底层存储还是基于set结构的,因此数据不能重复,如果重复添加相同的数据,score值将被反复覆盖,保留最后一次修改的结果;
Redis通用指令
1、key通用指令
#删除指定key
del key
#获取key是否存在
exists key
#获取key的类型
type key
#为指定key设置有效期
expire key seconds 以秒计
pexpire key milliseconds 以毫秒计
expireat key timestamp 时间戳
pexpireat key milliseconds-timestamp 时间戳以毫秒计
#获取key的有效时间(TTL是time to live的缩小)
ttl key 以秒为单位,返回给定 key 的剩余生存时间
pttl key 以毫秒为单位返回 key 的剩余的过期时间
#切换key从时效性转换为永久性
persist key
#为key改名
rename key newkey
renamenx key newkey 仅当 newkey 不存在时,将 key 改名为 newkey。否则会出现把存在的key值覆盖的情况
#对所有key排序
sort
#其他key通用操作
help @generic
#查询key(查询规则如下图)
keys pattern
2、数据库通用指令
redis在使用过程中,伴随着操作数据量的增加,会出现大量的数据以及对应的key,如果数据不区分种类、类别混杂在一起,极易出现重复或冲突;
因此redis为每个服务提供有16个数据库,编号从0到15。并且每个数据库之间的数据相互独立
#切换数据库
select index
#退出
quit
#主要用来测试服务器连接是否正常
ping
#输出信息
echo message
#数据移动
move key db
#统计当前库的大小
dbsize
#仅清除当前库的数据
flushdb
#清除所有库的数据(包括0-15)
flushall
Jedis
Jedis是Java语言连接redis服务主要使用的!
- jar包导入,下载地址:https://mvnrepository.com/artifact/redis.clients/jedis
- 基于maven:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
示例:
import redis.clients.jedis.Jedis;
public class RedisJava {
public static void main(String[] args) {
//连接本地的 Redis 服务
Jedis jedis = new Jedis("localhost");
// 如果 Redis 服务设置来密码,需要下面这行,没有就不需要
// jedis.auth("123456");
System.out.println("连接成功");
//查看服务是否运行
System.out.println("服务正在运行: "+jedis.ping());
}
}
只要获取到Jedis 对象,那么Redis所有的命令操作都能在Jedis对象里一一找到,使用非常方便!
持久化
持久化(Persistence)就是把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘);
问:为什么要持久化?
答:防止数据的意外丢失,确保数据安全性
Redis持久化过程共分为两种:
- 将当前数据状态进行保存,快照形式,存储数据结果,存储格式简单,关注点在数据
- 将数据的操作过程进行保存,日志形式,存储操作过程(执行命令),存储格式复杂,关注点在数据的操作过程
RDB
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。
既然RDB机制是通过把某个时刻的所有数据生成一个快照来保存,那么就应该有一种触发机制,对于RDB来说,提供了三种机制:save、bgsave、自动化;
1、save指令
命令:
save 手动执行一次保存操作
save指令的执行会阻塞当前Redis服务器,直到当前RDB过程完成为止,有可能会造成长时间阻塞,线上环境不建议使用;
2、 bgsave指令
命令:
bgsave 手动启动后台保存操作,但不是立即执行
bgsave命令是针对save阻塞问题做的优化。执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。Redis内部所有涉及到RDB操作都采用bgsave的方式,save命令可以放弃使用!
3、配置自动触发
在conf文件中进行配置:
save second changes 满足限定时间范围内key的变化数量达到指定数量即进行持久化
参数:
second:监控时间范围
changes:监控key的变化量
范例:
save 900 1
save 300 10
save 60 10000
save配置启动后执行的是bgsave操作;
注意:save配置要根据实际业务情况进行设置,频度过高或过低都会出现性能问题
相关配置
#设置本地数据库文件名,默认值为 dump.rdb
dbfilename dump.rdb
#设置存储.rdb文件的路径
dir
#设置存储至本地数据库时是否压缩数据,默认为 yes,采用 LZF 压缩;(如果设置为no,可以节省 CPU 运行时间,但会使存储的文件变得特别大)
rdbcompression
#设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均进行(如果设置为no,可以节约读写性过程约10%时间消耗,但是存储一定的数据损坏风险)
rdbchecksum
#后台存储过程中如果出现错误现象,是否停止保存操作,默认为开启状态
stop-writes-on-bgsave-error
save与bgsave对比
方式 | save指令 | bgsave指令 |
读写 | 同步 | 异步 |
阻塞客户端指令 | 是 | 否 |
额外内存消耗 | 否 | 是 |
启动新进程 | 否 | 是 |
RDB的优点
- RDB是一个紧凑压缩的二进制文件,存储效率较高
- RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景
- RDB恢复数据的速度要比AOF快很多
RDB的缺点
- RDB方式无论是执行指令还是利用配置,无法做到实时持久化,具有较大的可能性丢失数据
- bgsave指令每次运行要执行fork操作创建子进程,要牺牲掉一些性能
- Redis的众多版本中未进行RDB文件格式的版本统一,有可能出现各版本服务之间数据格式无法兼容现象
AOF(append only file)
以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令达到恢复数据的目的。与RDB相比可以简单描述为改记录数据为记录数据产生的过程;
AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式
AOF写数据三种策略(appendfsync)
- always(每次):每次写入操作均同步到AOF文件中,数据零误差,性能较低,不建议使用
- everysec(每秒):每秒将缓冲区中的指令同步到AOF文件中,数据准确性较高,性能较高,建议使用,也是默认配置
- no(系统控制):由操作系统控制每次同步到AOF文件的周期,整体过程不可控
相关配置
#是否开启AOF持久化功能,默认为不开启状态
appendonly yes|no
#AOF写数据策略
appendfsync always|everysec|no
#AOF持久化文件名,默认文件名未appendonly.aof,建议配置为appendonly-端口号.aof
appendfilename filename
#AOF持久化文件保存路径,与RDB持久化文件保持一致即可
dir
AOF重写
随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入了AOF重写机制压缩文件体积。
AOF文件重写是将Redis进程内的数据转化为写命令同步到新AOF文件的过程。简单说就是将对同一个数据的若干个条命令执行结果转化成最终结果数据对应的指令进行记录。
举例:
set name a
set name b
set name c
最终重写完就只有一条命令set name c,这样就大大的降低了AOF文件记录的体积;
AOF重写规则
- 忽略无效指令,重写时使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令(即上面举的例子)
- 对同一数据的多条写命令合并为一条命令,例如:
lpush list1 a
lpush list1 b
lpush list1 c
可以转化为:lpush list1 a b c
- 进程内已超时的数据不再写入文件
AOF重写方式
- 手动重写,命令:bgrewriteaof
- 自动重写,配置:
#AOF文件重写需要的尺寸
auto-aof-rewrite-min-size size
#AOF文件增长率
auto-aof-rewrite-percentage percentage
#当前AOF文件大小的变量(运行指令info Persistence获取具体信息)
aof_current_size
#AOF上次启动和重写的尺寸
aof_base_size
自动重写触发条件:
RDB VS AOF
持久化方式 | RDB | AOF |
占用存储空间 | 小(数据级:压缩) | 大(指令集:重写) |
存储速度 | 慢 | 快 |
恢复速度 | 快 | 慢 |
数据安全性 | 会丢失数据 | 依据策略决定 |
资源消耗 | 高/重量级 | 低/轻量级 |
启动优先级 | 低 | 高 |
如果对数据非常敏感,建议使用默认的AOF持久化方案。
如果需要对数据呈现阶段有效性,建议使用RDB持久化方案。
总结
本文参考资料: