1.什么是Redis,有何优点作用,为什么效率高?
redis是nosql中的一种,把数据存储在内存中的数据库,优点:高性能,读写速度快,支持多种字符,支持事务,和丰富的特性
纯内存数据库,非阻塞io,单线程模型,减少上下文切换。使用hash结构。
2.Redis相比memcached有哪些优势?
redis支持多种数据结构,memcached只能用普通的字符窜
redis读写速度比他快,
redis支持事务,支持持久化
3.Redis是单线程还是多线程?为什么选择单线程?为什么执行速度快? Redis 6出现了多线程来处理网络处理方面
他用单线程处理数据快,用多线程考虑上下文的切换和线程锁会影响性能。
执行速度快是因为他是纯内存操作,异步非阻塞I/O
Redis4.0就开始有多线程的概念了,一般都是通过多线程的方式在后台删除对象,以及redis模块实现阻塞命令。
在redis6把网络处理部分做成多线程处理方式,get/set操作性能会提供很多
4.Redis支持哪几种数据类型?
List按照插入顺序排序。,粉丝列表或者消息队列功能。
String 以kv行式进行存储,一般用于常规的kv缓存应用。或复制的计数功能的缓存
set 哈希表实现,元素不重复,做全局去重的功能
hash是一个k v是键值对集合,一般适用于存储对象,存储用户信息等,单点登录
zset 和set一样也是string类型元素的集合, 数据插入集合时,已经进行天然排序 应用于排行榜
5.为什么Redis需要吧所有数据放到内存中?
因为redis读取速度快,如果放在磁盘会影响读取性能
6.Redis集群方案应该怎么做?都有哪些方案?
redis cluster 自带的集群,集群中任意节点平等,每个节点保持连接活跃,任意节点可用获取其他节点的数据。
redis集群主要搭建了6台,3主(为了保证redis的投票机制)3从(高可用),每个主服务器都有一个从服务器,作为备份机。
Redis集群的时候没有使用一致性的hash,而是引入了哈希槽的概念,一般Redis集群的时候有16384个哈希槽,每个key值通过CRC16.效验后来决定发置那个槽,每个节点负责一部分hash槽。16384也就是最大节点数。
Redis Cluster主从模式
redis cluster 为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会有这个从节点选取一个来充当主节点,从而保证集群不会挂掉。
redis集群,搭建几台,怎么搭建
3台(为了保证redis的投票机制)每个主服务器都有一个从服务器。,Redis集群方式有很多种,我们采用的是redis-cluster集群,这种发送采用的是无中心结构,每个节点保持数据的整个集群的状态,每个节点都和其他所有节点连接。在redis集群中,我们会用哨兵模式去监控redis的状态。防止发生master宕机。一般这种几率很少出现。
8.如何保证Redis的数据都是热点数据?
可以设置redis的allkeys-lru内存回收策略,每次访问或插入数据的时候,清理最近使用最少的数据。
9.Redis有哪些适用的场景?
会话缓存 订阅发布,排行排,消息队列,全页缓存
10.Redis哈希槽的概念
redis集群的时候没有使用一致性的hash,而是引入哈希槽的概念,一般redis集群的时候有16384个哈希槽,每key值通过crc16校验后来决定放在哪个节点
11. redis的持久化方式
rdb:指定时间间隔内,将内存中的数据快照的方式保存到文件中。优点:对文件数据恢复数据效快,缺点:可能会丢失数据,不能保证数据的高可用。
aof:根据配置把每次写操作的命令写入到aof文件中,当redis重启,通过文件来恢复数据。优点:数据安全性高。缺点:恢复速度慢,效率低,因为文件比较大。
使用redis-port工具来将rdb文件恢复数据。 Aof看有没有flushall命令有就删除,然后重启redis。就会通过aof文件来恢复数据。
12.redis挂掉了怎么办?怎么实现高可用?
保存数据的话,做持久化,然后搭建redis集群,主机宕机,可以使用备用。
13.你怎么定期清理redis中缓存?设置过期时间需要注意什么?
主键失效和淘汰策略.
在Redis当中,有生存期的key被称为volatile。在创建缓存时,要为给定的key设置生存期,当key过期的时候(生存期为0),它可能会被删除。
在使用DEL、SET、GETSET等会覆盖key对应value的命令操作一个设置了过期时间的key的时候,会导致对应的key的过期时间被清除。Incr/lpush/hset等命令则不会清除过期时间
14.使用redis分布式锁吗?怎么实现?
基于redisson里面的Rlock锁来实现。或者使用事务。
15.redis的同步机制了解么?
主从同步,第一次同步时,主节点做一次bgsave,记录到内存中,然后将rdb文件同步到复制节点,然后将rdb加载到内存,主节点将修改的操作同步到复制节点中,就完成了同步过程。 修改的时候会做记录,然后加载到内存中,然后同步到其他节点上。
16.redis集群有哪些?redis集群是怎么实现的?
Redis Sentinal(哨兵模式)着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。
cluster模式为了解决单机Redis容量有限的问题,将Redis的数据根据一定的规则分配到多台机器。
17.redis的缓存竞争并发问题怎么解决?
做秒杀的时候产生的问题。使用分布式锁,抢到锁就做set操作,不推荐使用redis的事务机制。因为我们的生产环境,基本都是redis集群环境,做了数据分片操作。你一个事务中有涉及到多个key操作的时候,这多个key不一定都存储在同一个redis-server上
18.Redis过期策略和内存淘汰机制是什么?
过期策略分三种:定时删除:设置key的过期时间同时创建定时器,让定时器在key的过期时间到了时,立即执行删除操作
惰性过期:放任过期不管,用户获取key时检测是否过期,过期就删除,没有就返回。
定期过期:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。
因为redis是采用定期删除+惰性删除,就是定期删除会导致某一些key过期了没有被删除,因为他是随机检查的,惰性删除是用户获取key的时候检查删除key,如果用户设置key的过期时间,1没有被定时删除检查到,2用户没有去获取这个key,那么就会大量过期key堆积在内存里,导致redis内存块耗尽了,这个时候就需要redis的内存淘汰策略了。
内存淘汰策略分6种: 通过 config set maxmemory-policy volatile-lru 设置
noeviction: 默认的策略,即当内存使用达到阈值的时候,所有引起申请内存的命令都会报错;
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰 。
allkeys-random:随机移除某个key
volatile-random:从已设置过期时间的数据中任意选择数据淘汰。
volatile-lru:从已设置过期时间的数据中挑选最近最少使用的数据淘汰。
volatile-ttl:从已设置过期时间的数据中挑选将要过期的数据淘汰;适合场景:这种策略使我们可以向Redis
19.redis事务
1.事务是一个单独的隔离操作,事务在执行的过程中,不会被其他的命令打断,要么全部操作成功,要么全都失败。开启事务:multi 用queued添加数据不会添加成功,而是记录下来,事务提交exec把前面添加的数据提交,如果中间没有其他人做操作就可以成功,不然就添加失败,放弃事务:discard
20.redis的wathc机制
就是一个乐观锁,就是监视一个或多个key,如果在事务执行之前,key值被修改过,则事务被打断。
21.redis如何设置密码?
设置密码:config set requirepass **** 授权密码:auth *****
22.如何保证mysql和redis数据的一致性?
1.一般正常的话是先删除缓存再保存数据到db中。采用延迟双删除策略,先删除缓存,再写数据库,休眠500毫秒,再删除缓存。设置缓存时间等。(查询,先读缓存有就取出数据,没有就读数据库 ,更新,删除 先删除缓存在做操作。)
缺点:如果没有删除缓存的情况下可能存储着数据不一致的问题。
2.mq异步更新缓存(基于定义binlog的同步机制)MySQL中产生了新的写入、更新、删除等操作在binlog里面进行记录,订阅读取binlog后分析,利用消息队列,就可以把binlog相关的消息推送至Redis,Redis再根据binlog中的记录,对Redis进行更新。消息队列可以采用阿里的canal(肯那儿)+kafka或者rabbitmq来实现(模仿的mysql主从复制)
23. redis的安全机制
1.修改配置文件,使用禁止一些命令,和禁止远程修改db文件地址。
2.降低权限运行redis服务。可以配置禁止登陆。
3.要么为redis配置密码验证,或者防止外网访问redis
24.redis高并发粒度问题
粗粒度锁:
这时候,普遍的做法是加锁,但是如果对整个访问redis的动作加锁,那么等于多个线程串行访问了!
细粒度加锁:
我们这里的做法是对key进行细粒度加锁,每个key拥有一把锁,只对key进行并发控制,key与key之间允许并发。
数据颗粒度一般指影响的数据范围大小
25.单线程的redis如何利用多核cpu机器?
在同一台机来器上启动Redis的多个实例,将其当作不同的服务器
26.缓存穿透,缓存击穿,缓存雪崩是什么?解决方案?
1.缓存穿透:利用不存在的key来查询数据库,因为缓存中没有该key就去查询数据库,去数据库查询key的时候不管查询到了没有都进行缓存,如果是null就返回null值,。定期清楚为null的数据。
2.缓存击穿:经常热点访问的一个key,有10W并发量,同你这个key没有做缓存的时候去查询db(缓存时间到期的期间),使用互斥锁来实现,第一个人拿到锁了,后面的人就只能等待(或者休眠2S),然后重新返回这个方法查询。
3.缓存雪崩:缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
27.redis读写分离和数据分片
要在集群的情况下一步主服务器尽量的少读少写,其他的服务可以配置多少的读写次数。(数据分片)Key的hash槽为多少去访问那个服务器。
数据分片:指的是在Redis集群中为每一台服务器逻辑分配一定数量的槽位,然后按照一定的算法,计算数据存放的槽位,从而达到将数据均匀分散在几台服务器中,达到负载均衡的效果。
28.Redis在什么情况下会导致整个集群不可用?
如果有3个节点的集群,如果没有复制模型的情况下,某一个节点失败了,就会导致整个集群不可用
29.Redis主从复制?高可用哨兵?
有台服务器在主服务器配置中配置主从关系,主服务器写入数据会同步到从服务器中。
监控多个redis服务运行情况,服务器出现问题,则将从服务器提升成主服务器。
30.集群中如何复制?测试redis的连通性? 管道有何用?
1.异步复制 2.ping 3. 利用管道,客户端可以一次性发送多个请求而不用等待服务器的响应,待所有命令都发送完后再一次性读取服务的响应,降低请求时间从而提升性能
31.redis如何做内存优化?
1.缩减键值的长度(LZO压缩字符串)(能用简单的就用简单的)(进redis之前还可以压缩内容)
2.共享对象池(尽量使用整数对象)redis启动的时候默认会生成一个0-9999的整数对象共享池。
3.配置内存回收策略,设置最近少使用的进行清理。
4.编码优化(在配置中:config set hash-max-ziplist-entries 65。这样value大于65字节才转换成hash table。)
5.设置内存上限 6.控制key的数量,尽量使用hash。因为string的内存占用比较大key比较分散,hash支持hashtable和ziplist比string节约5倍的空间,但是hash不好设置单独某个值的过期时间
32.redis-cluster集群工作原理,及数据如何存放以及算法?
1.自动将数据分片,每个master上放一部分数据 2.提供内置的高可用支持,部分master不可用时,还可继续工作
Redis中
集群中分片的算法有、
Hash算法:key,首先计算 hash 值,然后对节点数取模。然后存在不同的 master 节点上。缺点:当某个master节点宕机,大量的数据就需要重新计算写入缓存和如果存在大量的请求,几乎大部分请求都获取不到缓存,那么直接请求数据库,就可能导致数据库挂了,因为这个节点上的master挂了,数据需要重新计算和写入
。
一致性Hash算法:将hash空间组织成一个虚拟的圆环,按顺时针方向来存储数,将各个master节点进行hash来确定每个节点在hash环上的位置。来了一个key,计算hash值来确定数据落在hash环上的位置,然后顺时针旋转找到离自己最近的节点进行存储。
问题1:如果节点太少时,可能造成节点发布不均匀,造成缓存热点的问题。一致性 hash 算法引入了虚拟节点机制,即对每一个节点计算多个 hash,每个计算结果位置都放置一个虚拟节点。这样就实现了数据的均匀分布,负载均衡。
在一致性哈希算法中,如果一个节点挂了,受影响的数据仅仅是此节点到环空间前一个节点(沿着逆时针方向行走遇到的第一个节点)之间的数据,其它不受影响。增加一个节点也同理。
Redis-cluster的hash slot(哈希槽)算法: Redis-cluster集群的时候有16384个哈希槽,每个key值通过CRC16.效验后来决定发置那个槽,每个master节点负责一部分hash槽。哈希槽让节点的增加和移除很简单,增加master节点,就将其他master的hash slot移动部分过去,减少一个master,就将它的hash slot移动到其他master上去
Redis开发规范
1.可读性和可管理性
以业务名 (或数据库名) 为前缀(防止 key 冲突),用冒号分隔,比如业务名: 表名: id
ugc:video:1
2.简洁性
保证语义的前提下,控制 key 的长度,当 key 较多时,内存占用也不容忽视,例如:
user:{uid}:friends:messages:{mid}简化为u:{uid}:fr:m:{mid}。
3.不要包含特殊字符
反例:包含空格、换行、单双引号以及其他转义字符
4.拒绝 bigkey
防止网卡流量、慢查询,string 类型控制在 10KB 以内,hash、list、set、zset 元素个数不要超过 5000。
5.选择适合的数据类型
例如:实体类型 (要合理控制和使用数据结构内存编码优化配置, 例如 ziplist,但也要注意节省内存和性能之间的平衡)
反例:
set user:1:name tom
set user:1:age 19
set user:1:favor football
正例:
hmset user:1 name tom age 19 favor football
6.控制 key 的生命周期
redis 不是垃圾桶,建议使用 expire 设置过期时间
Redis排查命令
ping 测试redis的连通性。
object idletime [key] 查看某个key的空闲时间。
object encoding [key]:返回指定key的内部存储使用的编码格式
object FREQ [key]:返回指定key访问频率的对数,当淘汰策略为LFU时,这一命令会被用到
Info Memory 查看redis内存使用情况
slowlog 查看查询慢的命令有哪些,默认命令耗时超过10毫秒就会记录到查询日志队列中。
slowlog get 2 查询2个
查看redis服务器资源监控RedisLive
检查服务端tcp连接:netstat -nat|grep -i "6379"|wc -l
检查服务端连接是否达到最大值:查看服务端支持的最大连接:CONFIG GET maxclients
查看当前服务端建立的 连接:connected_clients
如果是向磁盘保存数据失败为:Can’t save in background: fork: Cannot allocate memory
修改liunx内核参数 vm.overcommit_memory=1
overcommit_memory有三种取值:0, 1, 2
0::检查是否有足够的可用内存供进程使用;有则允许申请,否则,内存申请失败,并把错误返回给应用进程;
1:表示内核允许分配所有的物理内存,而不管当前的内存状态如何;
2:表示内核允许分配超过所有物理内存和交换空间总和的内存。