redis有16个数据库(0~15),默认是0号数据库
切换数据库:select xxx eg:select 3
查看当前数据库大小:DBSIZE
key
查看当前数据库所有的key:keys *
清空当前库/所有:flushdb/flushall
判断某个键是否存在:exist xxx eg:exist name(判断key为name的键是否存在)
将key移动到另一个数据库:move xx xx eg:move name 1(将key为name的键移动到数据库[1])
设置key过期时间:EXPIRE xx xx eg:EXPIRE name 10(key为name的键10秒后过期)
查看当前key的剩余时间:ttl xxx eg:ttl name(查看key为name的键剩余时间)
查看key的类型:type xxx eg:type name(查看key为name的类型)
String
追加字符串:append xxx xxx eg:append key1 "Hello World" 【注】如果当前key不存在就相当于set key
查看key对应的value值的长度:STRLEN xxx eg:STRLEN key1
i++ :incr xxx eg:set views 0 ==> incr views (则在0的基础上加1) / incr views 10(在0的基础上加10)
i-- :decr xxx eg:set views 0 ==> decr views(则在0的基础上减1) / decr views 10(在0的基础上减10)
按范围获取字符串:GETRANGE xxx start end eg:GETRANGE key1 0 3 【注】:0和3是闭区间 / GETRANGE key1 0 -1 (表示全部获取)
替换指定位置开始的字符串:SETRANGE xxx x eg:SETRANGE key2 xx (例如原字符串abcdef 则替换之后为axxdef)
同时设置/获取多个值: eg:mset key1 v1 key2 v2 key3 v3 / mget key1 key2 key3
List
向list中增加元素(头部插入):LPUSH xx xx eg:LPUSH list one LPUSH list two LPUSH list three(输出为 three two one)【注】如果为RPUSH list hhh 则输出为 three two one hhh (尾部插入)
获取list元素/指定位置获取:LRANGE xx x x eg:LRANGE list 0 -1(代表获取list中的全部元素)/ LRANGE list 0 1(0 1 为闭区间 取到的是three two 类似于栈,先进后出)
移除列表里的第一个元素:LPOP/RPOP eg:LPOP list 则输出为three RPOP list 输出为hhh
通过下标获取值:Lindex xxx x eg:Lindex list 0
获取list的长度:Llen xxx eg:Llen list
移除指定的值:LREM xxx x x eg:LREM list 1 one (移除list中的一个one) /LREM list 2 three(移除list中的2个three) 【注】list中可以放重复值,所以可能会有两个three
截取部分值:LTRIM xxx x x eg:LTRIM list 1 2 (1,2 为闭区间)
移除列表最后一个元素并移动到新的列表中:rpoplpush xx xx eg:rpoplpush list1 list2
将列表中指定下标的值替换为另一个值:LSET xxx x xx eg:LSET list 0 item(如果指定下表无值或者列表不存在则会报错)
将某个具体的元素加入到列表中某个元素的前面或者是后面:LINSERT xxx before/after xxx eg:LINSERT list before hhh
Set
添加元素 sadd xxx xx eg:sadd list "hhh"
查看指定set的所有值:smembers xxx eg:smembers list
判断指定元素是否存在:sismember xxx xx eg:sismember list hhh (判断hhh是不是在list中)
获取set集合中的个数:scard xxx eg:scard list (将返回set中元素的个数)
移除set中的指定元素:srem xxx xx eg:srem list hhh
随机抽选set中的元素:srandmember xxx (x) eg:srandmember list (2) (如果加上2就是随机抽选2个)
随机删除key:spop xxx eg: spop list(会随机删除list中的一个key)
将一个指定的值移动到另一个set中:smove xxx xxx xx eg:smove set1 set2 hhh
查看两个集合的交集:SINTR xxx xxx eg:SINTR set1 set2
查看两个集合的并集:SUNION xxx xxx eg:SUNION set1 set2
查看两个集合的差集:SDIFF xxx xxx eg:SDIFF set1 set2
Hash
设置一个具体的key-value: hset xxx xx xx eg:hset myhash field1 hhh
设置多个key-value:hmset xxx xx xx eg:hmset myhash field1 hello field world
获取一个字段值:hget xxx xx eg:hget myhash field1
获取多个字段值:hmget xxx xx xx eg:hmget myhash field1 field2
获取全部的数据:hgetall xxx eg:hgetall myhash
删除hash指定key字段:hdel xxx xx eg:hdel myhash field1
获取hash的字段数量:hlen xxx eg:hlen myhash
判断hash中的key是否存在:hexists xxx xxx eg:hexists myhash field1
只获得所有的key:hkeys xxx eg:hkeys myhash
只获得所有的value:hvals xxx eg:hvals myhash
Zset
增加元素:zadd xxx xx xx eg:zadd score 90 xiaohong
数据排序:zrangebyscore xxx xx xx eg: zrangebyscore score -inf +inf
事务
Redis事务没有隔离级别的概念!
所有命令在事务中,没有直接被执行,只有发起执行命令的时候才会被执行。
Redis单条命令是保证原子性的,但是事务不保证原子性。
Redis的事务:开启事务(multi)、命令入队(......)、执行事务(exec)
放弃事务:DISCARD
编译型异常(代码有错、命令有错),事务中所有的命令都不会被执行。
运行时异常(1/0),如果事务队列中存在语法性错误,其他命令可以正常执行,错误命令抛出异常。
锁
悲观锁:认为什么时候都会出问题,无论什么都加锁。
乐观锁:认为无论什么时候都不会出问题,不加锁。更新数据的时候去判断一下在此期间是否有人更改过数据(获取version,更新的时候比较version)
Redis用watch可以实现乐观锁
SpringBoot整合Redis
@Configuration
public class RedisConfig {
//编写我们自己的redisTemplate
@Bean
public RedisTemplateredisTemplate(RedisConnectionFactory factory)throws UnknownHostException{
//为了我们自己开发方便,一般直接使用
RedisTemplate template =new RedisTemplate<>();
template.setConnectionFactory(factory);
//json序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om =new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//String的序列化
StringRedisSerializer stringRedisSerializer =new StringRedisSerializer();
//key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
//hash的key采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
//hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
持久化之RDB操作
在指定的时间间隔内将内存中的数据集体写入磁盘
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程不进行任何IO操作,确保了极高的性能,如果需要大规模数据的恢复,且对于数据恢复的完整性不是十分敏感,那RDB方式要比AOF方式更加高效。RDB的缺点是最后一次持久化后的数据可能丢失。
rdb的保存文件是dump.rdb
触发机制:1.save规则满足的情况下,会自动触发rdb规则 2.执行flushdb命令,也会触发rdb规则 3.退出redis,也会产生rdb文件
备份就会自动生成一个dump.rdb文件
只需要将rdb文件放在redis的启动目录,redis启动的时候就会自动检查dump.rdb文件,恢复其中的数据。
持久化之AOF操作
如果append.aof文件有问题,将不能启动Redis,需要用redis-check-aof --fix来修复。如果文件修复好,重启就好了。
Redis发布订阅
使用场景:1.实时消息系统 2.实时聊天 3.订阅、关注系统
Redis主从复制
SLAVEOF host port eg:SLAVEOF 127.0.0.1 6379 (认6379做主机)
主机可以写,从机不能写只能读。从机会自从保存主机的所有信息和数据。主机断开连接,从机依旧是连接到主机的,主机回来之后从机依旧可以得到主机的信息。如果是用命令行配置的主从,如果重启了就会变为主机。
哨兵模式
配置哨兵文件(sentinel.conf)
如果主机挂了,会从从机里选择新的作为主机,如果主机回来了,只能归并到当前主机下作为从机。
Redis缓存穿透、缓存击穿和缓存雪崩
缓存穿透: