Redis中数据类型中分为八种 前五种为基本数据类型 后三种为特殊数据类型
一、String:
1.set key value
添加键值对
2.get key
获取key中的value
3.append key value
向key中追加值(value)
4.strlen key
获取key的长度
5.setnx key value
只有key不存在的时候才会设置key
6.incr key
指定的key 每次+1
7.decr key
指定的key 每次-1
8.incrby key value
指定的key每次+多少value
9.decrby key value
指定的key每次-多少value
10.mset key1 value1 key2 value2
同时设置多个key value
11.mget key1 key2
同时取出多个key的value
12.msetnx key1 value1 key2 value2
也是同时设置多个(key不存在时) 如果存在 会返回0 表示失败
13.getrange key 起始位置 结束位置
获取值的范围 例如 getrange key1 0 -1 获取下标从0开始到尾结束
14.setrange key 起始位置 value
向key中指定的位置插入值
15.setex key (秒) value
设置key的有效时间
16.getset key value
修改原来的value并让原来的value打印出来
二、List:特点:单键多值 底层双向链表实现 可重复 有序
1.lpush/rpush key value1 value2 ...
从左边/右边插入一个或多个值
2.lpop/rpop key
从左边/右边吐出一个值。当所有的value都吐出后 key将不存在
3.rpoplpush key1 key2
从key1列表右边吐出一个值插入到key2的左边 (剪切的意思)
4.lrange key 起始位置 结束位置
根据下标来获取值
5.lindex key index
按照下标取值(从左到右)
6.llen key
获取长度
7.linsert key (before/after/between) value newvalue
在value之前或者之后亦或者之间插入一个值
8.lrem key n value
从左边删除n个指定的值(从左到右)
9.lset key index value
将index位置的值替换成value
三、Set:自动排重 无序集合
1.sadd key value1 value2 ....
一个key设置多个值 重复的自动忽略
2.smembers key
取出key中所有的值 忽略重复
3.sismember key value
判断key是否含有value 有返回1 无返回0
4.scard key
返回这个key中的个数
5.srem key value1 value2 ...
删除key中的元素
6.spop key
随机从key中吐出一个值 都吐出来后key将不存在
7.srandmember key n
随机从key中取出n个值
8.smove key1 key2 value
将key1集合中的value 移动到key2中
9.sinter key key2
取出两个key中的交集(公有的value)
10.sunios key1 key2
取出两个key中的并集(所有的value)
11.sdiff key1 key2
取出两个key中的差集(key1中包含的value key2中不包含的value)
四、Hash 以对象存储 例如 user uname zhangsan user即key uname即field zhangsan即value
1.hset key field value
给key中的field赋值
2.hget key field
从key中将field的值取出
3.hmset key1 field1 value1 field2 value2 ..
批量设置hash的值
4.hexists key1 field
查看hash表key中field是否存在
5.hkeys key
列出该hash集合的所有field
6.hvals key
列出该hash集合所有的value
7.hincrby key field increment
为哈希表key中的域field的值加上增量 +1/-1
8.hsetnx key field value
将哈希表key中的域field的值设置为value 但必须field不存在才能设置
注意:Hash类型对应的数据结构是两种:ziplist(压缩列表)、hashtable(哈希表) 当field-value长度短且个数少的时候使用的是ziplist 否则使用hashtable
五、Zset:有序集合 与set集合不同的是 有序集合每个成员都关联了一个评分(score)
这个评分被用来按照从最低分到最高分的方式排序集合中的成员 集合成员
是唯一的但是评分是可以重估的
因为元素是有序的
1.zadd key score1 value1 score2 value2
将一个或多个member元素
2.zrange key start(0) stop(-1)
根据key取值 这里的顺序是按score顺序从小到达(只取value)
3.zrange key start(0) stop(-1) withscores
根据key取值 带withscores代表在这个范围的 score和value都取出来
4.zrangescore key min max
按score范围取value
5.zrangescore key min max withscores
按score范围取socre和value
6.zrevrangebyscore key max main
按score范围从大到小进行排序取值
7.zrevrangebyscore key max main withscores
按score范围从大到小进行排序取值和score
8.zincrby key increment value
给key中通过value给score增加
9.zrem key value
通过value来删除这个key中的值包括score
10.zcount key min max
查询 key中 score最小范围到最大范围的值
11.zrank key value
查看key中的value排在第几位(从0开始)
六、Bitmaps:都是操作二进制位来进行记住 只有0和1两个状态
1.setbit key <offset> value
赋值操作
2.getbit <key> <offset>
根据key、偏移量取值
注意:如果访问过则返回的是1 没有访问过返回的是0
3.bitcount <key>
统计字符串被设置为1的bit数
七、Hyperloglog:
优点:占用内存是固定的 一个long类型 仅仅占用12kb 错误率0.81%
命令:PFadd <key> value1 value2 value3 value4.....
PFCOUNT <key> 查看value的个数
PFMERGE <newKey> <key1> <key2> 将key1和key2中的value合并到newKey中
八、geospatial 地理位置
注意:china:city是key 经纬度城市名是value
1.geoadd china:city 经度 纬度 城市名
经纬度小数点后保留两位
2.GEOPOS china:city 城市名
获取经纬度的值
3.GEODIST china:city 城市名1 城市名2
查看两个城市的距离
4.GEORADUIS china:city 经度 纬度 半径(xxkm) [withdist]
查看以经纬度为中心寻找半径距离内的城市距离并查看直线距离
5.GEORADUIS china:city 经度 纬度 半径(xxkm) [withcorrd]
查看以经纬度为中心寻找半径距离内城市的直线距离并查看经纬度
6.GEORADUIS china:city 经度 纬度 半径(xxkm) [withdist] [withcorrd] count n
查看以经纬度为中心寻找半径内城市的直线距离和经纬度及数量
7.GEORADUISBYMEMBER china:city 城市名 半径(xxkm)
查看以城市名为中心寻找半径内的城市
Redis事务:
概念:
事务的本质:一组命令的集合!一个事务的命令中的所有命令都会被序列化,
在事务执行过程中,会按照顺序执行 Redis单条命令是保存原子性的 但是事务不保证原子性!
注意:事务没有隔离级别的概念 所有的命令在事务中并没有直接被执行 只有发起执行命令的 时候才会执行(exec)
事务命令:
开启事务(multi)
命令入队(set get等操作)
执行事务(exec):当命令入队后 执行次命令时 会依次执行命令入队的命令
注意:每次exec后代表当前事务结束 需要再次开启事务
放弃事务(discard) 取消事务后命令入队的操作将不会被执行
编译型异常(命令有错误):所有的命令都不会被执行
运行时异常:如果事务队列中存在语法性, 那么执行其他命令的时候是可以执行的
Redis锁机制:
悲观锁:
简单来说 认为无论时候都会出问题 无论做什么都会加锁!
乐观锁:
简单来说 认为什么时候都不会出问题 所以不会上锁 更新数据的时候判断一下 在此期间数据 是否被修改过
*面试常问:程序并发时使用的是什么锁?为什么?
一般情况下使用的都是乐观锁 因为悲观锁无论做什么都会加锁 这样执行效率就会极其低下
Redis监听:
通过乐观锁的方式进行监听 比方说有两个线程A、B
线程A:此时正在进行事务操作并进行监听(watch key) 线程B突然打断了线程A的事务操作 这个时候 线程A提交事务(exec) 则会返回(nil)
如果此时想获得线程B操作的数据 则在线程A中取消监听(unwatch key) 再重新监听事务(watch key)
注意:先监听key再进行事务的操作Jedis:
什么是Jedis:
是Redis官方推荐的Java连接开发工具 使用Java操作Redis中间件
使用步骤:
1.导入相关依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>X.X.X</version>
</dependency>
2.连接数据库
1.创建Jedis对象
Jedis jedis = new Jedis("地址",端口号);
再这个对象中可以使用redis命令
2.常用API:
String、List、Set、Zset、Hash
SpringBoot整合:
SpringBoot操作数据: spring-data jpa jdbc mongodb redis
SpringData也是和SpringBoot齐名项目
在SpringBoot2.X之后,原来使用的jedis被替换为了lettuce
jedis:采用的是直连方式,线程不安全
lettuce:采用netty 实例可以再多个线程中进行共享 不存在线程不安全的情况 可以减少数据 更 像NIO
源码分析:
在@SpringBootApplication这个注解中可以发现如下注解 @EnableAutoConfiguration
是开启自动配置的意思
再次点入@EnableConfiguration 大家都知道@Import是导入的意思 但是这个注解中包含了一个类AutoConfigurationImportSelector.class 这个类的意思为自动选择配置导入器 再点入这个类中
再AutoConfigurationImportSelector.class这个类中可以看到NotEmpty方法 这个方法中的字符串是告诉我们需要找到Spring.factories这个文件 关于这个方法的实现在之前的文章中有详细说明可以参考看一下 这个文件在org.springframework.spring.boot:spring-boot-autoconfigure这个依赖的META-INF文件夹下
在Sping.factories这个文件中ctrl+f 搜索Redis可以看到RedisAutoConfiguration 这个类就是SpringBoot实现的自动装配
在这个类中可以看到以下信息
再次点入RedisProperties类就可以看到一些配置文件中相关的配置如此便完成了自动装配
RedisTemplate使用:
Redis配置文件
单位: 对大小写不敏感
包含:
通用:
网络:
bind 127.0.0.1 #绑定的IP
procted-modes yes #受保护模式开启 保证安全性
port 6379 端口号
通用:
daemonize yes #以守护进程方式运行 默认为no
profile /var/run/redis_6579.pid #以后台方式运行就需要指定一个pid文件
loglevel #日志级别
databeses #数据库数量 默认16
always-show-logo #是否显示redis的logo 默认为yes开启
快照:
save 900 1 #多长时间内执行多少次
save 300 10
save 60 10000
持久化:
stop-writes-on-bgsave-error yes #持久化如果出错 是否还需要继续工作
rdbcompression yes #是否压缩rdb文件,需要消耗一些cpu资源
rdbchecksum yes #保存rdb文件的时候,进行错误的检查校验
dir ./ rdb保存的目录
主从复制:
replicaof ip 端口号 #进行认主操作
安全(SECURITY):
requirepass 密码 #设置redis密码 默认为空 设置密码后需要登陆 auth 密码
客户端(Clients):
maxclients 10000 # 设置最大客户端连接数
内存:
maxmemory-policy noeviction #内存到达上限之后的处理策略
#主要分为六种策略
1.volatile-lru:只对设置了过期时间的key进行删除
2.allkeys-lru:删除
3.volatile-random:随机删除即将过期的key
4.allkeys-random:随机删除
5.volatile-ttl:删除即将过期的key
6.noeviction:永不过期 返回错误
AOF:
appendonly no #默认不开启aof模式 默认使用rdb方式持久化 在大部分情况下使用的都是rdb
appendfilename "appendonly.aof" #持久化文件的名字
appendfsync always #每次修改都会同步 速度慢 消耗性能
appendsync everysec #每秒执行一次 可能丢失1s数据
appendsync no #不执行同步 这个时候操作系统自己同步数据 速度最快!
Redis修改密码命令 config set requirepass "XXX" 如果为null就没有密码
RDB持久化:
因为Redis默认启动的是RDB的方式进行持久化 并且在配置文件中 appendonly 设置为no
关闭了AOF持久化的方式 所以什么操作也不做的情况下使用的是RDB的方式
rdb保存的文件是dump.rdb 都是在我们配置文件中快照中进行配置的!
当在conf文件夹中修改了保存快照的设置 在bin目录中就会生成一个dump.rdb的文件
此时需要进行删除这个文件 rm -rf dump.rdb 此时 还需要保存配置文件的修改 命令:save
当保存过后 进行正常操作后 比如 配置文件中我设置的是 save 60 6 就是60秒内执行六次的 保存操作 又在redis中 set了6次key value 这时 在bin目录中就会生成一个dump.rdb文件
触发机制:
当开启RDB模式后 设置了key value 重新连接redis 再次get 一下刚才设置的key 这个时候
还是会获取到value 也就是说 它的值存储在 dump.rdb中 也就是说 我们上述描述的操作满
足了save的规则 它才触发了rdb的规则 生成了dump.rdb 或者是 执行flushall 命令的时候也
会触发rdb规则 产生rdb文件 退出redis 也会产生rdb文件 备份就自动生成一个dump.rdb
如何恢复rdb:
只需要将rdb文件放在redis的启动目录就可以了,redis启动的时候会自动帮我们检查dump.
rdb 恢复其中的数据
优点:
适合做大规模的数据恢复
对数据的完整性要求不高
缺点:
需要一定的时间间进程操作
AOF持久化:
将我们的所有命令都记录下来,恢复的时候就把这个文件全部执行一遍
在redis配置文件中将appendonly no 改为yes 即可 重启redis后便开启
了 AOF持久化模式 并且会在bin目录下生成.aof结尾的文件 当我们每次
进行写操作的时候都会在这个文件中追加 如 如果这个文件被特定的修改
了(损坏) 那么redis是启动不起来的 我们需要修复这个aof文件 才可以让
redis正常启动 如何修复?同样在bin目录下面执行命令 redis-check-aof
--fix appendonly.aof 启动这个命令后便可启动redis访问了
优点:
1.每次修改的时候都会进行同步,文件的完整性更好
2.每秒同步一次,可能会丢失秒级的数据
3.从不同步,效率最高
缺点:
1.相对于数据文件来说,aof远大于rdb,修复的速度也比rdb慢
2.运行效率低于rdb,所以redis默认的配置就是rdb的方式
订阅发布:
订阅:SUBSCRIBE CHANNEL(频道)
发布:PUBLISH CHANNEL message
主从复制:
主机:master 从机:slave
什么是主从复制:简单来说就将原来的一台主机复制成多个 原来的那台就是主机
复制后的就是从机 数据的复制是单向的 只能由主机到从机 master以写为主 Slave
以读为主 从而减少服务器的压力
主要作用:
1.数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式
2.故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的恢复
3.负载均衡:主从复制的基础上,配合读写分离,可以由主节点提供写服务,
由从节点提供读服务 分担服务器负载;尤其是在写少读多的场景下,通过多
个节点分担读负载,可以大大提高Redis服务器的并发量
4.高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础
因此说主从复制是redis高可用的基础
单台Redis最大使用内存不应该超过20G
查看当前redis机器信息 info replication 如果role信息显示的是master 那就是主机
注意:redis主从复制需要修改从节点的配置文件信息
1.port 6380 不能与其他信息一致
2.profile /var/run/redis_6380.pid 不能与其他机器一直
3.logfile "" 不能与其他机器一直后台启动改为yes dbfilename dump6480.rdb
配置好集群机器后注意每一台都是主机节点 如果要配置主从的关系 从机需要进行一个
认主的操作 SLAVEOF IP地址 端口号 这样指定的机器为从机的主机 再次输入命令
info replication的时候就会看到 role的信息变成了salve 即从机 这样认主就成功了
因为目前是通过命令的方式配置的主从复制 这个时效是暂时的 如果想通过永久性的
需要通过配置文件的方式来进行配置 在redis.conf配置文件中可以找到 replicaof
<masterip> <masterport> 输入主机ip和主机的端口号即可完成配置
复制原理:全量复制、增量复制
全量复制:在slave连接上master后会进行一次同步将master中的内容同步到slave
增量复制:在slave连接master时master再次写入的时候 slave通用可以获取到数据
哨兵:
什么是哨兵:在多台Redis机器上会有一台主机和多台从机 这个时候哨兵会对主机和
从机进行一个监控的状态 如果主机宕机在一定时间内并没有向哨兵发送实时的心跳包
哨兵会在从机上进行选举选出来一台机器当作主机
配置命令:在bin目录中编辑并配置sentinel.conf文件
文件内容:sentinel monitor 名字(任意) 需要监控的主机地址 端口号 1(投票机制)
配置好后开启哨兵 命令:在bin目录下输入命令 redis-sentinel sentinel.conf 代表指定
配置文件启动 这样哨兵就可以实时对机器进行监控
缓存:
什么是缓存:当客户端需要查询某条数据时 此时会先去看缓存中有没有需要的那条数
据如果有直接对客户端返回 如果没有就会进行对DBMS查询 再返回给用户 并把这条数
据存储到Redis中 下次访问这条数据时直接从缓存中返回数据
穿透: 当客户端查询某条数据,发现redis缓存中没有这条数据 于是向DBMS查询发现DBMS中
也没有 也就是查询失败 当多个客户端也就是多个用户都去访问了持久层数据库 这会给
数据库造成很大的压力 这时候就相当于出现了缓存穿透
解决方案:布隆过滤器 布隆过滤器是一种数据结构 对所有可能查询的参数以hash的形
式存储 再控制层先进行校验 不符合则丢弃,从而避免了对底层存储系统的查询压力
击穿: 缓存击穿是指一个key热度非常高 大并发集中对这一个点进行访问,当这个
key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,当某个key在过期的瞬
间,有大量的请求并发访问,这类数据一般是热点数据,由于缓存过期,会同时访问数
据库来查询最新数据,并且写回缓存,会导致数据库瞬间压力过大
解决方案:1.设置key永不过期 缺点 容易浪费空间 2. 加锁 :保证只有一个线程进去其余
的进行等待状态
雪崩: 是由于原有的缓存失效(过期) 新缓存未到期间 所有的请求都会去访问DBMS 从而对CPU
和内存造成了巨大的压力 严重情况下会导致宕机 从而形成一系列的连锁反应,造成整个
系统崩溃。
解决方案:给每个缓存数据增加相应的缓存标记,记录缓存是否失效,如果缓存失效,则更
新数据缓存即可。