Redis常用基础知识

redis的线程模型是什么

1)文件事件处理器

        文件事件处理器是单线程模式运行的,但是通过IO多路复用机制监听多个socket,可以实现高性能的网络通信模型,又可以跟内部其他单线程的模块进行对接,保证了redis内部的线程模型的简单性。

        文件事件处理器的结构包含4个部分:多个socket,IO多路复用程序,文件事件分派器,事件处理器(命令请求处理器、命令回复处理器、连接应答处理器,等等)。

        多个socket可能并发的产生不同的操作,每个操作对应不同的文件事件,但是IO多路复用程序会监听多个socket,但是会将socket放入一个队列中排队,每次从队列中取出一个socket给事件分派器,事件分派器把socket给对应的事件处理器。

        然后一个socket的事件处理完之后,IO多路复用程序才会将队列中的下一个socket给事件分派器。文件事件分派器会根据每个socket当前产生的事件,来选择对应的事件处理器来处理。

2)文件事件

      当socket变得可读时(比如客户端对redis执行write操作,或者close操作),或者有新的可以应答的socket出现时(客户端对redis执行connect操作),socket就会产生一个AE_READABLE事件。

     当socket变得可写的时候(客户端对redis执行read操作),socket会产生一个AE_WRITABLE事件。

      IO多路复用程序可以同时监听AE_REABLE和AE_WRITABLE两种事件,要是一个socket同时产生了AE_READABLE和AE_WRITABLE两种事件,那么文件事件分派器优先处理AE_REABLE事件,然后才是AE_WRITABLE事件。

3)文件事件处理器

      如果是客户端要连接redis,那么会为socket关联连接应答处理器

      如果是客户端要写数据到redis,那么会为socket关联命令请求处理器

      如果是客户端要从redis读数据,那么会为socket关联命令回复处理器

4)客户端与redis通信的一次流程

        在redis启动初始化的时候,redis会将连接应答处理器跟AE_READABLE事件关联起来,接着如果一个客户端跟redis发起连接,此时会产生一个AE_READABLE事件,然后由连接应答处理器来处理跟客户端建立连接,创建客户端对应的socket,同时将这个socket的AE_REA

         当客户端向redis发起请求的时候(不管是读请求还是写请求,都一样),首先就会在socket产生一个AE_READABLE事件,然后由对应的命令请求处理器来处理。这个命令请求处理器就会从socket中读取请求相关数据,然后进行执行和处理。 DABLE事件跟命令请求处理器关联起来。

        接着redis这边准备好了给客户端的响应数据之后,就会将socket的AE_WRITABLE事件跟命令回复处理器关联起来,当客户端这边准备好读取响应数据时,就会在socket上产生一个AE_WRITABLE事件,会由对应的命令回复处理器来处理,就是将准备好的响应数据写入socket,供客户端来读取。

        命令回复处理器写完之后,就会删除这个socket的AE_WRITABLE事件和命令回复处理器的关联关系。

拓展:Redis内存模型

redis都有哪些数据类型

 (1)string

        这是最基本的类型了 ,就是普通的set和get,做简单的kv缓存

 (2)hash

      这个是类似map的一种结构,这个一般就是可以将结构化的数据,比如一个对象(前提是这个对象没嵌套其他的对象)给缓存在redis里,然后每次读写缓存的时候,可以就操作hash里的某个字段。

     hash类的数据结构,主要是用来存放一些对象,把一些简单的对象给缓存起来,后续操作的时候,你可以直接仅仅修改这个对象中的某个字段的值(如购物车操作)

(3)list

      比如可以通过list存储一些列表型的数据结构,类似粉丝列表了、文章的评论列表了之类的东西,比如可以通过lrange命令,就是从某个元素开始读取多少个元素,可以基于list实现分页查询,这个很棒的一个功能,基于redis实现简单的高性能分页,

(4)set

      无序集合,自动去重

      直接基于set将系统里需要去重的数据扔进去,自动就给去重了,如果你需要对一些数据进行快速的全局去重,你当然也可以基于jvm内存里的HashSet进行去重,但是如果你的某个系统部署在多台机器上呢?得基于redis进行全局的set去重可以基于set玩儿交集、并集、差

(5)sorted set

     排序的set,去重但是可以排序,写进去的时候给一个分数,自动根据分数排序,最大的特点是有个分数可以自定义排序规则集的操作,比如交集吧,可以把两个人的粉丝列表整一个交集,看看俩人的共同好友是谁?

redis的过期策略都有哪些

  1:设置过期时间

        如果假设你设置一个一批key只能存活1个小时,那么接下来1小时后,redis是怎么对这批key进行删除的?

       答案是:定期删除+惰性删除

       所谓定期删除,指的是redis默认是每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。假设redis里放了10万个key,都设置了过期时间,你每隔几百毫秒,就检查10万个key,那redis基本上就死了,cpu负载会很高的,消耗在你的检查过期key上了。注意,这里可不是每隔100ms就遍历所有的设置过期时间的key,那样就是一场性能上的灾难。实际上redis是每隔100ms随机抽取一些key来检查和删除的。

       但是问题是,定期删除可能会导致很多过期key到了时间并没有被删除掉,那咋整呢?所以就是惰性删除了。这就是说,在你获取某个key的时候,redis会检查一下 ,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除,不会给你返回任何东西。并不是key到时间就被删除掉,而是你查询这个key的时候,redis再懒惰的检查一下

      通过上述两种手段结合起来,保证过期的key一定会被干掉。

  2:走内存淘汰机制。

    如果redis的内存占用过多的时候,此时会进行内存淘汰,有如下一些策略:

     1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错,

     2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最常用 的)

     3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key,

     4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key

     5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key

     6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优 先移除

redis的持久化有哪几种方式

持久化方式

   1:RDB

       RDB持久化机制就是周期性的将redis内存中的数据生成一份快照。

   2:AOF

       AOF机制对每条写入命令作为日志,以append-only的模式写入一个日志文件中去,在redis重启的时候可以回放AOF中日志写入指令来重新构建整个数据集,

      AOF是存放每条写命令的,所以就会 不断的膨胀,当大到一定的程度时候,AOF会进行rewrite操作,所谓的rewrite操作就是基于当时内存的数据来构建一个更小的AOF文件,然后将旧的AOF文件删除

      如果同时使用RDB和AOF两种持久化机制,那么在redis重启的时候,会使用AOF来重新构建数据,因为AOF中的数据更加完整

不同的持久化机制都有什么优缺点

RDB持久化的优点:

       1:RDB会生成多个数据文件,每个文件都代表某一个时间点的redis的数据,这种数据格式非常适合做冷备,

       2:RDB对redis对外提供读写服务影响非常小,可以让Redis保持高形成,因为redis主线程只需要fork一个子线程,让子线程执行磁盘IO来进行RDB持久化即可。RDB操作每次都写入到内存中去,只需要在一定时间,数据才会写入到磁盘,而AOF每次写入redis的时候,虽然可以快速写入到oscache中,但还是有一定的时间开销

       3:相对于AOF来说,直接基于RDB数据文件来重启和恢复redis进程,更加快速,因为AOF存放的是指令文件,每次都需要回放redis指令,来恢复redis内存中的数据

RDB持久化的缺点:

    1:如果redis在故障时,尽可能少的丢失数据,那么RDB没有AOF的效果好,

    2:RDB每次在fork一个子线程来执行RDB快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供服务暂停数秒,所以建议不要把RDB文件生成的间隔时间过长,如果过长,可能对redis性能有影响

AOF持久化的优点

  1. AOF可以更好的保证数据不丢失,一般AOF每隔1秒,通过后台线程会执行一次fsync操作,最多丢失1秒的数据,

  2. AOF日志文件通过append-only模式写入,所以没有任何寻址开销,写入性能非常高,而且文件不易损坏,即使尾部损坏,也非常容易恢复

  3. AOF日志文件即使文件过大的时候,出现后台重写操作,也不会影响客户端的读写,因为在rewrite log的时候会对其中的指令进行压缩,创建出一份需要恢复数据最小的日志出来,再创建新的日志文件的时候,老的日志文件还是照常写入,当新的merge后的日志文件ready的时候,再交还新老文件即可。

  4. AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复,比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据

AOF持久化的缺点

  1. 对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大

  2. AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的

  3. 以前AOF发生过bug,就是通过AOF记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来。所以说,类似AOF这种较为复杂的基于命令日志/merge/回放的方式,比基于RDB每次持久化一份完整的数据快照文件的方式,更加脆弱一些,容易有bug。不过AOF就是为了避免rewrite过程导致的bug,因此每次rewrite并不是基于旧的指令日志进行merge的,而是基于当时内存中的数据进行指令的重新构建,这样健壮性会好很多。

  4. 做数据恢复时,可能会比较慢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值