赞
踩
Redis
1、项目中redis如何使用(结合业务)
缓存手机号和验证码
缓存文章的点赞信息 用了hash结构,大K是文章的id 小k 是用户的id value 是个标识
分布式锁(场景)
....
2、redis的数据类型
字符串(string):普通字符串,常用
哈希(hash):适合存储对象
列表(list):按照插入顺序排序,可以有重复元素
集合(set):无序集合,没有重复元素
有序集合(sorted set / zset):集合中每个元素关联一个分数(score),根据分数升序排序,没有重复元素
3、redis的持久化方式 两者的区别 实际开发使用
一、形式不同
1、rdb:rdb在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
2、aof:aof以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
二、启动效率不同
1、rdb:通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。
2、aof:由子进程完成这些持久化的工作,可以极大地避免服务进程执行IO操作。如果数据集很大,aof的启动效率会更高。
三、安全性不同
1、rdb:系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
2、aof:由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。
4、redis是单线程,为什么那么快
1、Redis是纯内存数据库,一般都是简单的存取操作,线程占用的时间很多,时间的花费主要集中在IO上,所以读取速度快。 2、Redis使用的是非阻塞IO、IO多路复用,使用了单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件,减少了线程切换时上下文的切换和竞争。 3、Redis采用了单线程的模型,保证了每个操作的原子性,也减少了线程的上下文切换和竞争。 4、Redis避免了多线程的锁的消耗。 5、Redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。
5、怎么理解IO多路复用
单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力。
IO多路复用解决的本质问题是在用更少的资源完成更多的事。
6、主从复制的原理
1.slave节点请求增量同步。
2.master节点判断repl ID,发现不一致,拒接增量同步。
3.master将完整内存数据生成RDB,发送RDB到slave。
4.slave清空本地数据,加载master的RDB。
5.master将RDB期间的命令记录在repl-baklog,并持续将log中命令发送给slave。
6.slave执行接收的命令,保持与master之间的同步。
7、什么情况下需要全量更新
①第一次请求同步时。(Replicaton ID不同)
②当slave最后一次更新后的offset末尾索引的大于master的offset的开始索引,就会请求全局更新。
9、增量更新的原理
发生在slave重启后。
①slave携带replID和offset请求master同步
②master判断请求的replID和master的replID是否一致
③如果master判断一致说明不是第一次请求同步了,回复slave一个continue
④master去repl_baklog中获取数据offset后的数据
⑤master发送offset后的命令
⑥slave接收到offset后执行命令
10、哨兵机制的作用
哨兵机制(Sentinel):实现redis主从集群的自动故障恢复。
监控:Sentinel会不断检查master和slave是否按预期工作。
自动故障恢复:如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后,也是以新的master为主。
通知:Sentinel充当Redis客户端的服务发现来源,当集权发生故障转移时,会将最新的信息推送给Redis的客户端。
11、哨兵自动故障转移的算法(如何选择)
首先会判断slave节点与master节点断开时间长短,如果超过指定值(down-after-milliseconds * 10)则会排除该slave节点
然后判断slave节点的slave-priority值,越小优先级越高,如果是0则永不参与选举
如果slave-prority一样,则判断slave节点的offset值,越大说明数据越新,优先级越高
最后是判断slave节点的运行id大小,越小优先级越高。
12、工作redis几台服务器
三主三从
13、说一说散列插槽
Redis会把每一个master节点映射到0~16383共16384个插槽(hash slot)上,查看集群信息时就能看到。
数据key不是与节点绑定,而是与插槽绑定。redis会根据key的有效部分计算插槽值,分两种情况:
key中包含"{}",且“{}”中至少包含1个字符,“{}”中的部分是有效部分
key中不包含“{}”,整个key都是有效部分
14、redis的删除策略
删除策略:是当数据到期,redis对过期数据的处理策略。
1.定时删除:当某一个key的过期时间到达后,redis就把对应的value和key删除。
优点是省内存,能快速的把过期数据删除腾出空间。
缺点是CPU资源占用过高,尤其是当CPU还在尽力处理其他事情的时候,这时候如果有key过期,就可能两边(redis和其他服务)体验都不好,并且当定时key越多,分配的资源就越多,就越影响性能。
2.惰性删除:数据过期不是立刻删除,而是要获取数据的时候判断是否过期,如果过期再删除。
优点是节约CPU资源。
缺点是有较大的OOM风险。
3.定期删除:走定时任务,随机清理过期的数据。这个定时任务是通过时间进行资源分配的,比如1秒钟抽出0.1秒来执行删除任务。
这种策略是1和2的折中策略,优点是比1、2两个缺点好点,缺点是比1、2两个优点差点。
15、redis的淘汰策略(说说怎么保证redis都是热点数据)
淘汰策略:是当数据放不下的时候,淘汰其他数据的策略。
相关配置:
1:maxmemory ?mb 释:分配给redis的内存大小 ,触发淘汰策略的阈值。
2:maxmemory-samples count 释:每次选取待删除数据的个数,采用随机获取数据的方式作为待检测删除数据。
3:maxmemory-policy noeviction 一共8个值。
1)noeviction: 不删除,直接返回报错信息。 2)allkeys-lru:移除最久未使用(使用频率最少)使用的key。 3)volatile-lru:在设置了过期时间的key中,移除最久未使用的key。 4)allkeys-random:随机移除某个key。 5)volatile-random:在设置了过期时间的key中,随机移除某个key。 6)volatile-ttl: 在设置了过期时间的key中,移除准备过期的key。 7)allkeys-lfu:移除最近最少使用的key。 8)volatile-lfu:在设置了过期时间的key中,移除最近最少使用的key。
16、缓存雪崩
场景:数据库服务器崩溃,一连串的场景会随之儿来
1.系统平稳运行过程中,忽然数据库连接量激增
2.应用服务器无法及时处理请求
3.大量408,500错误页面出现
4.客户反复刷新页面获取数据
5.数据库崩溃
6.应用服务器崩溃
7.重启应用服务器无效
8.Redis服务器崩溃
9.Redis集群崩溃
10.重启数据库后再次被瞬间流量放倒
问题排查:
1.在一个较短的时间内,缓存中较多的key集中过期
2.此周期内请求访问过期的数据,redis未命中,redis向数据库获取数据
3.数据库同时接收到大量的请求无法及时处理
4.Redis大量请求被积压,开始出现超时现象
5.数据库流量激增,数据库崩溃
6.重启后仍然面对缓存中无数据可用
7.Redis服务器资源被严重占用,Redis服务器崩溃
8.Redis集群呈现崩塌,集群瓦解
9.应用服务器无法及时得到数据响应请求,来自客户端的请求数量越来越多,应用服务器崩溃
10.应用服务器,redis,数据库全部重启,效果不理想
总而言之就两点:短时间范围内,大量key集中过期
解决方案 思路:
1.更多的页面静态化处理
2.构建多级缓存架构 Nginx缓存+redis缓存+ehcache缓存
3.检测Mysql严重耗时业务进行优化 对数据库的瓶颈排查:例如超时查询、耗时较高事务等
4.灾难预警机制 监控redis服务器性能指标 CPU占用、CPU使用率 内存容量 查询平均响应时间 线程数
5.限流、降级 短时间范围内牺牲一些客户体验,限制一部分请求访问,降低应用服务器压力,待业务低速运转后再逐 步放开访问 落地实践:
1.LRU与LFU切换
2.数据有效期策略调整 根据业务数据有效期进行分类错峰,A类90分钟,B类80分钟,C类70分钟 过期时间使用固定时间+随机值的形式,稀释集中到期的key的数量
3.超热数据使用永久key
4.定期维护(自动+人工) 对即将过期数据做访问量分析,确认是否延时,配合访问量统计,做热点数据的延时
5.加锁:慎用! 总的来说:缓存雪崩就是瞬间过期数据量太大,导致对数据库服务器造成压力。如能够有效避免过期时 间集中,可以有效解决雪崩现象的 出现(约40%),配合其他策略一起使用,并监控服务器的运行数 据,根据运行记录做快速调整。
总的来说:缓存雪崩就是瞬间过期数据量太大,导致对数据库服务器造成压力。如能够有效避免过期时 间集中,可以有效解决雪崩现象的 出现(约40%),配合其他策略一起使用,并监控服务器的运行数 据,根据运行记录做快速调整。
17、缓存穿透★★★★★
布隆过滤器
场景:数据库服务器又崩溃了,跟之前的一样吗? 1.系统平稳运行过程中 2.应用服务器流量随时间增量较大 3.Redis服务器命中率随时间逐步降低 4.Redis内存平稳,内存无压力 5.Redis服务器CPU占用激增 6.数据库服务器压力激增 7.数据库崩溃
问题排查: 1.Redis中大面积出现未命中 2.出现非正常URL访问 问题分析: 获取的数据在数据库中也不存在,数据库查询未得到对应数据 Redis获取到null数据未进行持久化,直接返回 下次此类数据到达重复上述过程 出现黑客攻击服务器
解决方案: 1.缓存null 对查询结果为null的数据进行缓存(长期使用,定期清理),设定短时限,例如30-60秒,最高5分钟 2.白名单策略 提前预热各种分类数据id对应的bitmaps,id作为bitmaps的offset,相当于设置了数据白名单。当加 载正常数据时放行,加载异常数据时直接拦截(效率偏低) 使用布隆过滤器(有关布隆过滤器的命中问题对当前状况可以忽略) 2.实施监控 实时监控redis命中率(业务正常范围时,通常会有一个波动值)与null数据的占比 非活动时段波动:通常检测3-5倍,超过5倍纳入重点排查对象 活动时段波动:通常检测10-50倍,超过50倍纳入重点排查对象 根据倍数不同,启动不同的排查流程。然后使用黑名单进行防控(运营) 4.key加密 问题出现后,临时启动防灾业务key,对key进行业务层传输加密服务,设定校验程序,过来的key校 验 例如每天随机分配60个加密串,挑选2到3个,混淆到页面数据id中,发现访问key不满足规则,驳回 数据访问
总的来说:缓存击穿是指访问了不存在的数据,跳过了合法数据的redis数据缓存阶段,每次访问数据 库,导致对数据库服务器造成压力。通常此类数据的出现量是一个较低的值,当出现此类情况以毒攻 毒,并及时报警。应对策略应该在临时预案防范方面多做文章。 无论是黑名单还是白名单,都是对整体系统的压力,警报解除后尽快移除。
18、缓存击穿
场景:还是数据库服务器崩溃,但是跟之前的场景有点不太一样 1.系统平稳运行过程中 2.数据库连接量瞬间激增 3.Redis服务器无大量key过期 4.Redis内存平稳,无波动 5.Redis服务器CPU正常 6.数据库崩溃
问题排查: 1.Redis中某个key过期,该key访问量巨大 2.多个数据请求从服务器直接压到Redis后,均未命中 3.Redis在短时间内发起了大量对数据库中同一数据的访问 总而言之就两点:单个key高热数据,key过期
解决方案: 1.预先设定 以电商为例,每个商家根据店铺等级,指定若干款主打商品,在购物节期间,加大此类信息key的过 期时长 注意:购物节不仅仅指当天,以及后续若干天,访问峰值呈现逐渐降低的趋势 2.现场调整 监控访问量,对自然流量激增的数据延长过期时间或设置为永久性key 3.后台刷新数据 启动定时任务,高峰期来临之前,刷新数据有效期,确保不丢失 4.二级缓存 设置不同的失效时间,保障不会被同时淘汰就行 5.加锁 分布式锁,防止被击穿,但是要注意也是性能瓶颈,慎重!
总的来说:缓存击穿就是单个高热数据过期的瞬间,数据访问量较大,未命中redis后,发起了大量对同 一数据的数据库访问,导致对数 据库服务器造成压力。应对策略应该在业务数据分析与预防方面进行, 配合运行监控测试与即时调整策略,毕竟单个key的过 期监控难度较高,配合雪崩处理策略即可
19、缓存预热
场景:“宕机” 服务器启动后迅速宕机
问题排查:1.请求数量较高,大量的请求过来之后都需要去从缓存中获取数据,但是缓存中又没有,此时从数据库 中查找数据然后将数据再存入缓存,造成了短期内对redis的高强度操作从而导致问题 2.主从之间数据吞吐量较大,数据同步操作频度较高
解决方案: 前置准备工作: 1.日常例行统计数据访问记录,统计访问频度较高的热点数据 2.利用LRU数据删除策略,构建数据留存队列例如:storm与kafka配合 准备工作: 1.将统计结果中的数据分类,根据级别,redis优先加载级别较高的热点数据 2.利用分布式多服务器同时进行数据读取,提速数据加载过程 3.热点数据主从同时预热 实施: 4.使用脚本程序固定触发数据预热过程 5.如果条件允许,使用了CDN(内容分发网络),效果会更好
总的来说:缓存预热就是系统启动前,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的 时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
20、分布式锁
分布式锁,就是控制分布式系统中不同进程共同访问同一共享资源的一种锁的实现。
举个生活中的例子,就拿高铁举例,每辆高铁都有自己的运行路线,但这些路线可能会与其他高铁的路线重叠,如果只让高铁内部的司机操控路线,那就可能出现撞车事故,因为司机不知道其他高铁的运行路线是什么。所以,中控室就发挥作用了,中控室会监控每辆高铁,高铁在什么时间走什么样的路线全部由中控室指挥。
分布式锁就是基于这种思想实现的,它需要在我们分布式应用的外面使用一个第三方组件(可以是数据库、Redis、Zookeeper等)进行全局锁的监控,由这个组件决定什么时候加锁,什么时候释放锁。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。