InnoDB列压缩,提升DB性能
来源:互联网 发布:java io 装饰器模式 编辑:程序博客网 时间:2024/04/27 11:45
腾讯游戏的后台数据库一直守护着亿万玩家的数据,提供着稳定透明的服务。
腾讯后台数据库大部分使用的是MySQL数据库,现已大部分被替换为互娱DBA团队自己定制的TMySQL。IO问题是传统关系型数据库中最热门话题,互娱DBA团队在业务运营过程中同样遇到类似问题。
案例一:IO问题。某游戏的一个大区DB由于数据量过大,内存缓冲池不能完全cache数据,IO瓶颈制约DB整体性能,导致该大区不能提供稳定服务。
案例二:存储空间不足。某游戏的DB在合服过程中,由于数据量过大,导致合服效率极低。
对于上述问题,通用的方案或者是升级硬件,或者是在游戏server层修改存储逻辑,代价都很非常大。互娱DBA团队通过在TMySQL 1.4版本增加InnoDB列压缩功能,对应用层透明并且节省了硬件成本从而有效解决该问题。
列压缩技术方案与应用
互娱游戏的后台数据库经常使用blob/text类型字段来存储数据,业务中blob/text类型字段占据了很大部分的存储空间,如上述提到的案例二中DB中约90%的存储内容为blob/text类型列。对这些blob/text字段进行压缩存储,将大大降低存储空间,从而提高DB整体性能。
一、列压缩技术方案
TMySQL列压缩的实现主要包括语法层面、存储格式、压缩/解压逻辑及导入导出优化等几个方面。
1. 列压缩功能是可配置的,为此在TMySQL中增加compressed语法。
2. 存储格式:列压缩可以根据字段的长度来判断是否使用压缩存储,因为对于小数据量,压缩比不压缩可能更占用存储空间。目前,判断是否压缩的策略是:如果长度小于256字节,不压缩存储;如果长度大于256字节,压缩存储。压缩格式为:
首字节标记:第一个bit,0表示未压缩(对应就无解压后长度),1表示压缩;第2,3位表示算法类型(现阶段版本只有zlib算法),第6,7,8位表示有几个字节来存储压缩长度。
解压后长度:表示数据在压缩前或解压“压缩的内容”的长度,由于BLOB字段约定的最大长度(longblob)是2^32-1,因此4字节的最大长度已经足够。另外,1-4字节的内容分别表示长度上限为2^8-1、2^16-1、2^24-1,2^32-1。该信息也用于解压后的内存分配。
压缩的内容:就是压缩后的数据。
3. 压缩算法
当前版本,压缩和解压基于mysql内置的zlib(1.2.3)压缩库,函数为:my_compress和my_uncompress。
上述定义的格式中,预留了其它类型的算法标记,后续会结合不同压缩算法中cpu开销与压缩率来权衡一种更适当的算法。
4. 压缩与解压
压缩和解压处理需要在统一的函数调用位置,该位置确定在存储引擎和server数据交换的handler接口中,即
- Server层从存储引擎获取数据前,存储引擎负责解压。
- Server层要存储数据,需要把数据压缩处理。
这样解压和压缩都集中在存储引擎和server间的数据交换接口中,存储引擎和SERVER的其他处理就不需考虑数据是否压缩的逻辑,简化整个问题。
压缩接口:row_mysql_store_col_in_innobase_format。由server层传下来的每一个列的数据,都会经由本函数完成数据转换(特殊处理索引)。
解压接口:row_sel_store_mysql_rec。本函数用于将InnoDB层从物理介质上读取到的数据传递到server层的类型。
5. 导入导出优化
导入导出优化主要是通过两方面来实现。首先是在server层增加新的语法SELECT SQL_COMPRESSED 、INSERT SQL_COMPRESSED。在使用SELECTSQL_COMPRESSED时,DB会略过对压缩数据的解压逻辑,直接导出。
INSERT SQL_COMPRESSED与SELECT SQL_COMPRESSED必须是配套使用的,使用INSERT SQL_COMPRESSED略过压缩逻辑直接存储数据。
其次是通过实现tmysqldump使用SELECT SQL_COMPRESSED语法来获取数据内容,在生成SQL语句时使用对符合条件的SQL使用INSERT SQL_COMPRESSED这种语法。
二、列压缩的应用
1. 配置列的压缩属性
在建表时语句指定blob/text类型的列具有compressed属性,这样该列的内容会被压缩存储
支持compressed属性的列类型包括:TINYBLOB,BLOB, MEDIUMBLOB,LONGBLOB, TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT。
2. 修改列的压缩属性
对于正在线上运行的数据库,要将对其中的字段增加压缩属性,可以通过alter table来修改,alter table可以取消或增加压缩属性。
因此,只需简单的alter table操作,就可以让DB中特定列压缩存储。以上述案例二的游戏DB中数据为例,一个1.3G的表,通过alter table增加compressed特征后为0.19G,压缩率是15%。在DB中,这样的表是100个,收益明显。
3. 透明压缩/解压
列属性指定为compressed之后,TMySQL内部会根据实际需要进行压缩和解压处理。假设ServiceInfo_00.ServiceInfo、ServiceInfo_00.GameInfo列具有compressed属性,以下语句等价关系为
4. 导入导出优化
应用TMySQL的列压缩后,在使用mysqldump进行导入导出时,在导出时会执行select操作,那么会对所有的压缩数据进行解压;同样,在导入时也会对需要压缩的数据执行压缩操作。
通过改造mysqldump,增加选项enable-compress-optimization来控制压缩的数据在导出与导入过程中,分别不进行解压与压缩,明显缩减导出及导入的时间。
三、收益与展望
1、收益
互娱的游戏DB中,具有blob/text类型字段的数据表都能够应用compressed特性,目前已有4款游戏使用上该特性。
上述案例二中游戏某大区的gamedb,进行压缩前数据大小为160G,在使用TMySQL的列压缩属性后,数据大小变成20G,压缩率是12.5%。
以该游戏一个区的数据作压力测试,使用压缩特性后DB性能提升显著:
如上图,在100并发下,在A5机型中的QPS由未压缩的253提升到列压缩后的2236,提升了8.8倍。
另外,在该业务的合服(两个或多个大区合并成一个大区)操作中,未压缩与压缩的合服时间对比为14239秒 vs 5749秒 , 时间节省为原来的40.3%。即合服操作导致的停服时间由原来4小时缩短到1.6小时。
2、展望
现阶段已应用TMySQL列压缩功能的游戏DB,已明显感受到使用列压缩带来的收益:包括合服、回档中停机时长大幅度减小等。随着越来越多的游戏DB使用列压缩功能,列压缩带来的收益会越来越可观。
这是典型的使用CPU换取内存和IO的做法,列压缩极大地减少了IO开销,虽说相应增加了CPU消耗,但当前游戏DB服务器的CPU处于相对空闲状态,这是完全可以接受的。后续会对列压缩会提供多种压缩算法,可针对不同应用环境来进行选择从而更合理地平衡IO与CPU的消耗。TMySQL版本未来会不断演进和迭代,内置包括DB云化、冷热数据分离等核心特性,提供业内领先的优质DB服务。
- InnoDB列压缩,提升DB性能
- 压缩数据,提升Web service性能
- 性能提升-----将页面输出进行压缩
- PostgreSQL hstore 列性能提升一例
- innodb压缩
- Hadoop使用lzo压缩提升I/O性能
- gzip压缩tomcat服务器响应包,大幅提升web性能
- gzip压缩tomcat服务器响应包,大幅提升web性能
- GridView的列数设置为auto_fit会提升性能?
- 一次性能峰值提升10W的DB调优之旅
- 提升性能
- 提升性能
- 提升性能
- innodb表压缩
- mysql innodb表压缩
- 表压缩(innodb)
- 有史以来性价比最高最让人感动的一次数据库&SQL优化(DB & SQL TUNING)——半小时性能提升千倍
- 从图片压缩的角度来思考提升APP的性能
- 对动态规划算法的顿悟(一)
- java调用R出错
- C/C++编译链接过程详解
- 用户手机客户端登录Login页面跳转到手机MobileLogin页面问题总结
- Android Studio运行项目报错: Failed to complete Gradle execution
- InnoDB列压缩,提升DB性能
- 九度online judge-A + B
- Map集合的基本操作
- POJ_2151_Check the difficulty of problems_概率DP
- Map集合的两种取出方式
- Linux GPIO操作分析 - Exynos 5260
- OV手机无线快门测评
- Map练习(基本自定义类型练习)
- 对于form.show() 和Application.run(form)的理解