
数据库缓存可以提高网络环境下用户查询效率,它可将经常使用的数据存储在本地,对于频繁查询的数据可以减少查询的底层数据库的访问次数。而只读副本是数据库的冗余技术,通过在多个数据库上同步复制数据,避免一台数据库的死机对业务的影响,具有良好的容灾性。
在实际的开发当中,我们经常需要进行磁盘数据的读取和搜索,因此经常会有出现从数据库读取数据的场景出现。但是当数据访问量次数增大的时候,过多的磁盘读取可能会最终成为整个系统的性能瓶颈,甚至是压垮整个数据库,导致系统卡死等严重问题。
常规的应用系统中,我们通常会在需要的时候对数据库进行查找,因此系统的大致结构如下所示:
1缓存和数据库之间数据一致性问题
常用于缓存处理的机制我总结为了以下几种:
首先来简单说说Cache aside的这种方式:
Cache Aside模式
这种模式处理缓存通常都是先从数据库缓存查询,如果缓存没有命中则从数据库中进行查找。
这里面会发生的三种情况如下:
缓存命中:
当查询的时候发现缓存存在,那么直接从缓存中提取。
缓存失效:
当缓存没有数据的时候,则从database里面读取源数据,再加入到cache里面去。
缓存更新:
当有新的写 *** 作去修改database里面的数据时,需要在写 *** 作完成之后,让cache里面对应的数据失效。
关于这种模式下依然会存在缺陷。比如,一个是读 *** 作,但是没有命中缓存,然后就到数据库中取数据,此时来了一个写 *** 作,写完数据库后,让缓存失效,然后,之前的那个读 *** 作再把老的数据放进去,所以,会造成脏数据。
Facebook的大牛们也曾经就缓存处理这个问题发表过相关的论文,链接如下:
分布式环境中要想完全的保证数据一致性是一件极为困难的事情,我们只能够尽可能的减低这种数据不一致性问题产生的情况。
Read Through模式
Read Through模式是指应用程序始终从缓存中请求数据。 如果缓存没有数据,则它负责使用底层提供程序插件从数据库中检索数据。 检索数据后,缓存会自行更新并将数据返回给调用应用程序。使用Read Through 有一个好处。
我们总是使用key从缓存中检索数据, 调用的应用程序不知道数据库, 由存储方来负责自己的缓存处理,这使代码更具可读性, 代码更清晰。但是这也有相应的缺陷,开发人员需要给编写相关的程序插件,增加了开发的难度性。
Write Through模式
Write Through模式和Read Through模式类似,当数据发生更新的时候,先去Cache里面进行更新,如果命中了,则先更新缓存再由Cache方来更新database。如果没有命中的话,就直接更新Cache里面的数据。
2缓存穿透问题
在高并发的场景中,缓存穿透是一个经常都会遇到的问题。
什么是缓存穿透?
大量的请求在缓存中没有查询到指定的数据,因此需要从数据库中进行查询,造成缓存穿透。
会造成什么后果?
大量的请求短时间内涌入到database中进行查询会增加database的压力,最终导致database无法承载客户单请求的压力,出现宕机卡死等现象。
常用的解决方案通常有以下几类:
1空值缓存
在某些特定的业务场景中,对于数据的查询可能会是空的,没有实际的存在,并且这类数据信息在短时间进行多次的反复查询也不会有变化,那么整个过程中,多次的请求数据库 *** 作会显得有些多余。
不妨可以将这些空值(没有查询结果的数据)对应的key存储在缓存中,那么第二次查找的时候就不需要再次请求到database那么麻烦,只需要通过内存查询即可。这样的做法能够大大减少对于database的访问压力。
2布隆过滤器
通常对于database里面的数据的key值可以预先存储在布隆过滤器里面去,然后先在布隆过滤器里面进行过滤,如果发现布隆过滤器中没有的话,就再去redis里面进行查询,如果redis中也没有数据的话,再去database查询。这样可以避免不存在的数据信息也去往存储库中进行查询情况。
什么是缓存雪崩?
当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。
如何避免缓存雪崩问题?
1使用加锁队列来应付这种问题。当有多个请求涌入的时候,当缓存失效的时候加入一把分布式锁,只允许抢锁成功的请求去库里面读取数据然后将其存入缓存中,再释放锁,让后续的读请求从缓存中取数据。但是这种做法有一定的弊端,过多的读请求线程堵塞,将机器内存占满,依然没有能够从根本上解决问题。
2在并发场景发生前,先手动触发请求,将缓存都存储起来,以减少后期请求对database的第一次查询的压力。数据过期时间设置尽量分散开来,不要让数据出现同一时间段出现缓存过期的情况。
3从缓存可用性的角度来思考,避免缓存出现单点故障的问题,可以结合使用 主从+哨兵的模式来搭建缓存架构,但是这种模式搭建的缓存架构有个弊端,就是无法进行缓存分片,存储缓存的数据量有限制,因此可以升级为Redis Cluster架构来进行优化处理。(需要结合企业实际的经济实力,毕竟Redis Cluster的搭建需要更多的机器)
4Ehcache本地缓存 + Hystrix限流&降级,避免MySQL被打死。
使用 Ehcache本地缓存的目的也是考虑在 Redis Cluster 完全不可用的时候,Ehcache本地缓存还能够支撑一阵。
使用 Hystrix进行限流 & 降级 ,比如一秒来了5000个请求,我们可以设置假设只能有一秒 2000个请求能通过这个组件,那么其他剩余的 3000 请求就会走限流逻辑。
然后去调用我们自己开发的降级组件(降级),比如设置的一些默认值呀之类的。以此来保护最后的 MySQL 不会被大量的请求给打死。
我们都知道 MySQL 的 Table Cache 是表定义的缓存,江湖上流传着各种对这个参数的调优方法。
table cache 的作用,就是节约读取表结构文件的开销。对于table cache 是否命中,其实table cache 是针对于线程的,每个线程有自己的缓存,只缓存本线程的表结构定义。不过我们发现,strace 中没有关于表结构文件的 open *** 作(只有 stat *** 作,定位表结构文件是否存在),也就是说 table cache 不命中,不一定需要读取表结构文件。这种感觉好像是:在不命中 table cache 时,命中了另外一个表结构缓存。
运维建议:
我们读一下 MySQL 的文档,关于 table_open_cache 的建议值公式:建议值 = 最大并发数 join 语句涉及的表的最大个数。
通过实验我们容易理解:table_cache 是针对于线程的,所以需要最大并发数个缓存。另外,一个语句 join 涉及的表,需要同时在缓存中存在。所以最小的缓存大小,等于语句 join 涉及的表的最大个数。将这两个数相乘,就得到了 MySQL 的建议值公式。
因为Redis具有在数据存储中快速读写数据的能力,所以它比关系型数据库更具有性能优势。但是,关键值数据存储是简单的;它们没有一个类似于
SQL的查询语言或者结构化的数据模型。相反,它们有一个把键值作为与数值相关的标识符来使用的简单字典或哈希模式。管理员使用这些键来进行数值的存储和
检索。
键值存储是简单快速的,它可用于实现丰富数据模型和关系型数据库查询功能的良好匹配。但是,有时候还是使用键值与关系型数据库的组合为好。此外,还有很多商业支持的键值数据库,包括Redis、Riak和Areospike等。
为了运行一个优化热门查询性能的Redis缓存,首先应确定你希望缓存的查询结果。其中,应重点关注最常用的和最耗时的查询,然后确定应缓冲查询中的数据。为简便起见,缓存查询返回的所有列值。
为键值定义一个命名约定;可以使用行主键和列名的组合来构造密钥。例如,其主键ID为 198278的 产品描述可以‘198278:descry’的键值进行存储。确保你的命名规则是简单和规则驱动的,以便于使用最少的代码来实现键的程序化创建。
接下来,确定是运行Redis缓存作为自助管理服务还是运行亚马逊的ElastiCache。运行用户自己的Redis实例将赋予管理人员对缓存的完全控制权。而这一控制权意味着灵活性,例如当有超出容量的情况出现时,管理人员有使用现有保留实例的权力。
此外,当用户想要把应用程序从一家云计算供应商迁移至另一家时,他们会发现完整的管理控制权限是非常有用的。
如果用户选择运行一个自助管理的Redis实例,可下载服务器。Redis的客户端支持30种以上编程语言——从Java和Python到Prolog和Smalltalk。
已经使用AWS环境的企业可能会想要使用ElastiCache。除了诸如托管打补丁这样的优点之外,亚马逊ElastiCache支持一系列高速
缓存优化的节点类型,具体包括从中型到2X的m3节点、从大型到8X的r3节点以及从微型到中型的t2节点。ElastiCache还支持一些上一代的节
点类型,例如选择m1、m2、t1和c1节点。
ElastiCache还支持多个可用区。如果有一个节点发生故障,一个读 *** 作复制节点将取代故障节点。任何需要确保应用程序运行的DNS变更都是
自动完成的,同时会创建一个新的读 *** 作副本。ElastiCache允许基于单位时间使用率的按需定价模式,以及一年期或三年期预付费的节点使用条款。完
整定价清单可以在这里找到。
如果使用Redis缓存和亚马逊ElastiCache,那么就可以从AWS管理控制台启动一个集群。除了设置Redis服务外,还需要修改应用程
序代码以便于能够使用缓存。一个常用的模式就是,检查缓存中是否存在有一个键值,如果没有就执行一个SQL查询以检索数据,然后将其存储在缓存中。当缓冲
存满时,可以配置Redis删除旧数据,这样就不需要用户使用专门的代码来处理缓存存满的情况了。
java缓存技术
一、什么是缓存
1、Cache是高速缓冲存储器 一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问
2、凡是位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之为 Cache
二、缓存的分类
1、基于web应用的系统架构图
2、在系统架构的不同层级之间,为了加快访问速度,都可以存在缓存
*** 作系统磁盘缓存->减少磁盘机械 *** 作
数据库缓存->减少文件系统I/O
应用程序缓存->减少对数据库的查询
Web服务器缓存->减少应用服务器请求
客户端浏览器缓存->减少对网站的访问。
以上就是关于数据库缓存和只读副本的区别全部的内容,包括:数据库缓存和只读副本的区别、华为技术架构师分享:高并发场景下缓存处理的一些思路、数据库缓存机制是什么缓存是如何作用数据库等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)