redis数据淘汰策略lru(Least Recently Used,即最近最久未使用的意思)
Redis有哪几种数据淘汰策略?
1.noeviction:返回错误当内存限制达到,并且客户端尝试执行会让更多内存被使用的命令。
2.allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。
3.volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存 放。
4.allkeys-random: 回收随机的键使得新添加的数据有空间存放。
5.volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
6.volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间 存放。
一般来说:
如果分为热数据与冷数据, 推荐使用 allkeys-lru 策略。 也就是, 其中一部分key经常被读写. 如果不确定具体的业务特征, 那么 allkeys-lru 是一个很好的选择。
如果需要循环读写所有的key, 或者各个key的访问频率差不多, 可以使用 allkeys-random 策略, 即读写所有元素的概率差不多。
假如要让 Redis 根据 TTL 来筛选需要删除的key, 请使用 volatile-ttl 策略。
一个字符串类型的值能存储最大容量是多少? 512M
3、Redis支持哪几种数据类型? String、List、Set、Sorted Set、hashes
Redis支持的Java客户端都有哪些?官方推荐用哪个? Redisson、Jedis、lettuce等等,官方推荐使用Redisson
Redis集群之间是如何复制的? 异步复制
redis集群方案 https://www.cnblogs.com/kerwinC/p/6611634.html
1.官方3.0版本cluster方案
redis-cluster名词介绍
1、master 主节点、
2、slave 从节点
3、slot 槽,一共有16384数据分槽,分布在集群的所有主节点中。
cluster集群方案,采用的是虚拟槽分区,槽范围是0-16383,有16384个槽。集群中有3个主节点,每个节点大致负责5500个槽的读写,节点会维护自身负责的虚拟槽。
键所对应的哈希值通过如下公式计算:CRC16(key)%16384。目前常见的redisson、jedis等客户端工具都已实现,推荐使用redisson,jedis可以弃疗。
redisson客户端初始化的时候,会加载集群的元数据信息,创建连接池。包括IP 端口 哈希槽的映射关系。
在实际使用时,set key value命令会计算hash值,把key-value设置到对应的主节点上。
当动态添加或减少node节点时,需要将16384个槽做个再分配,槽中的键值也要迁移。
Redis集群,要保证16384个槽对应的node都正常工作,如果某个node发生故障,那它负责的slots也就失效,整个集群将不能工作。
为了增加集群的可访问性,官方推荐的方案是将node配置成主从结构,即一个master主节点,挂n个slave从节点。这时,如果主节点失效,Redis Cluster会根据选举算法从slave节点中选择一个上升为主节点,整个集群继续对外提供服务,Redis Cluster本身提供了故障转移容错的能力
2.哨兵模式Redis2.8以上的版本
1)Sentinel(哨兵)是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统
可以监视任意多个主服务器以及这些主服务器下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。
2)哨兵(Sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master主服务器是否下线的信息,
并使用投票协议(Agreement Protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master
redis持久化方案
rdb跟aof
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
RDB存在哪些优势呢?
1). 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。
2). 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。
3). 性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。
4). 相比于AOF机制,如果数据集很大,RDB的启动效率会更高。
RDB又存在哪些劣势呢?
1). 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
2). 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟
父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞,阻塞的时间跟所用内存大小成正比,要求redis实例最大不要超过10G。由子进程去创建最新的RDB文件。
什么时候会发生持久化操作呢?1、人工执行bgsave命令;2、达到配置文件中指定的约束条件
34.使用过Redis分布式锁么,它是怎么实现的?
SETNX job "programmer"
只在键 key 不存在的情况下, 将键 key 的值设置为 value 。
若键 key 已经存在, 则 SETNX 命令不做任何动作。
SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。
返回值
命令在设置成功时返回 1 , 设置失败时返回 0 。
先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。 如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?
set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令来用的!
Boolean ifAbsent = stringRedisTemplate.opsForValue().setIfAbsent(diskey, uuid, 5, TimeUnit.SECONDS);
stringRedisTemplate.delete(diskey);
什么是缓存穿透?如何避免?什么是缓存雪崩?何如避免?
缓存穿透 一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如 DB)。
一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫 做缓存穿透。 如何避免?
1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理 缓存。
2:对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过 该bitmap过滤。
缓存雪崩 当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压 力。导致系统崩溃。 如何避免?
1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线 程查询数据和写缓存,其他线程等待。
2:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为 短期,A2设置为长期
3:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀
Redis和Redisson有什么关系? Redisson是一个高级的分布式协调Redis客服端,能帮助用户在分布式环境中轻松实现一些Java的对 象
(Bloom filter, BitSet, Set, SetMultimap, ScoredSortedSet, SortedSet, Map, ConcurrentMap, List, ListMultimap, Queue, BlockingQueue, Deque,
BlockingDeque, Semaphore, Lock, ReadWriteLock, AtomicLong, CountDownLatch, Publish / Subscribe, HyperLogLog)。
15、Jedis与Redisson对比有什么优缺点? Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持;
Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能较为简单,不支持字符串操作, 不支持排序、事务、管道、分区等Redis特性。
Redisson的宗旨是促进使用者对Redis的关注分离,从 而让使用者能够将精力更集中地放在处理业务逻辑上。
假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以某个固定的已知的前缀开头的,如 果将它们全部找出来?
使用 keys 指令可以扫出指定模式的 key 列表。
对方接着追问:如果这个 redis 正在给线上的业务提供服务,那使用 keys 指令会有什么问 题?
这个时候你要回答 redis 关键的一个特性:redis 的单线程的。keys 指令会导致线程阻塞一 段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用 scan 指 令,
scan 指令可以无阻塞的提取出指定模式的 key 列表,但是会有一定的重复概率,在客 户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys 指令长。
https://blog.csdn.net/bird73/article/details/79792548
redis单线程
为什么说redis能够快速执行
(1) 绝大部分请求是纯粹的内存操作(非常快速)
(2) 采用单线程,避免了不必要的上下文切换和竞争条件
(3) 非阻塞IO - IO多路复用
redis的内部实现
内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,
绝不在io上浪费一点时间 这3个条件不是相互独立的,特别是第一条,如果请求都是耗时的,采用单线程吞吐量及性能可想而知了。应该说redis为特殊的场景选择了合适的技术方案。
Redis事件
Redis服务器是一个事件驱动程序,需要处理两类事件:文件事件与时间事件
Reactor反应器
中,这些被拆分的小线程或者子过程对应的是。,每一种handler会出处理一种event。这里会有一个全局的管理者selector,我们需要把channel注册感兴趣的事件,
那么这个selector就会不断在channel上检测是否有该类型的事件发生,
如果没有,那么主线程就会被阻塞,否则就会调用相应的事件处理函数即handler来处理
redis的key和string类型value限制均为512MB。
redis集群(redis cluster)
redis3以后,节点之间提供了完整的sharding(分片)、replication(主备感知能力)、failover(故障转移)的特性
配置一致性:每个节点(Node)内部都保存了集群的配置信息,存储在clusterState中,通过引入自增的epoch变量来使得集群配置在各个节点间保持一致
sharding数据分片
将所有数据划分为16384个分片(slot),每个节点会对应一部分slot,每个key都会根据分布算法映射到16384个slot中的一个,分布算法为slotId=crc16(key)%16384
当一个client访问的key不在对应节点的slots中,redis会返回给client一个moved命令,告知其正确的路由信息从而重新发起请求。client会根据每次请求来缓存本地的路由缓存信息,以便下次请求直接能够路由到正确的节点
分片迁移:分片迁移的触发和过程控制由外部系统完成,redis只提供迁移过程中需要的原语支持。主要包含两种:一种是节点迁移状态设置,即迁移钱标记源、目标节点;另一种是key迁移的原子化命令
failover故障转移
故障发现:节点间两两通过TCP保持连接,周期性进行PING、PONG交互,若对方的PONG相应超时未收到,则将其置为PFAIL状态,并传播给其他节点
故障确认:当集群中有一半以上的节点对某一个PFAIL状态进行了确认,则将起改为FAIL状态,确认其故障
slave选举:当有一个master挂掉了,则其slave重新竞选出一个新的master。主要根据各个slave最后一次同步master信息的时间,越新表示slave的数据越新,竞选的优先级越高,就更有可能选中。竞选成功之后将消息传播给其他节点。
集群不可用的情况:
集群中任意master挂掉,且当前master没有slave。
集群中超过半数以上master挂掉。
普通哈希算法和一致性哈希算法对比
普通哈希:也称硬哈希,采用简单取模的方式,将机器进行散列,这在cache环境不变的情况下能取得让人满意的结果,但是当cache环境动态变化时,这种静态取模的方式显然就不满足单调性的要求(当增加或减少一台机子时,几乎所有的存储内容都要被重新散列到别的缓冲区中)。
一致性hash(方便处理节点添加跟删除)
一致性哈希:将机器节点和key值都按照一样的hash算法映射到一个0~2^32的圆环上。当有一个写入缓存的请求到来时,计算Key值k对应的哈希值Hash(k),
如果该值正好对应之前某个机器节点的Hash值,则直接写入该机器节点,如果没有对应的机器节点,则顺时针查找下一个节点,进行写入,如果超过2^32还没找到对应节点,
则从0开始查找(因为是环状结构)。为了更可能的满足平衡性,可以引入虚拟节点,即一个实体节点映射到多个虚拟节点。