高性能MySQL复制与缓存

  1. 复制解决的基本问题

    让一台服务器的数据让其他服务器保持同步,一台主库的数据可以同步到多台备库上, 备库本身也可以被配置成另外一台服务器的主库。

    MySQL支持两种复制方式:基于行的复制和基于语句的复制(逻辑复制)。这两种都是在主库上记录二进制日志,在备库重放日志的方式来实现异步的数据复制, 这说明同一时间主备库存在不一致,并且无法保证主备之间的延迟。

  2. 常见的复制用途

    数据分布:MySQL通常复制不会造成很大的带宽压力,但基于行的复制会比基于语句的复制带宽压力大, 可以随意停止或开始复制,并在不同的地理位置来分布数据备份,例如不同的数据中心, 即使在不稳定的网络环境下,远程复制也可以工作,降低了单位复制延迟,最好有一个稳定的低延迟连接。

    负载均衡:将读操作分布到多个服务器上,实现对读密集型应用的优化

    备份:对备份来说,复制是一项很有意义的技术补充,但复制既不是备份也不能取代备份。

    高可用性和故障切换:帮助应用程序避免MySQL单点失败,一个包含复制的设计良好的故障切换系统能够显著地缩短宕机时间

    MySQL升级测试:使用一个更高版本的MySQL作为备库,保证在升级全部实例之前。查询能够在备库按照预期执行。

  3. 复制步骤

    主库把数据更改记录到二进制日志中

    在提交事物完成数据更新前,主库将数据更新的时间记录到二进制日志中,按照事务提交的顺序 而非每条语句的执行顺序来记录二进制日志,在记录之后,主库会告诉存储引擎可以提交事物了。

    备库将主库上的日志复制到自己的中继日志中

    备库读取中继日志中的时间,将其重放到备库数据之上

  4. 基于语句的复制

    主库会记录那些造成数据更改的查询,当备库读取并重放这些事件时,实际上这只是把主库上执行过的SQL在执行一遍

    优势:实现简单,二进制日志里面的时间更加紧凑,不会使用太多带宽

    劣势:更新必须串行,需要更多的锁,不是所有的引擎都支持这种复制模式,存在一些无法被正确复制的SQL, 存储过程和触发器在使用基于语句的复制模式时也可能存在问题

    基于行的复制

    将实际数据记录在二进制日志中,可以正确复制每一行,一些语句可以被更有效的复制

  5. 一主多备结构

    为不同的角色使用不同的备库比如 添加不同的索引或使用不同的存储引擎

    把一台备库当做代用的主库,除了复制没有其他数据传输

    将一台备库放到远程数据中心,用作灾难恢复

    延迟一个或多个备库,以备灾难恢复

    使用一个备库作为备份、培训、开发、或者测试使用服务器

  6. 主-被动模式服务器对称设置

    确保两台服务器上有相同的数据

    启用二进制日志,选择唯一的服务器ID,并创建复制账号

    启用备库更新的日志记录

    把被动服务器配置成只读,防止可能与主动服务器上的更新产生冲突

    启动每个服务器的MySQL实例

    将每个主库设置为对方的备库,使用新建的二进制日志开始工作

    主动服务器上更新时:更新记录到二进制日志中,通过复制传递给被动服务器的中继日志中 被动服务器执行查询并将其记录到自己的二进制日志中,由于事件的服务器ID与主动服务器的 相同,因此主动服务器忽略这些事件。

    这种类似于创建一个热备份,但是可以使用这个备份来提高性能,比如执行读操作、备份、离线 维护升级等。但是不会获得比单台服务器更好的写性能。

  7. 拥有备库的主-主结构

    为每一个主库增加一个备库,增加了冗余,对于不同地理位置的复制拓扑,能够消除站点断电失效的问题 可以将读查询分配到备库上

    主库失效时,用备库来代替主库是可行的,也可以把备库指向一个不同的主库,但需要考虑增加的复杂度

  8. 环形复制拓扑

    每一个服务器都是他之前服务器的备库,是他之后服务器的主库

  9. 主库 分发主库 备库

    分发主库实际上也是一个备库,他的目的是提取和提供主库的二进制日志 多个备库连接到分发主库,原来的主库摆脱了负担,为了避免在分发主库上做实际的查询, 可以将他的表修改为blackhole存储引擎

    可以使用分发主库实现对二进制日志时间执行过滤和重写规则,这个比在每个备库上重复进行日志记录、 重写和过滤效率高得多

    在分发主库上使用blackhole表,可以支持更多的备库,虽然会在分发主库上执行查询, 但其代价非常小,因为blackhole的表里面没有任何数据,blackhole表的缺点是存在bug, 在某些情况下会忘记将自增的id写入二进制日志

    使用分发主库无法使用一个备库来代替主库,因为分发主库的存在,导致各个备库与原始主库的二进制日志坐标已经不相同

  10. 日志服务器

    mysqlbinlog:用来记录mysql内部增删改查等对数据库有更新的内容的记录,对数据库的查询select或show等不会被binlog记录,主要用于数据库的主从复制以及增量恢复

    复制作为应用二进制日志的方法已经被大量的用户所测试,能够证明是可行的的,mysqlbinlog可能无法正确生成二进制日志中的数据更新

    复制的速度更快,因为无需将语句从日志导出来并传送给mysql

    很容易观察到复制过程

    方便处理错误,例如可以跳过执行失败的语句

    方便过滤复制事件

    有时候mysqlbinlog会因为日志记录格式更改无法读取二进制日志

  11. 缓存

    应用层以下的缓存:MySQL服务器有自己的内部缓存,也可以构建自己的缓存和汇总表,缓存表比许多应用层缓存更加持久,在服务器重启之后他们还存在

    应用层缓存:在同一台机器的内存中缓存数据,或者通过网络存在另一台机器的内存中, 应用层缓存可以节省获取数据以及基于这些数据进行计算。但是缓存命中率低,并且可能使用更多的内存。

    应用缓存之本地缓存:小,只在进程处理请求期间存在于进程内存中。可以避免对某些资源的重复请求

    应用缓存之本地共享内存缓存:中等大小,快速,难以在多台机器间同步,对小型的半静态位数据比较合适 ,但是访问非常快,通常比任何远程缓存访问都快

    应用缓存之分布式内存缓存:比本地共享内存缓存大得多,增长容易,缓存中创建的数据的每一个比特都只有一个副本, 不会浪费内存,也不会因为缓存创建的数据存在不同的地方而引入一致性问题。 非常适合存储共享对象,但是延时高,最有效的方法是批量进行多个获取操作,还要考虑怎么增加更多的节点, 以及某个节点崩溃了怎么处理,应用程序必须决定在节点间怎么分布或充分不缓存对象

    应用缓存之磁盘缓存:最好是持久性对象,很难全部存进内存的对象或者静态内容

  12. 缓存控制策略

    问题:重复数据,有多个地方需要更新数据,所以要避免读到脏数据

    TTL(time to live 存活时间):缓存对象存储是设置一个过期时间,可以通过清理进程在未达到过期时间后删除对象, 或者留到下次访问时再清理,对于数据很少变更或没有新数据的情况,这是最好的失效策略。

    显示失效:如果不能接受脏数据,那么在更新原始数据时同时使缓存失效

    写——失效:标记缓存数据已经过期(是否清理缓存数据是可选的)。

    写——更新:更新数据时替换掉缓存项

    读时失效:采用对象版本控制

    缓存对象分层:分层缓存对象对检索、失效和内存利用都有帮助,相对于只缓存对象,也可以缓存对象的ID、对象的ID组等需要一起检索的数据

    预生成内容:在后台预先请求一些页面,并将结果存为静态页面。

    作为基础组件的缓存

    使用handlerSocket 和memcached:handlerSocketto 刚刚一个简单的协议访问innodb handler 绕过上层的服务器层,

    通过网络直接连接innodb引擎,通过memcached协议访问innoDB

你可能感兴趣的:(数据库)