什么是redis?它是用来做什么的?
Redis是一个c语言编写的nosql的数据库,支持网络,可基于内存也可持久化的,key-value类型的数据库。 与一般数据库不同的是,redis是存储在内存中的,他的读写速度非常快,常常被广泛应用到缓存之中。
redis除了用作缓存,还可以干什么?
redis6.x版本之前,属于彻彻底底的单线程,redis中监听客户端连接、读写数据操作,都是由一个单线程来完成的,效率低。
redis6.x之后,引入了多线程。将客户端网络请求,由多线程来负责完成,数据读写操作仍然是单线程。(单线程操作不会出现并发安全问题,保证了操作的原子性)
redis的瓶颈不是cpu,而是内存大小、网络速度,本身速度就很快。
Redis底层是一个hash表结构,时间复杂度是O(1)
hash可以在O(1)的时间内计算出hash值并且找到对应的entry位置,entry里面是一个一个key指针和value指针,其实还有其他信息。这也是redis之所以性能高的原因之一。
因为redis数据平常存储在内存中,一旦机器故障可能数据就会丢失。Redis还提供了数据持久化的机制,把内存中的数据,根据一定规则写入到硬盘中的文件,分别是RDB和AOF。
点赞-->存储在redis内存中--->定期的将数据写入到文件中。定时任务:每天晚上0点,把redis的数据写入到mysql
在我们安装了redis之后,所有的配置都是在redis.conf文件中,里面保存了RDB和AOF两种持久化机制的各种配置。当符合一定条件时,Redis会自动将内存中的数据进行快照并持久化到硬盘。
在redis.conf文件中可以进配置,是否开启rdb持久化。在满足一定的条件时,定期的将redis中的数据(数据快照)保存到一个dump.rdb文件中,在redis 重新启动时,会将数据还原回来,将键值存储到rdb文件中。
数据快照:内存中有许多key-value、key1-value1---->存储在dump.rdb文件
rdb方式是redis默认的持久化方式,不需要配置开启,默认是支持的。
redis.conf文件中有触发rdb保存快照的条件。
save:这里是用来配置触发Redis的RDB持久化条件,也就是什么时候将内存中的数据保存到硬盘。比如"save m n"。表示m秒内数据集存在n次。修改时,自动触发bgsave。
如下配置:
如果不需要持久化,那么你可以注释掉所有的save行来停用保存功能。
退出redis,也会产生 rdb 文件, 命令: shutdown save。在Redis客户端模式下,关闭Redis服务时会保存快照,重新启动Redis服务时,会将dump.rdb文件中的数据还原回来。
以日志的方式来记录所有写操作的命令(读操作不记录)。redis重启的话,会还原数据,会将日志文件中写命令从前到后执行一次。
set name jim
set name tom
如果是RDB方式,最终记录name的值为tom;而AOP方式记录所有的
appendonly no #默认是不开启aof模式的,改为yes开启。
appendfilename appendonly.aof #默认的文件名是 appendonly.aof,可以通过appendfilename参数修改 AOF 同步机制。
appendfsync always #每次修改都会同步,消耗性能。
appendfsync everysec #每秒会同步一次,可能会丢失这1s的数据(默认)
appendfsync no #不同步
修改完之后,重启redis才生效。
redis事务:是将多条命令打包为一个整体执行(在同一个事务中),这样执行的过程中其他客户端命令就不能执行了。但是不保证命令的原子性(中间有一条命令报错,不影响其他命令的执行)。
redis 的事务操作:
实例:
但是事务不保证同一事物中多条命令执行的原子性,即使命令有错误也会添加到队列中,执行报错也不影响其他命令执行。
redisTemplate.multi();//开启事务
ValueOperations valueOperations = redisTemplate.opsForValue();
valueOperations.set(a,aa);
valueOperations.set(b,bb);
redisTemplate.exec();//执行事务
主从复制,是指将一台Redis服务器的数据复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主机到从机。
redis集群--->多台服务构成
Redis为了数据能够备份,实现读写分离(写命令找主机,读命令找从机)。有一台服务作为主机、多台服务作为从机,一台Redis服务器的数据复制到其他的Redis服务器。主机负责写数据,将数据备份到多台从机,从机负责读操作。
即使期间,有一台服务器出现问题,其他redis服务也可以正常工作。当有问题的服务故障排除后,可以继续在集群中工作。即使是主机故障,也可以从多台从机中,选举出一台服务作为主机(哨兵机制)
主从复制时只需要配置从库即可,其默认为主库模式。打开redis客户端登录,使用命令info replication查看。
主从复制可以搭建真集群,也可以搭建伪集群。
真集群:有多台主机、每台主机安装一个 redis。
redis伪集群:可以在一台机器上,配置多个redis端口,启动多个redis实例。配置方式两者相同。
1.复制多份配置文件,一主二从
主机配置
从机配置
从机进入客户端模式 ./redis-cli -p 从机端口
主机
测试主写从读
哨兵是一个独立的进程,独立运行。
哨兵定期的向redis集群中发送请求,等待Redis服务器响应。如果收不到回复,就说明redis服务有问题,会通过一套选举机制,在多台从机中选取一台作为主机;当主机故障恢复后,临时主机又变为从机角色。
单哨兵
哨兵集群
Redis中的key,是可以设置有效时间的。不是时间到期后就会自动删除的;当时间到了后,redis中有一套机制来删除过期的key。
Redis提供了两种删除策略:
key到期后不立即删除,只是使用一个字典记录此key已经过期,在下次使用此key时,才会删除。
浪费内存空间,但节省CPU
每隔指定的时间后,字典中记录过期的key,定期的删除过期的key。
redis使用的过期键值删除策略是:惰性删除加上定期删除,两者配合使用
采用延时双删机制:两次删除Redis中的数据,一次是在更新mysql前删除Redis数据,此时mysql还没有真正更新,有可能其他线程去mysql中查询到没有更新前的数据,所以需要在更新完mysql中数据后,定时再次删除Redis中的数据,这样其他请求就可以读到与mysql中一致的数据。
Redis数据类型(String、哈希、list、set、zset)
跳表是一种特殊的有序链表,可以维护一些区间。查询一个元素时,不需要从头一个一个查询,先确定元素在调表中的区间范围,可以提高查询效率。
先分成大区间,再分成小区间
redis可以用来缓存数据,访问量大的时候可以缓解mysql的压力。如果Redis使用不当,也会造成新的问题。
前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存并返回结果,数据库没取到直接返回空结果。
数据在mysql中本身就不存在,这样redis中也没有,每次查询时,都会访问mysql,大量访问会压垮mysql。
解决办法:
mysql中有数据,在Redis中的某个时刻key到期了。此时刚好有大量请求到达,这时没有做任何的控制,大量请求查询redis,但是redis中没有数据,请求到达mysql,导致mysql被压垮。
解决办法:
大量的key过期或者Redis服务器出现故障,导致大量的请求到达mysql(更严重的击穿)。
解决办法: