深入了解redis

Redis有哪些缓存淘汰策略?

相关问题1:  Redis有哪些驱逐算法?

相关问题2:  EhCache有哪些淘汰策略?

常见的有四种淘汰策略(EhCache使用的是这3种):

FIFO:First In First Out,先进先出。判断被存储的时间,离目前最远的数据优先被淘汰。

LRU:Least Recently Used,最近最少使用。判断最近被使用的时间,时间越远且没使用的数据优先被淘汰。

LFU:Least Frequently Used,最不经常使用。在一段时间内,数据被使用次数最少的,优先被淘汰。

体积优先原则:数据最小者多保存,数据最大者优先淘汰。

Redis 提供 6种数据淘汰策略:

voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

no-enviction(驱逐):禁止驱逐数据

 

物理服务内存只有8G,但数据有100G,如何缓存到Redis中?

Redis有缓存淘汰策略,内存不足时会淘汰数据,腾出空间,让新数据进来。但会导致缓存命中率低,缓存效果不好。在公司成本允许的情况下,利用分片集群来增加机器会提高命中率。

 

命中率是什么意思?

相关问题1:  什么叫缓存命中率?

命中率就是缓存里能查询到的记录数除以数据库里总记录数,命中率也越大性能越高,反之越差,造成命中率低的原因有:

1、内存不足,加快淘汰;

2、缓存服务器宕机;

 

什么叫缓存穿透?

在缓存中查询一个不存在的数据时,会导致每次请求都要到存储层去查询(穿透到数据库),缓存不起作用。在流量大时,数据库就会挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。

有很多种方法可以有效地解决缓存穿透问题:

1、最常见的则是采用布隆过滤器(布隆过滤器(Bloom Filter)实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。),将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。

2、另一个简单粗暴的方法,如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

 

什么叫缓存雪崩?

缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。缓存失效时的雪崩效应对底层系统的冲击非常可怕。有多种解决办法:

1、一个简单的办法是将缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

2、另外可以在系统设计时考虑用加锁或者队列的方式保证缓存的单线 程(进程)写,从而避免失效时大量的并发请求落到底层存储系统上()。

 

什么叫缓存击穿?

一个存在的key,在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。解决办法:

在访问key之前,采用SETNX(set if not exists)来设置另一个短期key来锁住当前key的访问,访问结束再删除该短期key。

 

 

Redis系列化方式有哪些?哪个系列化性能最好?

Redis系列化方式有JDK系列化、JSON系列化、XML系列化等多种。

我专门测试过,在我的笔记本电脑上保存5万条User对象到Redis,JDK系列化方式平均要15秒,JSON系列化方式只要13秒多点,JSON效率高,而且它点的内存空间少。

 

 

Redis持久化机制

Redis有两种持久化机制:

第一种是RDB快照模式,也是默认方式,它会把内存中所有数据都保存到磁盘上。它会在三种情况保存,一是根据配置触发,例如默认情况下15分钟之内更新一条记录,或者5分钟之内更新了10条记录,或者1分钟之内更新了1万都会触发保存。二是客户端手动执行save命令。三是服务端正常退出时也全部保存。RDB的缺点很明显,容易丢数据,另外由于每次保存都全部备份内存的数据,因此写入的数据大。

第二是是AOF追加模式,它只记录最后执行了更新命令和数据。优点是丢失的数据少,最大丢失一秒的数据,写入压力小,它追加最后一条。AOF模式不是默认的,需要手动打开,一旦打开后,RDB模式就失效。

 

如何取Redis中指定范围内的字符串?

Redis的getrange命令可以只取一部分字符串,

命令和参数为:GETRANGE key 开始位置 结束位置

 

 

Redis与Memcached的区别?

Redis功能要强大很多,现在很多公司都用它,它与Memcached有很多不同之处,例如:

Redis的数据类型很丰富,有String、List、Set、Store Set和Hash五种,而Memcached只支持单一的数据类型;

Redis支持数据持久化,Memcached则不支持,但可以通过第三方扩展来实现;

Redis支持事务,Memcached则不支持;

Redis是单线程,单线程在高并发系统中可以解决资源争夺问题。Memcached是多线程。

在集群和高可用方面,由于Memcached不互相通信,因此它无法构建服务端集群,尽管可以在客户端哈希分片集群,但容易引起缓存雪崩,一个节点宕机,则要重新从数据库装载数据并重新哈希存放。,Redis自2.8版本之后就支持基于哨兵模式的服务端主从结构,4.0去掉哨兵,支持更简单的主从模式。3.0之后支持分片集群。

在性能方面,Redis只使用单核,而Memcached可以使用多核,所以在比较上,平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。两者在每秒处理请求的次数都不会成为瓶颈。

 

 

 

Redis主从复制

  主从复制实现了读写分离,为了分担读压力,Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步和增量同步。

1 全量同步
  Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下: 
  1)从服务器连接主服务器,发送SYNC命令; 
  2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令; 
  3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令; 
  4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照; 
  5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令; 
  6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令; 
完成上面几个步骤后就完成了从服务器数据初始化的所有操作,从服务器此时可以接收来自用户的读请求。
2 增量同步
  Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。 
增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
 
3 Redis主从同步策略
  主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
 
4 注意点
如果多个Slave断线了,需要重启的时候,因为只要Slave启动,就会发送sync请求和主机全量同步,当多个同时出现的时候,可能会导致Master IO剧增宕机。所以就说到了下边的哨兵机制。
 
 
 

Redis哨兵模式

  Sentinel(哨兵)进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用,其已经被集成在redis2.6+的版本中,Redis的哨兵模式到了2.8版本之后就稳定了下来。一般在生产环境也建议使用Redis的2.8版本的以后版本。哨兵(Sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master主服务器是否下线的信息,并使用投票协议(Agreement Protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master。每个哨兵(Sentinel)进程会向其它哨兵(Sentinel)、Master、Slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定配置时间(可配置的)内未得到回应,则暂时认为对方已掉线,也就是所谓的”主观认为宕机” ,英文名称:Subjective Down,简称SDOWN。有主观宕机,肯定就有客观宕机。当“哨兵群”中的多数Sentinel进程在对Master主服务器做出 SDOWN 的判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,这种方式就是“客观宕机”,英文名称是:Objectively Down, 简称 ODOWN。通过一定的vote算法,从剩下的slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改相关配置,并开启故障转移(failover)。

1、Sentinel(哨兵)进程的作用:

              1】、监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
              2】、提醒(Notification):当被监控的某个Redis节点出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
              3】、自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master;当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用现在的Master替换失效Master。Master和Slave服务器切换后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,即,Master主服务器的redis.conf配置文件中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。

      
2、Sentinel(哨兵)进程的工作方式:
             1】、每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器,Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING 命令。
             2】、如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)。
             3】、如果一个Master主服务器被标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态。
             4】、当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主服务器进入了主观下线状态(SDOWN), 则Master主服务器会被标记为客观下线(ODOWN)。
             5】、在一般情况下, 每个 Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送 INFO 命令。
             6】、当Master主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主服务器的所有 Slave从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
             7】、若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。若 Master主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master主服务器的主观下线状态就会被移除。


3、哨兵模式的环境:
             1】、Master主服务器配置信息:IP:192.168.127.128, Port:6379,OS:Linux
             2】、Slave从服务器的配置信息:IP:192.168.127.129 Port:6379,OS:Linux
             3】、在Slave从服务器上安装了一个哨兵进程(Sentinel),在Master服务器也安装了一个哨兵进程(Sentinel)。


            由于两个Redis服务器都是安装在Linux操作系统上,而且这两个Redis服务器会在Master主服务器发生故障的时候会进行切换,必须保证两个Redis服务器的端口号已经增加进了防火墙,或者把两个Linux操作系统的防火墙关闭,否则会提示Master-link-Status:down,没有连接上Master主服务器。解决办法有两个:第一个办法是关闭两个Linux操作系统的防火墙;第二个办法是把各个Redis服务的端口号增加到防火墙里面,允许通过该端口号进行通信。可以先使用命令 【firewall-cmd --query-port=6379/tcp】,如果结果是 No,那就继续执行以下命令【firewall-cmd --add-port=6379/tcp】,命令执行后,返回Success,表示增加成功。这样两个Linux系统上的Redis服务器就可以顺利切换,执行哨兵模式的操作。

posted @ 2018-10-23 10:39  王大仙儿  阅读(473)  评论(0编辑  收藏  举报