redis 分布式缓存

分布式缓存的主要有点: 高性能与高并发

高性能:内存读取速度远高于数据库

高并发:数据库瞬间不能支持高并发,通过缓存,可以支持每秒十万级的请求。普通数据库每秒响应千级的。

使用缓存存在的常规问题:

1.缓存与数据库双写不一致   常用的是先更新数据库,然后删除缓存 这个叫 Cache Aside Pattern,老外发明的。如果先更新数据库,再删除缓存,那么就会出现更新数据库之前有瞬间数据不是很及时。   可以   先删缓存,然后写db,通过订阅数据库的binlog在删除缓存。

2.缓存雪崩   缓存集群挂了,或者大量缓存同一时间过期的导致大量请求打到db。保证缓存集群的高可用, 哨兵或者cluster方案。热点key不要过去,定时去更新。热点key分部在cluster的不同节点上。

3.缓存击穿    一个缓存key失效的瞬间,大量请求进入db。  做限流,分布式锁,只允许一个请求去查询db。

4.缓存穿透   大量cache中不存在这个key,请求进入db。  可以在db中查询没有的key,在cache中设置一个快速过期的空值。或者使用布隆过滤器,把所有可能存的数据存在一个足够大的bitmap中,一定不存在的数据就会被拦截在,从而避免对底层数据库的查询。

redis的线程模型:

        redis基于reactor模式开发了网络事件处理模型,这个事件叫做文件事件处理模型(file event handler)。这个文件处理器是单线程的,采用IO多路复用机制同时监听多个socket,根据socket上的事件来选择对应事件处理器来处理这个事件。

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

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

        多个socket可能并发的产生不同的操作,每个操作对应不同的文件事件,但是IO多路复用机制会监听多个socket,但是会将socket放入一个队列中进行排队,每次从队列中取出一个socket给事件分派器,事件分派器把socket给对应的事件处理器。然后一个socket的事件处理完成之后,IO多路复用程序才会将队列中的下一个socket给事件分配器,事件分配器把socket给具体的事件处理器。

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

        Redis的客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个步骤。其中执行命令阶段,由于redis是单线程来处理命令的,所以每条到达服务端的命令不会立即被执行,所有命令会进入一个队列然后逐个被执行。多个客户端发送的命令的执行顺序是不确定的,但是可以确定的是两个命令不会被同时执行,不会产生并发问题,这就是redis的单线程基本模型。

在redis启动初始化的时候,redis会将连接应答处理器和跟AE_READABLE事件关联起来。

当有一个client和redis发起连接,此时会产生一个AE_READABLE事件,然后又对应的事件处理器处理。这个命令处理器就会从socket中读取相关的数据,然后进行执行和处理。

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

接着redis准备好了给客户端的相应数据之后,就会将socket的AE_WRITABLE ;

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章