服务器缓存系统

WEB系统中各参与者都可以进行缓存。数据库缓存,应用服务器缓存,Web服务器缓存,客户端浏览器缓存。

 

java缓存级别:

堆缓存

堆外缓存

磁盘缓存

分布式缓存

 

典型java服务器端缓存系统:

1、接入nginx负载均衡到应用nginx。

2、应用nginx读取本地缓存(Nginx Proxy Cache或者Local Redis缓存)。如果命中,则直接返回。后续步骤中也是类似不再赘述。

3、读取从redis服务器缓存。OpenResty的lua-resty-redis模块可以使Nginx具有了直接读取redis缓存的能力,不占用tomcat的线程。

3、回源到Tomcat集群。

4、Tomcat应用中,读取本地缓存。

6、回源到数据库集群。

7、将数据库返回的数据以异步方式写到主redis服务器。

 

有缓存时的查询流程:

应用服务器查询缓存。如果查到缓存服务器,则使用。如果没有查到缓存,则查询数据库。数据库返回结果后,应用服务器写缓存服务器,内容为key-value对。

 

缓存使用模式:

Cache-Aside:查不到缓存时,由业务代码回源SoR(source of record)

Cache-As-SoR:所有操作都是对cache进行,Cache进行SoR回源。

 

缓存淘汰or更新

淘汰缓存只是增加了一次cache miss。更新缓存虽然避免了cache miss,但是成本更高。所以通常淘汰缓存而不是更新。

 

数据库和缓存的一致性:

方式1:先更新数据库,然后同步淘汰缓存。优点:数据不一致性时间短。缺点:请求处理时间长。例如:使用mysql memcached UDF(用户自定义函数)和mysql触发器在更新mysql数据库的时候,触发淘汰cache。这样可以减少应用程序的逻辑。也可以保证事务的完整性。

方式2:先更新数据库,然后异步淘汰缓存。优点:请求处理时间短。缺点:数据不一致时间长。例如:可以使用canal,模拟mysql slave和master的同步机制,监控mysql binlog来触发redis缓存的淘汰。

 

清除缓存

基于时间清除缓存:TTL和TTI(Time to Idle)

缓存满的含义:缓存超过设置的存储空间或者超过设置的条目数。

缓存满了,使用LRU机制驱逐老的缓存。热点缓存,要多存储几份,也可以在应用系统中进行几秒钟的本地缓存,从而降低远程缓存系统的压力。

除了LRU还有FIFO和LFU(Least Frequently used)

 

缓存相关问题:

缓存穿透:查询不存在的id,每次都会访问DB。如果id不存在,则内容设置为null,并且设置缓存的失效时间。

缓存雪崩:缓存集中过期失效(比如双11活动在0点开始,1点缓存集中失效)。缓存失效时间加一个随机因子,防止同时失效。可以在缓存失效前,主动通知后台线程更新缓存。

缓存击穿:一个key非常热点(爆款产品),这个key失效瞬间,导致大量数据库请求。对一个key只允许一个线程查询数据库和写缓存,其他线程等待。

缓存预热:缓存预热就是系统上线后,提前将相关的热点数据加载到缓存系统。避免在用户请求的时候,再查询数据库。

 

Redis:

redis是数据结构服务器,所以重点就是它支持的数据结构。使用命令来操作数据结构。最常用的命令是set()和get()。

Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库、高速缓存和消息队列。Key-Value中值(value)可以是字符串、列表、集合、有序集合、哈希、位图、hyperloglog(用于快速计算基数(一个数据集中不同元素的数目))、流等数据类型。内置Lua脚本、LRU机制、事务以及不同级别磁盘持久化功能。Redis支持master-slave模式的数据备份。可以通过Redis Sentinel(哨兵)提供高可用功能,发现主服务器崩溃后,自动选举新的主服务器,并且通知应用服务器。也可以通过Redis Cluster提供集群功能。

Redis使用ANSI C语言编写,提供多种语言的API,包括:c、C++、C#、php、java、python、go等语言。

Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。

Redis支持 publish/subscribe模式,所以可以用作消息队列。

Redis 支持管道技术。允许服务端未响应时,客户端继续向服务端发送其它请求,并最终一次性读取所有服务端的响应。这提高了性能。

 

Twemproxy可以作为redis的代理。这样可以减少和后台缓存服务器的连接数。也可以用于实现redis集群。Twemproxy支持多种hash算法。支持失败节点自动删除。后端sharding(分片)逻辑对业务透明。

Redis集群也可以不使用Twemproxy,直接使用redis-cluster特性。Redis-Cluster采用无中心结构。健壮性更高。

数据按照hash slot存储分布在多个节点。

每个节点保存整个集群状态,每个节点(包括slave节点)都和其他所有节点连接。

每个主节点有若干个slave节点。实现故障自动failover,节点之间通过gossip协议交换状态信息,用投票机制完成Slave到Master的角色提升。这类似于简化版的OSPF DR选举。但是又不同,从节点发现主节点down了,从节点会广播request消息,要求成为主节点,其它从节点会如果同意则返回ack,如果选票过半,则当选。gossip协议用于P2P网络中,传播消息的方式类似于OSPF的flood机制。

可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。

高可用性,部分节点不可用时,集群仍可用。

应用服务器可以访问任何一个主节点,如果数据不在这个主节点上,它会返回一个moved重定向消息,告诉应用服务器应该访问哪个主节点。可以使用JedisPool,它将cluster slots的结果保存在本地,分配请求。

 

主从同步:

Redis全量复制通常发生在slave初始化阶段。之后就是增量赋值。

全量复制时,主服务器收到从服务器的SYNC命令后会生成RDB(Redis DataBase)快照文件。同时在缓冲区中记录此后执行的命令。将RDB文件发送给slave之后,还要将缓冲区中的命令发送给slave。之后主服务器执行写命令时就会向从服务器发送相同的写命令。

这和ospf很类似。但是ospf显然更先进,它会比较双方的LSDB,只请求缺失的部分。

主从同步还可以使用AOF的方式,它的基本原理是从服务器回放主服务器执行过的命令。

 

redis cluster集群中通过消息来进行通信。消息共有以下5种。

meet消息:加入到集群中。

ping消息:检测目标节点是否处于在线状态。

pong消息:收到到meet消息或者ping消息后,会回复pong消息。另外,pong消息也可以用于主动更新,例如故障转移后,新的主节点会向集群中发送pong消息,用于告知它已经升级为主节点。

fail消息:fail消息用于通知某个节点掉线了。例如节点A认为节点B已下线(B一段时间内都没有回复pong消息),节点A会向集群中发送一条fail消息,接收到这条消息的节点会将节点B标记为疑似下线。当大于等于半数的节点认为B下线了,这个节点就被标记为下线。

 

Redis vs Memcache

有持久化需求、对数据结构要求高、对处理有高级要求的应用,选择redis。简单的key/value存储,选择memcache。Redis只支持linux。Memcache支持windows、linux。

Redis支持简单的事务,只是一次性按顺序执行多条命令。但是不支持回滚,即有命令出错,也会继续执行。Memcache不支持事务。

Redis是单线程的。Memcache是多线程的。

Redis没有自己的内存管理模块。Memcache有自己的内存管理模块,内存分配效率更高。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值