赞
踩
key-value存储形式的非关系型数据库。
三大特点:
优点:
Redis支持五种数据类型:
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
批量操作在发送 EXEC 命令前被放入队列缓存。
收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
Redis以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令。
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
MySQL:
Redis:
MySQL会默认开启一个事务,且缺省设置是自动提交,即,每成功执行一个SQL,一个事务就会马上 COMMIT。所以不能Rollback。
Redis默认不会开启事务,即command会立即执行,而不会排队。并不支持Rollback。
Redis可以设置过期时间,至于过期键什么时候删除有三种策略
指缓存中的数据大批量的过期甚至是缓存服务器宕机,而查询数据量过大,引起数据库压力过大或导致宕机。
解决方法:
业务系统要查询的数据根本就不存在!当业务系统发起查询时,首先会前往缓存中查询,由于缓存中不存在,然后再前往数据库中查询。由于该数据压根就不存在,因此数据库也返回空。这就是缓存穿透。
产生原因:恶意攻击;代码逻辑错误。
解决方法:
空数据的key各不相同、key重复请求概率低的场景而言,应该选择第二种方案。而对于空数据的key数量有限、key重复请求概率较高的场景而言,应该选择第一种方案。
热点数据,在缓存中失效了,数据库中有,大量线程/进程访问数据库,导致数据库压力过大或者崩溃。
解决方法:
使用互斥锁重建缓存;
当第一个数据库查询请求发起后,就将缓存中该数据上锁;此时到达缓存的其他查询请求将无法查询该字段,从而被阻塞等待;当第一个请求完成数据库查询,并将数据更新值缓存后,释放锁;此时其他被阻塞的查询请求将可以直接从缓存中查到该数据。
当某一个热点数据失效后,只有第一个数据库查询请求发往数据库,其余所有的查询请求均被阻塞,从而保护了数据库。但是,由于采用了互斥锁,其他请求将会阻塞等待,此时系统的吞吐量将会下降。这需要结合实际的业务考虑是否允许这么做。
设置热点数据永不过期(从功能上看一发生逻辑过期,就使用单独的线程重建缓存);
但唯一不足的就是重构缓存期间,会出现数据不一致的情况,这取决于应用方是否容忍这种不一致。
在 Redis 中,实现 高可用 的技术主要包括 持久化、复制、哨兵 和 集群,下面简单说明它们的作用,以及解决了什么样的问题:
RDB(Redis DataBase)持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化)
优点:
劣势:
AOF持久化(Append Only File) (原理是将Reids的操作日志以追加的方式写入文件)可采用每秒同步、每修改同步策略。
优点:
缺点:
二者选择的标准,如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化;如果系统是愿意牺牲一些性能,换取更高的缓存一致性,可以选用AOF。
主从复制
为一个主服务器设置多个从服务器,从服务器从主服务器中复制内容。
主服务器master可以进行读写操作,当主服务器的数据发生变化,master会发出命令流来保持对salve的更新,而从服务器slave通常是只读的(可以通过slave-read-only指定),在主从复制模式下,即便master宕机了,slave是不能变为主服务器进行写操作的。
主从复制的好处:
Redis的主从复制过程大体上分3个阶段:建立连接、数据同步、命令传播
https://juejin.cn/post/6844903663362637832
它可以实现对 Redis的监控、通知、自动故障转移。主要作用:
1.通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
2.当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。
然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。
Sentinel的工作方式:
在3.0版本及以后才支持集群
数据库和缓存更新,就容易出现缓存和数据库间的数据一致性问题。不管是先写数据库,再删除缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。
1.如果删除了缓存Redis,还没有来得及写库MySQL,另一个线程就来读取,发现缓存为空,则去数据库中读取数据写入缓存,此时缓存中为脏数据。
2.如果先写了库,在删除缓存前,写库的线程宕机了,没有删除掉缓存,则也会出现数据不一致情况。
解决办法:
会
情况1:确认下是否采用了复杂度高的慢查询命令
解决方法:用其他高效命令代替。
情况2:过期 key 操作(如果超过 25% 的 key 过期了,Redis 的线程就会一直执行删除,这样一来,就没办法正常服务其他的键值操作了,就会进一步引起其他键值操作的延迟增加,Redis 就会变慢。)
解决方法:将过期时间分散开。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。