MySql架构设计:如何合理利用第三方-Cache-解决方案?,java编程面试公开书

本文探讨了如何将Memcached有效整合到系统架构中,作为提升性能的Cache工具与MySQL数据库的融合方案。介绍了两种方式:一是单纯作为Cache加速,二是通过WaffleGrid实现Memcached作为MySQL缓存增强。详细阐述了各自优缺点和适用场景。
摘要由CSDN通过智能技术生成

要将 Memcached 较好的整合到系统架构中,首先要在应用系统中让 Memcached 有一个准确的定位。是仅仅作为提升数据服务性能的一个 Cache 工具,还是让他与 MySQL 数据库较好的融合在一起成为一个更为更为高效理想的数据服务层。

①作为提升系统性能的 Cache 工具

如果我们仅仅只是系统通过 Memcached 来提升系统性能,作为一个 Cache 软件,那么更多的是需要通过应用程序来维护 Memcached 中的数据与数据库中数据的同步更新。这时候的 Memcached 基本可以理解为比 MySQL 数据库更为前端的一个 Cache 层。

如果我们将 Memcached 作为应用系统的一个数据 Cache 服务,那么对于 MySQL 数据库来说基本上不用做任何改造,仅仅通过应用程序自己来对这个 Cache 进行维护更新。这样作最大的好处就在于可以做到完全不用动数据库相关的架构,但是同时也会有一个弊端,那就是如果需要 Cache 的数据对象较多的时候,应用程序所需要增加的代码量就会增加很多,同时系统复杂度以及维护成本也会直线上升。

下面是将 Memcached 用为简单的 Cache 服务层的时候的架构简图。

从图中我们可以看到,所有数据都会写入 MySQL Master 中,包括数据第一次写入时候 的 INSERT,同时也包括对已有数据的 UPDATEDELETE。不过,如果是对已经存在的数据 ,则需要在 UPDATE 或者 DELETE MySQL 中数据的同时,删除 Memcached 中的数据,以此保证整体数据的一致性。而所有的读请求首先会发往 Memcached 中,如果读取到数据则直接返回,如果没有读取到数据,则再到 MySQL Slaves 中读取数据,并将读取得到的数据写入到 Memcached 中进行 Cache

这种使用方式一般来说比较适用于需要缓存对象类型少,而需要缓存的数据量又比较大的环境,是一个快速有效的完全针对性能问题的解决方案。由于这种架构方式和 MySQL 数据库本身并没有太大关系,所以这里就不涉及太多的技术细节了。

②和 MySQL 整合为数据服务层

除了将 Memcached 用作快速提升效率的工具之外,我们其实还可以将之利用到提高数据服务层的扩展性方面,和我们的数据库整合成一个整体,或者作为数据库的一个缓冲。

我们首先看看如何将 MemcachedMySQL 数据库整合成一个整体来对外提供服务吧。一般来说,我们有两种方式将 MemcachedMySQL 数据库整合成一个整体来对外提供数据服务。一种是直接利用 Memcached 的内存容量作为 MySQL 数据库的二级缓存,提升 MySQL Server 的缓存大小,另一种是通过 MySQLUDF 来和 Memcached 进行数据通信,维护和更新 Memcached 中的数据,而应用端则直接通过 Memcached 来读取数据。

对于第一种方式,主要用于业务要求非常特殊,实在难以进行数据切分,而且有很难通过对应用程序进行改造利用上数据库之外的 Cache 的场景。

当然,在正常情况下是肯定无法做到这一点的,之少目前必须借助外界的力量,开源项目 Waffle Grid 就是我们需要借助的外部力量。

Waffle Grid 是国外的几位 DBA 在工作之余突发奇想出来的一个点子:既然 PC Server 的低廉成本如此的吸引我们,而其 Scale Up 的能力又很难有一个较大的突破,何不利用上现在非常流行的 Memcached 作为突破单台 PC Server 的内存上限呢?就在这个想法的推动下,几位小伙子启动了 Waffle Grid 这个开源项目,利用 MySQLMemcached 双双开源的特性,结合 Memcached 通信协议简单的特点,将 Memcached 成功实现成为 MySQL 主机的外部“二级缓存”,目前仅支持用于 InnodbBuffer Pool

Waffle Grid 的实现原理其实并不复杂,他所做的事情就是当 Innodb 在本地的 Buffer Pool(我们姑且称其为 Local Buffer Pool 吧)的时候,在从磁盘数据文件读取数据之前,先通过 Memcached 的通信 API 接口尝试从 Memcached 中读取相应的缓存数据(我们称之为 Remote Buffer 吧),只有在 Remote Buffer 中也不存在需要的数据的时候, Innodb 才会访问磁盘文件来读取数据。而且,只有处于 Innodb Buffer pool 中的 LRU List 中的数据会被发送到 Remote Buffer Pool 中,而这些数据一旦被修改,就会 Innodb 就会将之移入 FLUSH ListWaffle Grid 同时会将进入 FLUSH List 的数据从 Remote Buffer Pool 中清除掉。所以可以说,Remote Buffer Pool 中永远不会存在 Dirty Pages,这也保证了当 Remote Buffer Pool 出现故障的时候不会产生数据丢失的问题。下图是使用 Waffle Grid 项目时候的架构简图:

如架构图上所示,我们首先在 MySQL 数据库端应用 Waffle Grid Patch,通过他连与其他的 Memcached 服务器通信。为了保证网络通信的性能,MySQLMemcached 之间尽可能用高带宽私有网络。

另外,这里的架构图中并没有再将数据库区分 MasterSlave 了,并不是说一定不能区分,只是一个示意图。在实际应用过程中,大部分时候只需要在 Slave 上面应用 Waffle Grid 即可,Master 本身并不需要如此大的内存。

看了 Waffle Grid 的实现原理,可能有些读者朋友会有些疑问了。这样做不是所有需要产生物理读的 Query 的性能就会受到直接影响了吗?所有读取 Remote Buffer 的操作都需要通过网络来获取,其性能是否足够高呢?对此,我同样使用作者对 Waffle 的实测数据来接触大家的疑虑:

通过 DBT2 所得到的这组测试对比数据,在性能我想并不需要太多的担忧了吧。至于 Waffle Grid 是否适合您的应用场景,那就只能依靠各位读者朋友自己进行评估了。

下面我们再来介绍一下 MemcachedMySQL 的另外一种整合方式,也就是通过 MySQL 所提供的 UDF 功能,自行编写相应的程序来实现 MySQLMemcached 的数据通信更新操作。

这种方式和 Waffle Grid 不一样的是 Memcached 中的数据并不完全由 MySQL 来控制维护,而是由应用程序和 MySQL 一起来维护数据。每次应用程序从 Memcached 读取数据的时候,如果发现找不到自己需要的数据,则再转为从数据库中读取数据,然后将读取到的数据写入 Memcached 中。而 MySQL 则控制 Memcached 中数据的失效清理工作,每次数据库中有数据被更新或者被删除的时候,MySQL 则通过用户自行编写的 UDF 来调用 MemcachedAPI 来通知 Memcached 某些数据已经失效并删除该数据。

基于上面的实现原理,我们可以设计出如下这样的一个数据服务层架构:

如图中所示,此架构和上面将 Memcached 完全和 MySQL 读离开作为常规的 Cache 服务器来比较,最大的区别在于 Memcached 的数据变为由 MySQL 数据库来维护更新,而不是应用程序来更新。首先数据被应用程序写入 MySQL 数据库,这时候将会触发 MySQL 上面用户自行编写的相关 UDF,然后通过该 UDF 调用 Memcached 的相关通信接口,将数据写入 Memcached。而当 MySQL 中的数据被更新或者删除的时候,MySQL 中的相关 UDF 同样会更新或者删除 Memcached 中的数据。当然,我们也可以让 MySQL 做更少一些的事情,仅仅只是遇到数据被更新或者删除的时候,通过 UDF 来删除 Memcached 中的数据,写入工作则像前面的架构一样由应用程序来作。

由于 Memcached 基于对象的数据存取,以及通过 Hash 进行数据检索的特性,所以所有存储在 Memcached 中的数据都需要我们设定一个用于标识该数据的 Key,所有数据的存取操作都通过该 Key 来进行。也就是说,如果您并不能像 MySQL

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

Query 语句一样通过某一个(或者多个)关键字条件来读取包含多条数据的结果集,仅适用于通过某个唯一键来获取单条数据的数据读取方式。

二、嵌入式数据库编程库 Berkeley DB

说实话,数据库编程库这个叫法实在有些别扭,但我也实在找不到其他合适的名词来称呼 Berkeley DB 了,那就姑且使用网上较为通用的叫法吧。

Memcached 所实现的是内存式 Cache,如果我们对性能的要求并没有如此之高,在预算方面也不是太充裕的话,我们还可以选择 Berkeley DB 这样的数据库型 Cache 软件。可能很多读者朋友又会产生疑惑了,我们使用的 MySQL 数据库,为什么还要再使用一个 Berkeley DB 这样的“数据库”呢?实际上 Berkeley DB 在之前也是 MySQL 的存储引擎之一,只不过后期不知道是何原因(获取与商业竞争有关吧),被 MySQL 从支持的存储引擎中移除了。之所以在使用数据库的同时还使用 Berkeley DB 这样的数据库型 Cache,是因为我们可以充分发挥出二者各自的优势,在使用传统通用型数据库的同时,同时可以利用 Berkeley DB 高效的键值对存储方式作为高效数据检索的性能补充,以得到更好的数据服务层扩展性和更高的整体性能

Berkeley DB 自身架构可以分为五个功能模块,五个模块的在整个系统中相对比较独立,而且可以设置使用或者禁用某一个(或者几个)模块,所以可能称之为五个子系统会更为恰当一些。这五个子系统及基本介绍分别如下:

  • 数据存取
    数据存取子系统主要负责最主要也是最基本的数据存与取的工作。而且 Berkeley DB 同时支持了以下四种数据的存储结果方式:HashB-TreeFixed Length 以及 Dynamic Length。实际上,这四种方式对应了四种数据文件存储的实际格式。数据存储子系统可以完全单独使用,也是必须开启的一个子系统。
  • 事务管理
    事务管理子系统主要是针对有事务要求的数据处理服务,提供完整的 ACID 事务属性。在开启事务管理子系统的时候,出了需要开启最基本的数据存取子系统外,还至少需要开启锁管理子系统和日志系统来帮助实现事务的一致性和完整性。
  • 锁管理
    锁管理系统主要就是为了保证数据的一致性而提供的共享数据控制功能。支持行级别和页级别的锁定机制,同时为事务管理子系统提供服务。
  • 锁管理
    锁管理系统主要就是为了保证数据的一致性而提供的共享数据控制功能。支持行级别和页级别的锁定机制,同时为事务管理子系统提供服务。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值