Redis将所有的数据都存放在内存中,所以读写速度很快。同时,Redis将内存中的数据以快照或日志的形式保存到硬盘上,以保证数据的安全性。
Redis典型的应用场景:缓存、排行榜(热门帖子的缓存)、计数器(某一个帖子的访问量)、社交网络(点赞,关注等)、消息队列等。
redis-server redis.conf
启动redis服务端,使用不同的配置文件时,启动起来的redis不一样。redis-cli [-p 6379]
启动redis客户端,select [id]
id默认为0select
命令切换数据库dbsize
查看当前数据库的key的数量flushdb
清空当前库flushall
清空全部库Redis的配置文件redis.config位于redis目录下,配置文件中内容大小写不敏感,且1k与1kb不一样。
config get 配置设置名
:获取配置文件中某选项的值。
config set 配置文件名
:设置配置文件中某选项的值。
操作:
keys *
:查看当前库所有key(匹配:keys *1)exists key
:判断某个key是否存在type key
:查看你的key是什么类型del key
:删除指定的key数据unlink key
:根据value选择非阻塞删除,仅将keys从keyspace元数据中删除,真正的删除会在后续异步操作。expire key [number]
:为key设置过期时间,时间以秒为单位,比如expire key 10表示十秒后过期。ttl key
:查看还有多少秒过期,-1表示永不过期,-2表示已过期字符串实际分配的空间capacity一般要高于实际字符串长度len。当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时一次只会多扩1M的空间。⚠️字符串最大长度为512M。
String的数据结构为动态字符串,是可以修改的字符串,内部结构实现上类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。
常用命令
set
:添加键值对get
:查询对应键值append
:将给定的追加到原值的末尾strlen
:获得值的长度setnx
:只有在key不存在时,设置key的值incr
:将key中存储的数字值增1,只能对数字值操作,如果为空,新增值为1decr
:将key中存储的数字值减1,只能对数字值操作,如果为空,新增值为-1incrby/decrby <步长>
:将key中存储的数字值增减,自定义步长mset …
:同时设置一个或多个key-value对mget …
:同时获取一个或多个valuemsetnx …
:同时设置一个或多个key-value对,当且仅当所有给定key都不存在getrange <起始位置> <结束位置>
:获得值的位置,类似Java中的substring,前包,后包setrange <起始位置>
:用覆写 所存储的字符串值,从<起始位置>开始(索引从0开始)setex <过期时间>
:设置键值的同时,设置过期时间,单位秒getset
:以新换旧,设置了新值同时获得旧值单键多值,Redis列表是简单的字符串列表,按照插入顺序排序,底层实际是个双向链表。
常用命令
lpush/rpush …
:从左边/右边插入一个或多个值。lpop/rpop
:从左边/右边吐出一个值。值在键在,值光键亡。rpoplpush
:从列表右边吐出一个值,插到列表左边。lrange
:按照索引下标获得元素(从左到右),lrange key 0 -1表示取所有。lindex
:按照索引下标获得元素(从左往右)。llen
:获得列表长度。linsert before/after
:在的前面/后面插入插入值。lrem
:从左边删除n个value(从左到右)。lset
:将列表key下标为index的值替换成value。set与list类似,也是一个列表的功能,特殊之处在于set是可以自动排重的。set是String类型的无序集合,它的底层其实是一个value为null的hash表,所以添加、删除和查找的复杂度都是O(1)。
set数据结构是dict字典,字典是用哈希表实现的。
常用命令
sadd …
:将一个或多个member元素添加到集合key中,已经存在的member元素将被忽略。smembers
:取出该集合的所有值。sismember
:判断集合是否含有该值,有1,没有0。scard
:返回该集合的元素个数。srem …
:删除集合中的某个元素。spop
:随机从集合中吐出一个值。srandmember
:随机从该集合中取出n个值。不会从集合中删除。smove
:把集合中一个值从一个集合移动到另一个集合。sinter
:返回两个集合的交集元素。sunion
:返回两个集合的并集元素。sdiff
:返回两个集合的差集元素(key1中的,不包含key2中的)。hash是一个键值对集合,是一个string类型的field和value的映射表,hash表特别适合用于存储对象。类似于Java里面的Map
。
hash类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable。
常用命令
hset
:给集合中的键赋值hget
:从集合域中取出valuehmset …
:批量设置hash值hexists
:查看hash表key中,给定域field是否存在,存在1,不存在0hkeys
:列出该hash集合的所有fieldhvals
:列出该hash集合的所有valuehincrby
:为hash表key中的域field的值加上增量incrementhsetnx
:将哈希表key中的域field的值设置为value,当且仅当域field不存在zset与普通集合set非常相似,是一个没有重复元素的字符串集合。有序集合的每个成员都关联了一个评分(score),这个评分被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员时唯一的,但是评分可以是重复的。
zset底层使用了两个数据结构(1)hash,hash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。(2)跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。
常用命令
zadd …
:将一个或多个member元素及其score值加入到有续集key当中。zrange [WITHSCORES]
:返回有序集合key中,下标在 之间的元素,带WITHSCORES,可以让分数一起和值返回到结果集。 zrangebyscore key min max [withscores] [limit offset count]
:返回有序集key中,score值介于min和max之间(包括等于min或max)的成员。有序集成员按score值递增(从小到大)次序排列。zrevrangebyscore key max min [withscores] [limit offset count]
:同上,改为从大到小排序。zincrby
:为元素的score加上增量。zrem
:删除该集合下,指定值的元素。zcount
:统计该集合,分数区间内的元素个数。zrank
:返回该值在集合中的排名,从0开始。bitmaps(位图)本身不是一种数据类型,实际上是字符串,但是可以对字符串的位进行操作。
bitmaps单独提供了一套命令,所以与string使用方法不太相同。可以把bitmaps想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在bitmaps中叫做偏移量。
命令:
setbit
:设置bitmaps中某个偏移量的值(0或1)。⚠️注意:偏移量从0开始。getbit
:获取bitmaps中某个偏移量的值,即某个key键的offset的值。bitcount [start] [end]
:统计bitmaps中被设置为1的bit数。默认情况下,给定的bitmaps都会被进行计数,通过指定额外的start或end参数,可以让计数只在特定的位上进行。⚠️注意:redis的setbit设置或清除的是bit位置,而bitcount计算的是byte位置。bitop and(or/not/xor) [key…]
:符合操作,可以做多个bitmaps的and(交集),or(并集),not(非),xor(异或)操作,并将结果保存在destkey中。bitmaps与set对比:
- 当用bitmaps和set分别存储网站的活跃用户时,bitmap可以节省很多的内存空间。
- 但是如果网站每天独立访问用户很少(大量的僵尸用户),那么使用bitmaps就不太合适了。
HyperLogLog(超级日志),可以对数据统计,也可以对数据合并。采用一种基数算法,用于完成独立总数的统计。不精确的统计算法,标准误差为0.81%。
占据空间小,无论统计多少个数据,只占12K的内存空间,适用于输入元素的数量或者提及非常大时。但是,因为HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
命令:
pfadd [element …]
:添加指定元素到HyperLogLog中。操作成功返回1,操作失败返回0。pfcount [key …]
:计算HyperLogLog的近似基数,可以计算多个。pfmerge [sourcekey …]
:将一个或多个HyperLogLog合并,并将合并后的结果存储在另一个HyperLogLog中。GEO,Geographic,地理信息的缩写。该类型,就是元素的2维坐标,在地图上就是经纬度。redis基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度Hash等常见操作。
命令:
geoadd [longitude latitude member…]
:添加地理位置(经度,纬度,名称)。有效的经度从-180度到180度,有效的维度从-85.05112878度到85.05112878度,当坐标位置超出指定范围时,返回一个错误。geopos [member…]
:获得指定地区的坐标值。geodist [m|km|ft|mi]
:获取两个位置之间的直线距离。单位:m表示米,[默认值];km表示千米;mi表示英里,ft表示英尺。georadius radius m|km|ft|mi
:以给定的经纬度为中心,找出某一半径内的元素。参数为:经度 纬度 半径 单位。subscribe channel1 [channel2
…]
;publish channel message
在pom.xml文件中引入redis相关依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
在application.properties文件中进行redis相关配置
#Redis服务器地址
spring.redis.host=127.0.0.1
#Redis服务器连接端口
spring.redis.port=6379
#Redis数据库索引(默认为0)
spring.redis.database=0
#连接超时时间(毫秒)
spring.redis.timeout=1800000
#连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=20
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
#连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0
添加redis配置类,构造Spring Redis的核心组件RedisTemplate,这个组件是由Spring提供的
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String,Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 设置key的序列化方式
template.setKeySerializer(RedisSerializer.string());
// 设置value的序列化方式
template.setValueSerializer(RedisSerializer.json());
// 设置hash的key的序列化方式
template.setHashKeySerializer(RedisSerializer.string());
// 设置hash的value的序列化方式
template.setHashValueSerializer(RedisSerializer.json());
template.afterPropertiesSet();
return template;
}
}
测试一下
@SpringBootTest
class RedisSpringbootApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testRedis(){
redisTemplate.opsForValue().set("name","Amy");
String name = (String) redisTemplate.opsForValue().get("name");
System.out.println(name);
}
}
补充:导入依赖时同时需要导入spring-boot-starter-web和spring-boot-starter-test,否则的话在运行测试函数的时候会报java.lang.IllegalStateException: Failed to load ApplicationContext
错误。为什么呢?
multi
:标记一个事务块的开始,在此之后的命令只是入队但没执行exec
:执行所有事务块内的命令,在此之前只是入队但没执行discard
:取消事务,放弃执行事务块内的所有命令watch key1 [key2
…]
:在执行multi之前,先执行 watch命令,可以监视一个(或多个)key,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断。unwatch
:取消watch命令对所有key的监视。如果在执行watch命令之后,exec命令或discard命令先被执行了的话,那么就不需要再执行unwatch了。dbfilename dump.rdb
dir ./
config get dir
配置文件中snapshotting
快照配置
命令
save
:只管保存,其他不管,全部阻塞。
bgsave
:在后台异步进行快照操作,快照同时还可以响应客户端请求。可以通过 lastsave 命令获取最后一次成功执行快照的时间。
flushall
:也会产生dump.rdb文件,但里面是空的,无意义。
cp dump2.rdb dump.rdb
redis-cli config set save ""
save后给空值,表示禁用保存策略applyonly no
,改为 yes
config get dir
)applyonly no
,改为yes
/usr/local/bin/redis-check-aof--fix appendonly.aof
进行恢复bgrewriteaof
进行重写补充:
AOF和RDB同时开启,系统默认读取AOF的数据(数据不会存在丢失)
RDB与AOF用哪个好?官方推荐两个都启用。如果对数据不敏感,可以单独选用RDB。不建议单独用AOF,因为可能会出现Bug。如果只是做纯内存缓存,可以都不用。
redis-server redis6379.config
slaveof
: 成为某个实例的从服务器info replication
: 打印主从复制的相关信息,即查看当前redis的属性,是从机还是主机。salveof no one
将从机变为主机。redis-sentinel /myredis/sentinel.conf