IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 从开源框架理解设计模式系列#Memento备忘录模式 -> 正文阅读

[大数据]从开源框架理解设计模式系列#Memento备忘录模式

目录

what什么是备忘录模式

why为什么需要备忘录模式

how如何实现备忘录模式

开源框架经典案例?

Mysql的Redo日志

JDK中Corba的备忘录模式

使用场景

优缺点对比

优点

缺点

参考资料


what什么是备忘录模式

? ? ? ? ?Gof定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。别名Token。

why为什么需要备忘录模式

? ? ? ? 使用备忘录有两个目标。

  • 存储系统关键对象的重要状态。
  • 维护关键对象的封装。

???????有时有必要记录一个对象的内部状态。为了允许用户取消不确定的操作或从错误中恢复 过来,需要实现检查点和取消机制, 而要实现这些机制,你必须事先将状态信息保存在某处, 这样才能将对象恢复到它们先前的状态。但是对象通常封装了其部分或所有的状态信息, 使得 其状态不能被其他对象访问,也就不可能在该对象之外保存其状态。而暴露其内部状态又将 违反封装的原则,可能有损应用的可靠性和可扩展性。

how如何实现备忘录模式

????????备忘录模式的主要角色如下。

  1. 发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
  2. 备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
  3. 管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。

备忘录模式的结构图

开源框架经典案例?

Mysql的Redo日志

? ?我们都知道,事务的四大特性里面有一个是?持久性?,具体来说就是只要事务提交成功,那么对数据库做的修改就被永久保存下来了,不可能因为任何原因再回到原来的状态。那么 MySQL 是如何保证一致性的呢?最简单的做法是在每次事务提交的时候,将该事务涉及修改的数据页全部刷新到磁盘中。但是这么做会有严重的性能问题,主要体现在两个方面:

  • 因为 Innodb 是以页为单位进行磁盘交互的,而一个事务很可能只修改一个数据页里面的几个字节,这个时候将完整的数据页刷到磁盘的话,太浪费资源了。
  • 一个事务可能涉及修改多个数据页,并且这些数据页在物理上并不连续,使用随机 IO 写入性能太差。

????????因此 MySQL 设计了?redo log?,具体来说就是只记录事务对数据页做了哪些修改,这样就能完美地解决性能问题了(相对而言文件更小并且是顺序IO)。

????????redo log 包括两部分:一个是内存中的日志缓冲(redo log buffer),另一个是磁盘上的日志文件(redo log file)。MySQL 每执行一条 DML 语句,先将记录写入 redo log buffer ,后续某个时间点再一次性将多个操作记录写到 redo log file 。

????????默认情况下,redo log 在磁盘上由名为?ib_logfile0?和?ib_logfile1?的两个物理文件展示。redo log 相关参数简单介绍如下:

  • innodb_log_files_in_group:redo log 文件的个数,命名方式如:ib_logfile0,iblogfile1... iblogfilen。默认2个,最大100个。
  • innodb_log_file_size:单个 redo log 文件设置大小,默认值为 48M,最大值为512G,注意最大值指的是整个 redo log 系列文件之和,即(innodb_log_files_in_group * innodb_log_file_size )不能大于最大值512G。
  • innodb_log_group_home_dir:指定 redo log 文件组所在的路径,默认./ ,表示在数据库的数据目录下。
  • innodb_log_buffer_size:redo log buffer 大小,默认16M。延迟事务日志写入磁盘,把 redo log 放到该缓冲区,然后根据 innodb_flush_log_at_trx_commit 参数的设置,再把日志从 buffer 中 flush 到磁盘中。
  • innodb_flush_log_at_trx_commit:控制 redo log 刷新到磁盘的策略,默认为1。值为1,每次 commit 都会把 redo log 从 redo log buffer 写入到 system ,并 fsync 刷新到磁盘文件中。值为2,每次事务提交时 MySQL 会把日志从 redo log buffer 写入到 system ,但只写入到 file system buffer,由系统内部来 fsync 到磁盘文件。如果数据库实例 crash ,不会丢失 redo log,但是如果服务器 crash,由于 file system buffer 还来不及 fsync 到磁盘文件,所以会丢失这一部分的数据。值为0,表示事务提交时不进行写入 redo log 操作,这个操作仅在 master thread 中完成,而在 master thread 中每1秒进行一次重做日志的 fsync 操作,因此实例 crash 最多丢失1秒钟内的事务。

????????更改 redo log 及其 buffer 大小是需要重启数据库实例的,建议初始化时做好评估。可以适当加大 redo log 组数和大小,特别是你的数据库实例更新比较频繁的情况下。但也不推荐 redo log 设置过大。

JDK中Corba的备忘录模式

????????参考一下Corba的类,FragmentableStreamMemento是对FragmentableStream流进行备份,备份就有create和restore,很清晰。

 private class FragmentableStreamMemento extends StreamMemento
    {
        private int fragmentOffset_;

        public FragmentableStreamMemento()
        {
            super();

            fragmentOffset_ = fragmentOffset;
        }
    }

    public java.lang.Object createStreamMemento() {
        return new FragmentableStreamMemento();
    }

    public void restoreInternalState(java.lang.Object streamMemento)
    {
        super.restoreInternalState(streamMemento);

        fragmentOffset
            = ((FragmentableStreamMemento)streamMemento).fragmentOffset_;
    }

使用场景

  • ?必须保存一个对象在某一个时刻的( 部分) 状态,? 这样以后需要时它才能恢复到先前的状态。

  • 如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

优缺点对比

优点

  • 在同一个集合上中可有多个状态一起工作。
  • 它不需要为支持迭代而破坏一个集合的封装性。备忘录仅由集合自身来解释; 任何其他对象都不能访问它。支持迭代的其他方法要求将迭代器类作为它们的集合类的友元, 从而破坏了封装性。这一情况在基于备忘录的实现中不再存在,此时Collection是IteratorState的一个友元。

缺点

  • 存储和恢复可能很费时

参考资料

设计模式之禅

Gof设计模式:可复用面向对象软件的基础 典藏版

Head_First设计模式

MySQL redo与undo日志解析

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-09-09 11:50:45  更:2021-09-09 11:52:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:38:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码