3.1 缓存定义
缓存是计算机领域非常重要的一个概念,它是介于应用程序和永久性的存储系统(比如数据库,文件系统等)之间一种媒介。缓存降低了应用程序对持久性数据源的访问,从而使得应用程序具有更好的性能。
3.2 缓存种类
3.2.1 按照缓存中的元素划分
缓存按照缓存中存储的内容来划分可以划分为:
数据缓存(比如数据库中内置的缓存)
文件缓存(比如文件系统的缓存,浏览器的缓存js,css文件等)
对象缓存
对象缓存是这次交流的重点,采用了DDD以后,系统会有一个完整的领域模型,这个领域模型一般目前都是通过对象模型来实现的,那么这个对象模型的就要用到对象缓存了。
4) 其它缓存(比如CPU内部的高速缓存等等)
3.2.2 按照缓存和应用程序的耦合度划分
Local Cache
Local Cache是指应用程序与缓存运行在统一进程中,比如目前J2EE界流行的OScache,Ehcache,jbosscache等。这一类型的缓存离应用程序近,因此效果也比较好,但是无法应对分布式和集群情况下的缓存要求,因为local Cache多数都是采用了广播机制来对各个节点进行更新,这样在集群环境下,当节点个数比较多的时候,广播通信就会对系统带来很大的开销,甚至这种开销抵消了缓存带来的性能方面的提升。
Remote Cache
Remote Cache是指应用程序与缓存运行在不同的进程中,这种类型的缓存的代表是著名的Memcached,Remote Cache是一种分布式和集群级别的缓存,这种情况下,应用程序一般通过缓存系统的协议与缓存系统进行交互。
3.2.3 按照缓存的生命周期划分
按照缓存的生命周期来划分,缓存可以分为以下几种类型:
Request或者事务级别
Request级别的缓存一般存在于单个的Request生命周期里面,当一个Request结束的时候,缓存也就消失了。Request级别的缓存的代表是Hibernate的一级缓存。Request级别的缓存也可以叫作事务级别的,因为每次事务结束的时候,缓存也随之消失。
Session级别
Session级别的缓存一般是扩展到了整个Session期间,它存活于整个Session周期中,当Session结束时,Session级别的缓存也随之结束。这方面的缓存比如Httpsession或者Statefull session bean 扩展持久化上下文。
Application级别
Application级别的缓存存在一个整个Application的生命周期之中,当应用程序启动的时候,缓存生命周期开始,当应用程序结束的时候,缓存的生命周期结束。
在采用了DDD建模以后形成了领域模型,这个领域模型需要缓存,此时主要是指Applicaiton级别的缓存,是整个应用程序级别的缓存。
3.3 缓存的清除策略
当缓存中的元素超过缓存的限制的时候,缓存系统就会采用一定的缓存策略将缓存中的元素从缓存中移除,缓存的清除策略主要有以下3种:
FIFO (First In First Out)
这种缓存策略表示当缓存清除缓存元素的时候,缓存系统会清除在缓存中时间最长的元素。
LRU (Least Recently Use)
这种缓存策略表示当缓存清除缓存元素的时候,缓存系统首先清除最近最少使用的元素,这种情况下,一般缓存元素都会有一个时间戳,缓存系统会选择清除时间戳离当前时间最远的元素。
LFU (Less Frequently Use)
这种缓存策略表示当缓存清除缓存元素的时候,缓存系统首先选择缓存中一直以来最少使用的元素,这种情况下,缓存元素一般都会有个hits属性,每次命中以后,hits都会加一,当要清除的时候,缓存系统选择hits最小的元素清除。
在选择缓存清除策略的时候,我们根据当前业务系统的特点来进行选择,每一种缓存清除策略都有它自己的优点。一般情况下推荐使用LRU。
4 领域模型和缓存如何配合?
4.1 对底层缓存系统进行封装
采用DDD建模和缓存以后,首先我们面临的问题就是如何对缓存系统进行封装的问题,因为缓存系统是一种技术的时候,同时也有好多种选择,我们不能让领域模型依赖于具体的缓存技术,这个时候就需要进行缓存的封装。而在本次CBB LPQ的设计中,我们的团队也对底层缓存系统进行了封装,具体在封装的时候,我们可以通过图4-1所示的方式进行封装:
图4-1 Cache 类图
4.2 提供统一的缓存入口
在系统中引入缓存之后,我们需要提供一个统一的缓存入口,系统的其它部分要想通过缓存来获取领域对象都必须通过统一的缓存入口。通过提供统一的缓存入口使得缓存的管理更加方面。如果不提供一个统一的缓存入口,这样整个缓存的逻辑就散落在了系统的不同部分,这样维护起来就比较麻烦。
4.2 Factory与Cache的结合
采用DDD建模以后,系统中会形成很多领域对象,当需要创建一个领域对象的时候,因为领域对象涉及到很多状态,要构建一个状态非常多的领域对象非常复杂,因此有必要通过工厂来封装,在工厂创建领域对象的时候,因为领域对象聚合了很多的子对象,同时还关联了了其它的聚合根对象,因此当创建一个聚合根的时候,当需要另外的领域对象的时候,首先从缓存中取,如果有就直接返回,没有再查询DB获取,最终形成一个完整的领域对象返回。举个例子,比如创建一个论坛帖子的时候,我们需要获得是谁发帖子,因此在创建帖子的时候,我们需要得到Account(用户)对象,而此时就需要首先从缓存中获取Account对象,如果存在就直接返回,不存在再查数据库。
5 领域模型和缓存总结
经过领域建模以后,系统形成了良好的领域模型,在这个领域模型真正与架构融合,并且跑起来之后,领域模型需要一个生存的场所,领域模型需要在这个生存的场所里面完成它的生命周期,这个生存场所就是缓存。领域模型+缓存是一种面向业务的分析、设计和面向业务的存储结合的结果,这种结合的结果就是能方便的进行面向业务的内存计算。
目前key-value存储系统正处在不断的快速发展过程当中,等以后key-value存储系统真正普及以后,我们可以通过key-value存储系统来作为领域模型的生存场所,这样整个系统也将完全是一种:面向业务分析、设计,面向业务的存储,面向业务内存计算的结合体,这将是非常完美的一个新世界。
5.1 Scalability(伸缩性)
通过将领域模型放入缓存,使得领域模型能够真正的以业务形态存在于内存中,能真正以业务形态进行内存的运算,这样以来,系统负载增多的时候,我们可以采用分布式和集群级别的缓存,这样就增强了系统的水平伸缩性。如果采用传统的那种方式,大部分业务逻辑都与数据耦合,这样当系统负载增多时候,数据库就成为了最不具伸缩性的一层。5.2 Performance(性能)
这也是Hibernate创始人所描述的:数据库成为了大多数企业应用的主要瓶颈,也成为了运行环境中最不具伸缩性的层。
系统性能方面,因为引入了缓存,这样当每次用户请求来的时候,系统将用更少的时间来完成对用户请求的响应,这样也将提高性能“多快”的方面,同时因为通过缓存降低了对数据库的压力,从而使得系统能应对更多的访问量,这也就增加性能“多大”的方面。同时在性能“多大”方面,通过引入分布式和集群缓存,甚至是引入key-value存储系统,我们的系统能平滑的过渡到一种分布式和集群环境中,这样也使得系统能应对更大负载,从而提升了性能“多大”的方面。
四 总结
采用DDD以后,系统形成了完整的领域模型,这个领域模型已经如实的反映了我们领域的实质,这样领域模型的可扩展性,可维护性和可复用性就非常高,而通过将领域模型和缓存结合以后,整个系统变成了一种:面向业务分析、设计,面向业务的存储和面向业务运算结合的一种更加具有良好性能表现和伸缩性的系统。
因此领域模型和缓存使得系统在可扩展性,可维护下,可复用性,可伸缩性以及性能方面都有良好的改进和提高。
结论:
1. 软件不是计算工具,软件帮助人们解决某一领域的复杂问题
2. 软件的核心是领域模型,而不是技术
3. 领域模型是一种面向业务的模型
4. 领域模型更加忠实地反映了软件实质
5. 领域模型+缓存=面向业务的分析和设计+面向业务的存储
6. 领域模型+RDBMS=面向业务的分析和设计+面向关系的存储,不匹配,矛盾!
7. 领域模型使得系统在满足功能的同时,具有可扩展性,可 维护性,可复用性
8. 领域模型和缓存使得系统具有更好的伸缩性和性能
9. 领域模型使得系统天然的具有功能性和非功能性的血统
10.领域模型和架构的关系:分析设计的时候领域模型独立于架构,而实现的时候,领域模型和架构粘合,真正运行的时候,领域模型和架构完全统一(是不是类似于EJB中,编程时分离,部署时粘合,运行时真正统一的思想)
相关推荐
采用领域驱动的开发方式,最终系统形成了一个通用的模型,这个模型是完全面向业务的,这个模型是业务人员和开发人员都能容易理解的,同时这个模型也是如实的反映了领域实质的,这样以来软件不是依赖于某种技术,同一...
9.3 动机:为什么要创建领域模型 9.4 准则:如何创建领域模型 9.5 准则:如何找到概念类 9.6 示例:寻找和描绘概念类 9.7 准则:敏捷建模—类图的草呼 9.8 准则:敏捷建模—是否要使用工具维护模型 9.9 准则:...
9.3 动机:为什么要创建领域模型 9.4 准则:如何创建领域模型 9.5 准则:如何找到概念类 9.6 示例:寻找和描绘概念类 9.7 准则:敏捷建模—类图的草呼 9.8 准则:敏捷建模—是否要使用工具维护模型 9.9 准则:...
GPT模型作为近年来自然语言处理领域的热门技术之一,其应用范围越来越广泛。然而,由于模型参数庞大,训练时间长,因此如何提高模型的训练效率成为了研究人员关注的重点。本文将介绍Cerebras公司的权重流架构,以及...
9.3 动机:为什么要创建领域模型 9.4 准则:如何创建领域模型 9.5 准则:如何找到概念类 9.6 示例:寻找和描绘概念类 9.7 准则:敏捷建模—类图的草呼 9.8 准则:敏捷建模—是否要使用工具维护模型 9.9 准则:...
9.3 动机:为什么要创建领域模型 9.4 准则:如何创建领域模型 9.5 准则:如何找到概念类 9.6 示例:寻找和描绘概念类 9.7 准则:敏捷建模—类图的草呼 9.8 准则:敏捷建模—是否要使用工具维护模型 9.9 准则:...
9.3 动机:为什么要创建领域模型 9.4 准则:如何创建领域模型 9.5 准则:如何找到概念类 9.6 示例:寻找和描绘概念类 9.7 准则:敏捷建模—类图的草呼 9.8 准则:敏捷建模—是否要使用工具维护模型 9.9 准则:...
9.3 动机:为什么要创建领域模型 9.4 准则:如何创建领域模型 9.5 准则:如何找到概念类 9.6 示例:寻找和描绘概念类 9.7 准则:敏捷建模—类图的草呼 9.8 准则:敏捷建模—是否要使用工具维护模型 9.9 准则:...
9.3 动机:为什么要创建领域模型 9.4 准则:如何创建领域模型 9.5 准则:如何找到概念类 9.6 示例:寻找和描绘概念类 9.7 准则:敏捷建模—类图的草呼 9.8 准则:敏捷建模—是否要使用工具维护模型 9.9 准则:...
9.3 动机:为什么要创建领域模型 9.4 准则:如何创建领域模型 9.5 准则:如何找到概念类 9.6 示例:寻找和描绘概念类 9.7 准则:敏捷建模—类图的草呼 9.8 准则:敏捷建模—是否要使用工具维护模型 9.9 准则:...
发明BSD、TCP/IP、csh、vi和NFS的SUN首席科学家Bill Joy说过,在计算机体系结构领域里,缓存是唯一称得上伟大的思想的。其他的一切发明和技术不过是在不同场景下应用这一思想而已。在计算机软件领域里,情形也大体...
Spring框架是Java开发领域中最受欢迎的开源框架之一,它提供了一套全面的编程和配置模型,用于开发可维护的应用程序。通过依赖注入(DI)和面向切面编程(AOP)的核心特性,Spring帮助开发者实现业务逻辑与底层技术...
4.3.1 Ricart和Agrawala的第二个算法 4.3.2 一个简单的基于令牌环的算法 4.3.3 一个基于令牌环的容错算法 4.3.4 基于令牌的使用其他逻辑结构的 互斥 4.4 选举 4.4.1 Chang和Roberts的算法 4.4.2 非基于比较的...
我们同时也研究一些领域模型及数据库关联的代码生成和自动维护模式。紧接着我们还研究了如何通过NHibernate解决传统的数据库的集合键和触发器。 第十章提供了更多现实的应用。我们通过一个简单应用,将它转换成为一...
第3章 领域模型和元数据 3.1 CaveatEmptor应用程序 3.1.1 分析业务领域 3.1.2 CaveatEmptor领域模型 3.2 实现领域模型 3.2.1 处理关注点渗漏 3.2.2 透明和自动持久化 3.2.3 编写POJO...
1.2 完全采用面向对象思想设计的业务领域模型 4 1.3 采用工作流引擎技术的业务流程模型 5 2 灵活的适应能力 7 2.1 支持多平台 7 2.2 支持多种后台数据库 8 2.3 支持多种客户端类型 8 3 强大的二次开发能力 9 3.1 ...