1.软件系统在设计过程中要注意考虑哪些问题?-八维教育

高性能软件系统设计中应当考虑的问题

高性能软件系统都是应用于大用户量,超大数据量处理的情况下,这样的软件系统并不好设计,这儿主要述说一下对于高性能软件系统在设计过程中要注意考虑什么问题。

1.显存的使用

栈:

在高性能软件设计时,因为处的的数据量大且复杂。所以会大量的使用多线程技术。一个进程的线程数有可能达到几千或是上万。而每位线程就会有自己的线程线来保存局部变量和函数调用的信息。因为线程数之多,而总的显存空间又是有限的。平均出来每位线程的栈空间就少的可怜了。所以在使用栈空间时就要考虑怎样合理的使用了,不然还会发生栈数据越界的严重问题。在此时使用局部变量时就要慎重些了。1.尽量避开使用超大的局部数据变量。2.要注意函数调用的数组数据宽度和数目。3.要注意函数调用的深度,由于涵数调用的越深,压栈的数据也就越多。4.要慎重使用递归函数(递归算法),控制好递归的深度,或是用别的算法来替代递归算法。

堆:

堆空间是通过new(malloc)和delete(free)方式进行申请和释放的。堆空间可以拿来储存比较大的数据信息。但在多线程的程序中,堆空间的管理是间很大的麻烦事。分配到的堆空间哪些时侯用,有什么线程会在哪些时侯用到,在哪些时侯用完,哪些时侯才会释放。这种问题不解决好,会出现好多问题。例如其中一个线程过早释放,而另外的线程又在使用,或是用完了没有释放(显存泄露)等严重问题。针对这种问题,最好是能设计一个显存管理器来专门管理堆空间的显存分配与回收。其它所有的模块或线程要得到堆空间时都通过显存管理器获取,也由显存管理器决定哪些时侯进行释放。这样即可以解决堆空间管理混乱的问题,能够增强程序效率,由于可以通过显存管理器重复使用同一块堆空间,而毋须频繁的分配和释放显存,还有一点也十分得要,就是发生显存操作错误或是显存泄露之后也可以通过显存管理器的一些信息快速的找到问题的所在。最简单的一种显存管理器就是采用引用记数的方法。就是当通过显存管理器分配到一块资源后对该显存块资源的合用标记加一,之后每每一个模块使用一次该资源就加一,用完后就减一,当减到为零时,由显存管理器去决定重复借助还是释放。通过个简单的方式可以实现一个相对简单且实用的显存管理器。显存管理器的方式多种多样,具体要如何设计要看具体的情况。

2.多线程管理

创建线程池管理器:

一个进程当中有各类功能的线程,每一种功能的线程似乎有好多个。线程的种类和数目之多,这对线程的管理与监控来说是件麻烦的事情。在这些情况下应该设计线程池管理器,专门来创建分配线程资源,回收释放线程资源,监控管理线程,控制线程数目等方面的工作,也同时多次复用线程资源,防止重复的创建和释放线程,增强系统整体效率。对不同功能类的线程应该分配一个独立的线程池。这样便捷不同功能类型的线程个自特点的管理。

怎样决定线程的数目:

一个进程当中并不是线程越多越好,由于线程越多消耗的资源也越多。并且加上线程间频繁的切换会影响效率。那怎么来确定线程数目多少合适呢?通常来说每位CPU核分配两个线程比较合适,但这些方式不太科学,比较片面。最好的方式是要依照不同功能的线程来进行考虑。例如一个线程专门用于网路操作的,这么该类型线程的数目就决定网路带宽,和网卡IO的情况了,这时每位线程发出一个网路动作恳求后,因为网路的廷迟和网路设备IO的限制需要等待比较长的时间,此时会步入睡眠状态。这么因为这些线程在工作时大部分时间处于睡眠状态,所以可以多开几个线程,以更好的借助CPU和其它计算机设备的资源。再例如现今是一种纯数据运算的线程,它只应用到CPU和显存的资料,没有其它IO操作。这种类型的线程数目主要考虑CPU和显存的参数性能。可能不太适宜过多数目的线程,由于过多的线程会导致频繁的切换,反倒效率下滑。再例如一个专门用于操作数据库的线程,那就要考虑你所用的数据库系统了,若果只有一个数据库,这么就在同一时间最多分配一个线程比较合适了,由于太多的线程同时去操作同一个数据库,因为数据库本身须要不断切换联接用户和数据库内部的一些操作的切换,反倒影响了数据库工作的性能。所以说不同功能的线程要看具体这个线程完成哪些工作,要用到什么其它资源,再来决定该类线程的数目。

3.资源的分配与管理

在多线程程序中有个很急手的问题,就是资源访问控制。倘若没处理好资源访闾控制,那都会导致死锁或冻死的现象。在普通的多线程程序设计中可以通过互斥体,讯号量,载流子锁等方式可以控制,但在高性能程序设计,因为线程数目之多,关系复杂,假如只靠简单这种方式可能很难解决资源访问控制问题。非常有些线程在自己的深度死锁问题(深度死锁就是一个线程得到一个资源后对该资源进行了上锁,但在后续的操作当中,因为逻辑复杂,函数调用太深,在某处再度对该资源获取操作权,但在上面他自己把这个资源上了锁还没解锁,再度尝试获取操作权时导致失败的问题)。在针对那些情况下,就须要设计一个资源分配管理器来进行资源的分配和管理了。当一个线程须要访问某个资源时都须要通过个资源分配器来获得操作权。资源分配器记录着什么资源如今是那个线程在访问,有什么线程须要访问什么线程,由资源分配管理器来决定那些线程谁将先获得什么资源的访问权。资源分配管理器还记录着资源被什么线程所使用过的时间有多长,通过合理的调配,让优先级比较低的线程也能得到资源的访问权,不至于冻死。

4.数据的储存

数据储存问题是高性能系统设计中所避开不了的。假如这儿没做好,会严重影响系统的整体性能。好多数据的储存都是传统的关系型数据库。所以在设计数据库时考虑好多的问题,例如表关系设计是否设计合理,对数据量大的表进行分表或表分区储存,对表数据构建合理的索引,通过多种索引联合检索的方法来提升查询效率,考虑表锁和表行锁的影响,储存过程设计的合理问题,还有就是开启数据库的cache功能设计算法时需要考虑,数据库集群,分布式数据库都是须要考虑的问题。

不仅这种,你最重要的一点就是还要考虑数据的关系。现今的数据库系统是表关系型数据,假如你的数据是树关系或是图关系的,那你得考虑传统数据库时否适宜了,由于表关系型数据库对保存树关系或是图关系这种的数据是相当难的,会靠成数据大量冗余或是检索上去相当难。在这个时候你就不能依赖于现有的数据库系统了,你得按照数据关系的实际情况来设计适宜的储存结构模块和数据检索模块了。

5.缓存的应用

好多情况下,数据储存的性能困局并不是在数据储存系统上,而是在储存设备上,你们都晓得外储存器(硬碟,FLASH)的速率比CPU和显存的速率可不是几倍或是几十倍的差别,那是好几个数目级的差别。在这时侯才会出现数据储存和数据检索上的性能困局了,非常是数据检索。在这些情况下我们就得在数据操作层和数据储存层之间加一个缓存层了。通过合理的设计把数据索引和访问频度高的数据常驻显存。这样能够大量提升数据储存和数据检索的性能。缓存层的设计最好是能达到透明,对上下两层的工作不会有影响。

6.集群,分布式与负载均衡

高性能系统都是处理超大数据量信息的,而单台计算机的性能其实是有限的。所以在做高性能系统设计的时侯就不得不考虑通过集群,分布式与负责均衡的方式来提升整体的处理能力。整个系统有各类不同功能的模块组成。针对不同的功能模块可以设计成一个独立的进程,例如一个进程专门用于网路的操作,另一个专门负责数据的运算或专门用于数据的储存,而同一功能的进程又可以分布在多台的机器上运行,把那些计算机通过网路连在一起产生一个统一的系统。为何要这样设计呢?很简单,由于每位模块进程的功能不同,对设备资源的要求也不同,如操作网路的模块进程主要是对网路的要求要高,这样的话就让这些进程运行成一组网路配置比较高的计算机上,而另外一个专门用于数据运算的模块进程则对CPU和显存的要求比较高,那我们就可以让它运行在一组CPU和显存配置比较高的计算机上。这样即能节约成本又能增强系统整体的性能,并且可以针对某个功能模块实际须要的运算量来降低和降低相关的计算机设备。在这些设计当中,我们就要考虑同一功能模块间多个进程的任务分配(这儿还要考虑负载均衡等问题),工作协调等问题,在这时可以通过集中控制或是进程间互相间自我协调的方法进行控制。在不同功能模块进程间的工作协调也要进行集中和互相间自我的控制。这也降低了系统整体的复杂度,这儿最好是设计一个专门的监控与控制管理器来管理整个系统的工作。

7.可靠性与安全性

这些高性能系统都须要长时间稳定的对外提供服务。所以在设计中可靠性和安全性是必须考虑的问题。在这儿须要考虑整个系统中当一个进程或机器出现问题不能工作时,其它相同的进程或机器能不能及时接管其没有完成的工作,出现问题的进程或机器能不能快速的恢复。当遇见一些不可预知的问题或外部功击时,原始数据被破坏时,能不能快速的恢复。那些都是可靠性的表现。这儿可以通过功能模块冗余设计,模块或进程实时的监控来快速发觉问题,通过让其它进程及时的接管工作或让其快速的自我恢复。还有就是要设计数据镜像的实时备份等功能来提高系统的可靠性。

整个系统是运行在多台计算机上,当中通过网路过行数据的交换和控制。当系统遭受恶意功击时可能让系统未能正常的工作,或是泄露系统中重要的信息施行其它的恶意行为。那些在设计时也要考虑。我们可以通过对系统网路中的交换的数据进行加密,对系统重要的配置信息进行加密后再保存。在系统内部数据交换或是系统控制等合同设计上要严谨,以免出现严重的漏洞让人恶意借助。通过这种一系统的方式来提升系统的安全性。

8.后续的优化和构建

系统开发完成后放到机器上运行即使大功告成了吗?似乎还差很远。像这样的高性能系统很难做到一步设计到位的。好多问题在运行后才能曝露下来,虽然你很有经验也一样。例如个别算法的设计是否合理,达到了性能要求。个别数据的处理方式是不是正确的。个别功能的设计是否合理。那些都可能在系统运行后才会发觉。当一个算法达不到要求时,我们就得优先它,重画算法。个别模块对数据的处理流程并不合理,我们要构建它。由于个别需求有所改动或功能设计的不合理,我们要对该模块进行重新设计。这种工作都是须要的。为了解决这种问题,我们在设计系统时就要做好打算,尽量做到系统的可扩充性好,模块可构建性高。由于后期的算法优化,模块构建或降低新的功能可能会对系统影响很大。所以设计时须要注意一些问题。尽量做到模块间耦合度低,互相依赖小,模块间插口明晰。可以考虑模块插件式的设计方式,这样在后期对模块进行更换,降低时不会影响到相领的模块。在详尽设计时应用好设计模式(设计模式千变万化,不能按书的硬套),增强代码的复用率设计算法时需要考虑,降低代码冗余,代码功能扩充性好。考虑算法与数据结构分,这样当更换算法时不用改变数据的结构。这种方式都可以降低系统的灵活性和便捷后期的优化。还有一点也十分重要,那就是文档的管理,构架文档,算法文档,插口文档等一系列的设计文档。这种也是在后期进行优化和构建的重要信息。

在设计这种复杂性高的高性能软件系统还有好多东西要考虑,这儿只提到了一小部份的介绍,要设计好这样的系统还须要更进一步的学习和总结。

© 版权声明
THE END
喜欢就支持一下吧
点赞267 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片