Redis
简介:
redis是用c语言开发的一个开源的高性能键值对数据库;
特征:
- 数据之间没有必然的关联关系
- 内部采用单线程进行工作
- 高性能
- 多数据类型支持
- 字符串类型: string
- 列表类型: list
- 散列类型: hash
- 集合类型:set
- 有序集合类型:zset/sorted_set
- 支持持久化,进行数据灾难恢复
应用场景:
- 为热点数据加速查询:如热点商品
- 即时信息查询:排行榜,站点访问统计
- 时效性信息控制:验证码
- 分布式数据共享:如分布式集群架构中的session分离
- 消息队列
Redis启动
启动服务器
#配置文件启动
redis-server config_file_name
#指定端口启动
redis-server --port 6379
使用命令进入容器:
#进入Redis容器
redis-cli
#退出容器 使用ctrl+c
exit
#清空屏幕
clear
在Docker 中使用命令进入容器
#第一步
docker exec -it redis-test /bin/bash
#第二步输入
redis-cli
Redis数据类型
String类型
- 基本操作
#添加数据 set key value
set name lzy
# 获取数据 get key
get name
#删除数据
del key
#判定性添加数据,如果key存在就不会添加
setnx key value
#添加/修改多个数据
mset key1 value1 key2 value2 …
#获取多个数据
mget key1 key2 …
#获取数据字符个数(字符串长度)
strlen key
#追加信息到原始信息后部(如果原始信息存在就追加,否则新建)
append key value
- 拓展操作
#设置数值数据增加指定范围的值,必须是int,如果不存在就会 0 开始
incr key
incrby key increment
incrbyfloat key increment
#设置数值数据减少指定范围的值
decr key
decrby key increment
#设置数据具有指定的生命周期 秒 , 毫秒
setex key seconds value
psetex key milliseconds value
-
注意事项:
- 数据没获取到就是:nil,等同于null
- 数据最大存储量:512MB
- string在redis内部存储的默认就是一个字符串,当遇到incr,decr操作的时候会转成数值类型计算
- 按数值进行操作数据,如果原始的数据不能转成数值,或超越了redis数值上限范围,就会报错
- redis所有的操作都是院子的,采用单线程处理所有的业务,命令也是一个一个执行的,因此无需考虑并发带来的数据影响
-
使用事例:
hash类型,内部有存储顺序按照字母排序
-
-
基本使用
-
#添加/修改数据 hset key field value #获取数据 hget key field hgetall key #删除数据 hdel key field1 [field2] #设置field的值,如果该field存在则不做任何操作 hsetnx key field value #添加/修改多个数据 hmset key field1 value1 field2 value2 … #获取多个数据 hmget key field1 field2 … #获取哈希表中是否存在指定的字段 hexists key field
-
hash的拓展操作
-
#获取哈希表中所有的字段名或字段值 hkeys key hvals key #设置指定字段的数值数据增加指定范围的值 hincrby key field increment hincrbyfloat key field increment
-
注意事项:
- hash只能存储字符串,不能存储其他数据类型,不存在嵌套
- 每个hash可以存储2^32-1个键值对
- hash十分贴近对象的存储形式,但是不能滥用
- hegtall可以获取到全部属性,如果field过多,便利数据效率会很低
List类型 双向链表
- 数据存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分
- 需要的存储结构:一个存储空间保存多个数据,且通过数据可以提现进入的顺序
- list类型:保存多个数据,底层使用双向链表存储结构实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cUZcs0qC-1626777049062)(D:/3.%E5%AD%A6%E4%B9%A0%E8%A7%86%E9%A2%91/javaWEB/day25-Redis/%E8%AE%B2%E4%B9%89/md%E6%96%87%E6%A1%A3/img/list1.png?lastModify=1626761647)]
- list 类型数据基本操作
#添加/修改数据 如果存在就会变成追加操作
lpush key value1 [value2] ……
rpush key value1 [value2] ……
#获取数据 0 -1 是获取全部
lrange key start stop
lindex key index
llen key
# 获取并移除数据
lpop key
rpop key
-
list扩展操作
#移除指定数据count删除的数量 lrem key count value #规定时间内获取并移除一个数据 blpop key1 [key2] timeout brpop key1 [key2] timeout brpoplpush source destination timeout
- 注意事项:
- list中保存的数据都是String类型的,数据总量是有限的
- list有索引的概念,但是基本上以队列方式出队入队
- 获取全部数据操作结束索引设置为-1
- list可以分页操作,通常第一页的数据来自于list
- 注意事项:
Set类型 仅存储键,不存储值(nil)
与hash存储结构完全相同,仅存储键,不存储值(nil),并且值是不允许重复的,查询效率非常高
- set 基本使用
#添加数据
sadd key member1 [member2]
#获取全部数据
smembers key
#删除数据
srem key member1 [member2]
#获取集合数据总量
scard key
#判断集合中是否包含指定数据
sismember key member
#随机获取集合中指定数量的数据,不会删除
srandmember key [count]
#随机获取集中的某个数据并将该数据移除集合
spop key [count]
- set 类型数据的扩展操作
#求两个集合的交、并、差集
sinter key1 [key2 …]
sunion key1 [key2 …]
sdiff key1 [key2 …]
#求两个集合的交、并、差集并存储到指定集合中
sinterstore destination key1 [key2 …]
sunionstore destination key1 [key2 …]
sdiffstore destination key1 [key2 …]
#将指定数据从原始集合中移动到目标集合中
smove source destination member
- 注意事项:
- set 类型不允许数据重复,如果添加的数据在 set 中已经存在,将只保留一份。
- set 虽然与hash的存储结构相同,但是无法启用hash中存储值的空间。
-
set应用场景
- 黑名单
- 白名单
key的操作
- 基本操作
#删除指定key del key #获取key是否存在 exists key #获取key的类型 type key #排序 sort #改名 rename key newkey renamenx key newkey
- 拓展操作
# 为指定key设置有效期 expire key seconds pexpire key milliseconds expireat key timestamp pexpireat key milliseconds-timestamp # 获取key的有效时间 负数就是失效了 ttl key pttl key #切换key从时效性转换为永久性 persist key
Redis数据库
里面有16个数据库,共用Redis内存大小,没有谁大谁小,数字只代表区域
#切换数据库 select index #其他操作 ping #数据移动 move key db #数据总量 dbsize #数据清除 flushdb flushall
Jedis
java连接redis工具类HelloWorld(Jedis版)
Jedis简易工具类开发
可视化客户端
public class JedisTest { public static void main(String[] args) { //1.获取连接对象 Jedis jedis = new Jedis("192.168.40.130",6379); //2.执行操作 jedis.set("age","39"); String hello = jedis.get("hello"); System.out.println(hello); jedis.lpush("list1","a","b","c","d"); List<String> list1 = jedis.lrange("list1", 0, -1); for (String s:list1 ) { System.out.println(s); } jedis.sadd("set1","abc","abc","def","poi","cba"); Long len = jedis.scard("set1"); System.out.println(len); //3.关闭连接 jedis.close(); } }
Redis持久化
将内存中的数据保存到硬盘里面(永久性存储介质,防止数据意外都是,确保数据安全)
持久化过程保存什么
RDB:数据快照
AOF:过程(日志)
RDB与AOF区别
RDB
三种方案:
- save 操作
save 手动执行一次保存操作
save指令相关配置
- 设置本地数据库文件名,默认值为 dump.rdb,通常设置为dump-端口号.rdb
dbfilename filename
- 设置存储.rdb文件的路径,通常设置成存储空间较大的目录中,目录名称data
dir path
- 设置存储至本地数据库时是否压缩数据,默认yes,设置为no,节省 CPU 运行时间,但存储文件变大
rdbchecksum yes|no
save指令工作原理
弊端:save指令的执行会阻塞当前Redis服务器,直到当前RDB过程完成为止,有可能造成长时间阻塞,线上环境不建议使用
原理:
- bgsave指令
后台保存模式,bgsave指令,bg其实是background的意思,后台执行的意思
手动启动后台保存操作,但不是立即执行
#手动启动后台保存操作,但不是立即执行
bgsave
#后台存储过程中如果出现错误现象,是否停止保存操作,默认yes
stop-writes-on-bgsave-error yes|no
工作原理:bgsave命令会调用一个fork函数生成子线程,然后去执行save操作
-
自动save
-
save second changes
参数
second:监控时间范围(s)
changes:监控key的变化量(多少个发生了变化)
-
解释:就是在时间内这么多key发生变化了就存
-
只要操作成功了,就会计数
RDB优点:
- RDB是一个紧凑压缩的二进制文件,存储效率较高
- RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景
- RDB恢复数据的速度要比AOF快很多
- 应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程机器中,用于灾难恢复。
RDB缺点
- RDB方式无论是执行指令还是利用配置,无法做到实时持久化,具有较大的可能性丢失数据
- bgsave指令每次运行要执行fork操作创建子进程,要牺牲掉一些性能
- Redis的众多版本中未进行RDB文件格式的版本统一,有可能出现各版本服务之间数据格式无法兼容现象
AOF 持久化
为什么要有AOF,这得从RDB的存储的弊端说起:
- 存储数据量较大,效率较低,基于快照思想,每次读写都是全部数据,当数据量巨大时,效率非常低
- 大数据量下的IO性能较低
- 基于fork创建子进程,内存产生额外消耗
- 宕机带来的数据丢失风险
那解决的思路是什么呢?
- 不写全数据,仅记录部分数据
- 降低区分数据是否改变的难度,改记录数据为记录操作过程
- 对所有操作均进行记录,排除丢失数据的风险
**概念:**AOF持久化,一个独立的日志方式记录每次的写命令,重启时再执行AOF文件里面的命令,达到恢复的目的;
备份的过程:修改命令来了就保存到缓存,达到了一定数量然后就全部存到硬盘里面
启动AOF相关配置
开启AOF持久化功能,默认no,即不开启状态
appendonly yes|no
AOF持久化文件名,默认文件名为appendonly.aof,建议配置为appendonly-端口号.aof
appendfilename filename
AOF持久化文件保存路径,与RDB持久化文件保持一致即可
dir
AOF写数据策略,默认为everysec
appendfsync always|everysec|no
5.3.2 AOF执行策略
AOF写数据三种策略(appendfsync)
-
always(每次):每次写入操作均同步到AOF文件中数据零误差,性能较低,不建议使用。
-
everysec(每秒):每秒将缓冲区中的指令同步到AOF文件中,在系统突然宕机的情况下丢失1秒内的数据 数据准确性较高,性能较高,建议使用,也是默认配置
-
no(系统控制):由操作系统控制每次同步到AOF文件的周期,整体过程不可控
-
每次指令存储和每秒存储,有区别,每秒保存会多一个缓冲区.
AOF文件重 写是将Redis进程内的数据转化为写命令同步到新AOF文件的过程。简单说就是将对同一个数据的若干个条命令执行结 果转化成最终结果数据对应的指令进行记录
-
降低磁盘占用量,提高磁盘利用率
-
提高持久化效率,降低持久化写时间,提高IO性能
-
降低数据恢复用时,提高数据恢复效率
-
自动重写
auto-aof-rewrite-min-size size
auto-aof-rewrite-percentage percentage
自动重写触发条件设置
auto-aof-rewrite-min-size size
auto-aof-rewrite-percentage percent
自动重写触发比对参数( 运行指令info Persistence获取具体信息 )
aof_current_size
aof_base_size