redis介绍
一、redis的特性
redis的特性
丰富的数据类型,包含五种(set、zset、hash、string、list)
可用于缓存消息,设置过期时间自动删除
支持持久化方式rdf和aof
rdf:redis在进行数据持久化的过程中,会先将数据写入到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次持久化好的文件,如果大规模的数据恢复,使用rdf会高效。
缺点:因为是通过全量数据的同步,假设每过5分钟持久化一次,如果redis出现了故障,期间的数据就会丢失。需要重新刷数。
aof(Append Only File:即只允许追加不允许改写的文件):AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍。当有操作指令执行,先将指令写入到aof的文件当中,默认的情况下是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中)
缺点:AOF方式也同样存在缺陷,比如在同样数据规模的情况下,AOF文件要比RDB文件的体积大。而且,AOF方式的恢复速度也要慢于RDB方式
主从分布式,redis支持主从的读写分离
使用场景:
- 通过sorted set实现排行榜功能,比如商城积分的排行榜等等
- 用过期的key结合springboot cache实现缓存存储
- redis的分布式session共享
- 使用布隆过滤器解决缓存穿透
- 通过redis实现分布式锁
二、redis的数据结构
redis的数据结构包含以下五种:
- String
- list
- set
- sortset
- hash
2.1、String
String是最常用的一种数据类型,普通的key/value都可以归为此类
set/get
set:设置key对应的值为String类型的value
get:获取key对应的值
mget
批量获取多个key的值,如果不存在则返回nil
incr && incrby (i++)
incr对应的值进行进行加加操作,并返回新的值;incrby加上指定值
decr && decrby (i--)
decr对key对应的值进行减减操作,并返回新的值;decrby减去指定的值
setnx set if not exist
指定key对应的值为String类型的value,如果key已经存在则返回0
setex set expire 单位:秒
指定key对应的值为String类型的value,并且设置有效期
使用redis来当分布式锁,需要结合setnx和setex一起使用,因为setnx是没有有效时间的,为了让锁在有效时间内释放,需要配合setex使用。但是redis里单个命令是原子性操作,而两个命令之间是没有原子性操作的保障,所以需要通过lua脚本来保证分布式锁的原子性操作。
2.2、hash
类似hashmap,适用场景为存储一个对象信息,如商品信息、产品信息等等。
hash是一个string类型的field和value之间的映射
redis的hash数据类型的key(hash表名)对应value实际的内部存储结构为一个hashMap
hash特别适合存储对象
相对于把每一个对象的每个属性为String类型,将整个对象存储在hash类型中会占用更少内存
所存储的成员较少时数据存储为zipmap,当成员数量增大的时候自动转成真正的hashmap,此时encoding为ht
命令:
- hset:设置key对应的hashmap中的field的value
- hget:获取key对应的hashmap中的field的value
2.3、list
lpush:在key对应的list头部添加一个元素
lrang:获取key对应list的指定下标范围元素,-1表示获取所有元素
lpop:从key对应的list头部删除一个元素,并返回该元素
rpush:在key对应的list尾部添加一个元素
rpop:从key对应的list尾部删除一个元素,并返回该元素
lrem:删除指定的list的value
LREM key count value 根据参数 count 的值,移除列表中与参数 value 相等的元素。 count 的值可以是以下几种: count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。 count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。 count = 0 : 移除表中所有与 value 相等的值。
2.4、set
- sadd:在key对应的set中添加一个元素
- smembers:获取key对应的set所有元素
- spop:随机返回并删除key对应set中的一个元素
- suion:求给定key(两个以上)对应的set并集
- sinter:求给定key(两个以上)对应的set交集
- sdiff:求给定key(两个以上)对应的set差集,第一个key有,后面的key没有的数据。
2.5、sorkSet
在set的基础上增加顺序,set的基础上增加score元素,根据score进行排序。例如:排行榜等等。
- zadd:在key对应的zset中添加一个元素
- zrange:获取key对应zset中指定范围的元素,-1表示获取所有
- zrem:删除key对应的zset中的一个元素
- zrangebyscore:返回有序集key中,指定分数范围的元素
- zrank:返回key对应的zset中指定排名,其中member按score值递增(从小到大);排名以0为底,也就是说score最小的成员为0
- zrevrange:与zrank相反,member按score值递增(从大到大);
三、发布订阅消息
功能比较薄弱,但是毕竟轻量。一般使用MQ,mq支持持久化。
- PUBLISH:将消息message发送到指定的频道channel,返回收到消息的客户端数量
- SUBSCRIBE:订阅指定频道的消息
- UNSUBSCRIBE:取消订阅指定的频道,如果不指定,则取消订阅的所有频道
四、Redis6.x
4.1 多线程
redis6增加了多线程的特性,这里多线程只是针对网络的读写和协议的解析操作,真正处理redis数据的还是单线程。这里的多线程不存在安全问题。
4.2 acl 权限控制
之前的redis没有用户的概念,redis6引入了acl,可以给每个用户分配不同的权限来控制权限,通过限制对命令和密钥的访问来提高安全性,以使不受信任的客户端无法访问。提高操作安全性,以防止由于软件错误或人为错误而导致进程或人员访问 Redis,从而损坏数据或配置。
默认是default用户,具有所有的key权限
常用acl命令:
- acl list 当前启用的 ACL 规则
- acl cat 支持的权限分类列表
- acl cat hash 返回指定类别中的命令
- acl setuser 创建和修改用户命令
- acl deluser 删除用户命令。
+<command> 将命令添加到用户可以调用的命令列表中,如+@hash
-<command> 将命令从用户可以调用的命令列表中移除
#切换默认用户
auth default 123456
#例子 密码 123 ,全部key,全部权限
acl setuser jack on >123 ~* +@all
#例子 密码 123 ,全部key,get权限
acl setuser jack on >123 ~* +get
参数说明:
参 数 | 说明 |
---|---|
user | 用户 |
default | 表示默认用户名,或则自己定义的用户名 |
on | 表示是否启用该用户,默认为off(禁用) |
#... | 表示用户密码,nopass表示不需要密码 |
~* | 表示可以访问的Key(正则匹配) |
+@ | 表示用户的权限,“+”表示授权权限,有权限操作或访问,“-”表示还是没有权限; @为权限分类,可以通过 ACL CAT 查询支持的分类。+@all 表示所有权限,nocommands 表示不给与任何命令的操作权限 |
4.3 Client-Side-Caching 客户端缓存
redis支持客户端缓存数据。客户端缓存类似于浏览器缓存,当客户端1访问过这个key以后就会记录这个可以进入本地缓存,再次获取的时候不会发送远程的请求。当客户端2修改了这个key,redis server端会通知其它的客户端这个使得本地缓存的key失效。
目前java客户端的lettuce支持这种客户端缓存的方式。
优点:提高了效率
缺点:如果通知客户端的时候server端宕机了,会出现数据不一致的现象
客户端缓存分为两种模式:
默认模式
- Server 端全局唯一的表(Invalidation Table)记录每个Client访问的Key,当发生变更时,向client推送数据过期消息。
- 优点:只对Client发送其访问过的被修改的数据
- 缺点:Server端需要额外存储较大的数据量。
- Server 端全局唯一的表(Invalidation Table)记录每个Client访问的Key,当发生变更时,向client推送数据过期消息。
广播模式
- 客户端订阅key前缀的广播,服务端记录key前缀与client的对应关系。当相匹配的key发生变化时通知client。
- 优点:服务端记录信息比较少
- 缺点:client会收到自己未访问过的key的失效通知