公司已经有一套运行多年的信息系统。已经积累了三年左右的数据。
数据库使用oracle。系统开发由于赶进度,开发时使用了堆字段,各种关联的方式来设计。
经常出现了5百行以上的SQL语句,经常系统性能不佳,用户报怨系统卡与慢。
经过分析,有多个SQL语句经常超过20秒钟,并且一些批量的操作,会让oracle假死。
由此不得不重启数据库,以便恢复系统正常。
细化分析后,发现直接堆代码的地方实在太多,基本业务逻辑都放在数据库中操作。
很多复杂的业务逻辑基本放在数据库当中操作。
程序则反而比较简单,大量的业务都是放在sql语句中去实现。
这里表现的性能瓶颈很明显,基本90%的时间都是在数据库中,而web系统的资源基本都是空闲的。
因于类似的代码超过上万行,一一修改的可能性比较多,修改后会引起各种新的缺陷。
因此通过修改代码来得升性能的可能性很低。
分析出来的一些性能较差的结论:
1)业务逻辑大量写在SQL语句,压力集中在数据库;
2)业务逻辑复杂,代码之间关联比较多,代码难以修改优化;
3)基本没有使用索引,查询效率极差;
4)日志数据写在数据库中;
5)查询输出的字段多,每个查询平均输出超过50个字段;
6)关键表的字段超出400个,已经无法再维护表结构;
7)使用oracle数据库,维护操作空间较少;
特征:
8)总数据量并非很大,整个数据库(三年数据,包括所有请求日志)不超50G
解决思路:
1.改代码
方法:将性能比较差的请求找出来,然后将sql语句分离,一些业务相关逻辑放在程序当中去处理。
数据库仅做简单的查询与插入,修改操作。
问题:开发成本比较高,需要修改比较多的代码,修改时间比较度,经常引起其他缺陷。
优化的情况不明显,输出的字段还是比较多。
结论:花时间太长。
2.做集群
做集群技术能力不足,资料比较少。
需要请oracle相关的人过来。
结论:提升的效果不明显,或者说基本没有效果。
3.堆硬件
数据库服务器加大内存;
将磁盘换成SSD,做RAID 10;
结论:测试后性能提升很大,许多消耗40秒左右的变成10秒钟左右。
4.堆硬件+软件处理
由于增加硬件后,性能提升非常有效,因此往这个方面走得更进一步。
发现内存增加对性能的提升基本推近于零。
磁盘的改进,特别将SSD换上去后,性能才有明显的提升。
因此,需要有比SSD更强大的东西来替代。此时,我直接是想到了内存。
现在内存比较便宜,我想到组建一个内存盘。
通过将内存虚拟成磁盘,一般称为RamDisk,然后将数据库数据放入RamDisk。
此时一般会担心有数据安全的问题,这个问题是有解决方案的,可以稍后讨论。
结论:估计性能会有质的提升,需要解决数据安全问题。
关键不需要修改任何原来业务的逻辑代码。决定走这一步。
测试阶段1:
测试目标:将数据库的表空间文件放入RamDisk,查询复杂的语句,取得与常规的SSD相关性能差异量。
准备流程:
1.建立一个32G的RamDisk磁盘。
2.将oracle安装到RamDisk中。
3.建立表空间文件,将文件位置放入RamDisk中。
4.导入生产环境数据库,将此数据库命名为ramDb。
5.找出系统查询最慢的SQL语句,将此业务名为slowJob1,仅查询。
执行SQL流程:
在生产环境数据库执行slowJob1语句,输出20w左右的数据,用时40s。
在RamDB数据库执行此语句,输了内容相同,则用时1s。
简单结论:
起码使用RamDisk的方式可以有效提高查询效率。查询结果无异。
思考:
由于内存的读写效率与磁盘的读写效率差异有10倍之大,基本可以忽略了数据读取性能的相关问题。
理应多复杂的查询,多复杂的数据读取,都基本不需要考虑磁盘性能带来的影响。
目前唯一需要考虑更多的就是数据容量与安全问题。
数据容量问题:
由于三年的数据都不超过50G,然而50G中有20G的日志数据,也就是业务数据30g。
以6年的设计,则数据量则约为30*2=60G,也就将RamDisk设计到64G就可以应付6年的数据量。
128G的空间则可以支撑10年。
数据安全的思考:
由于内存存在断电数据丢失风险,则需要将数据存入可靠的磁盘中。
读写分离是一个较好的解决方案。
写入数据时,则写入内存块与磁盘块。读时仅读内存块。
此逻辑下,有几种模式:
1)安全型:安全写入磁盘后,完成操作。
2)性能型:写入内存后则返回,异步写入磁盘。
第一种写入性能较慢,第二种则快,不过有数据丢失的风险。
两种可以视情况而决定,没有统一的解决方案。
当前项目中,写操作次数远远小于读取,而写入内容并不高,在使用SSD+Raid10下,性能已经够和。
则会选择安全型。
方案的实现:
一,简易快速方案
服务器64G内存,SSD250G raid 10;
使用windows 2008;
使用魔方内存盘,设定54g内存;
虚拟内存设置在ramdisk上;
安装oracle, oracle data文件夹设置在ramdisk上;
建库,将表空间设置在ramdisk上;
风险:软件不够稳定,魔方稳定性比较差,1个月基本会挂一次。
数据不够安全,需要手功去将内存数据存入磁盘中。
二,基于linux模块实现
服务器64G内存,SSD250G raid 10;
安装centos 6.5;
安装RamDisk模块(需要开发,另行编写文章介绍);
RamDisk空间设置大小为54G;
配置RamDisk中的映射文件于/home/oracle/ram.img,写同步模式;
安装RamDisk模块后会出现/dev/ramdisk设备
mkfs.ext4 /dev/ramdisk
mkdir /home/oracle/ramdisk
mount /dev/ramdisk /home/oracle/ramdisk
安装oracle, oracle data文件夹设置在ramdisk上;
建库,将表空间设置在ramdisk上;
RamDisk模块要监测ramdisk所有写入操作,将数据同步到/home/oracle/ram.img
重启系统时,会自动将/home/oracle/ram.img同步入/dev/ramdisk中;
好处:数据安全,读取数据性能提升明显。
风险:维护操作相对复杂,需要开发RamDisk模块。