内容简介:这一期的数据库测评报告让咱们一起来讨论下数据压缩这一话题。对于海量的数据存储,既要保证存储空间的使用,又要确保较高的性能,不论从业务逻辑层面、存储技术、架构设计等方面都会有大量的解决方案。本期的数据库评测报告仅仅从底层的数据组织形式的角度来解决这一问题,对比了不同的存储引擎的压缩机制的效率、性能。(1)减少磁盘和内存之间的数据传输量从而提升性能;(2)减少磁盘和内存空间的使用量。二级索引意义更大,因为索引数据同样可以被压缩;
一、写在前面的话
这一期的数据库测评报告让咱们一起来讨论下数据压缩这一话题。对于海量的数据存储,既要保证存储空间的使用,又要确保较高的性能,不论从业务逻辑层面、存储技术、架构设计等方面都会有大量的解决方案。本期的数据库评测报告仅仅从底层的数据组织形式的角度来解决这一问题,对比了不同的存储引擎的压缩机制的效率、性能。
1、压缩技术的下特点:
(1)减少磁盘和内存之间的数据传输量从而提升性能;
(2)减少磁盘和内存空间的使用量。二级索引意义更大,因为索引数据同样可以被压缩;
(3)通过使用更少的db大小来减少io,不过需要消耗一部分CPU资源来做压缩操作。
2、适合压缩的数据
(1)表结构中包含字符型数据列如char, varchar, text或blob等时,具有较高的压缩率,而一些二进制数据,如整形或浮点型数据列,或者一些已经压缩的多媒文件,其压缩率都不会高;
(2)完全随机的数据是最糟糕的。传统的数据往往有重复的值,压缩起来也相对有效。
二、聊聊innodb压缩
1、压缩参数
(1)监控参数(information_schema中)
①INNODB_CMP表
该表为每一个档位的page size(key_block_size)展现压缩情况,1k,2k,4k,8k,16k几个档位,可以利用这个表来测试某一张表A是否应该采用压缩技术。
- compress_ops:b-tree页压缩的次数
- compress_ops_ok:b-tree页成功压缩的次数
- compress_time:压缩花掉的累计时间
- uncompress_ops:没有被压缩成功的次数,一般是压缩失败或者第一次访问时
- uncompress_time:没有压缩成功花掉的总时间
如果大部分的cpu时间都花在压缩和解压上,那么使用更快或更多的cpu可以提升性能,或者是增大缓冲池大小,因为这样更多的未压缩页就能常驻在内存,从而减少了在内存中以压缩格式存储的数据需要解压的操作。大量的压缩操作(insert、update、delete)证明压缩表更新太过频繁,这时选择一个较大的page size,或者压缩表上主要负责读操作可能有益于系统性能。成功压缩的次数(COMPRESS_OPS_OK)和总共的压缩次数(COMPRESS_OPS)比例很高的话,通常表明系统运行良好,如果这个比例很低,mysql将会重新压缩。在这种情况下,需要避免某些表的压缩操作,或者增大key_block_size。通常来说,失败率超过1%或者2%的情况下,就建议关闭压缩。
②INNODB_CMP_PER_INDEX
该表提供每一张表和索引的压缩情况,这个信息对某一张表是否应该采用压缩技术更加有效,适用于开发测试环境,这样可以模拟不同工作负载,数据量,压缩率下的性能表现。不过这个比较消耗系统资源,测试时候需要开启innodb_cmp_per_index_enabled参数。
(2)参数调忧
①innodb_compression_level
默认值为6,可选值0-9,数值越大表示压缩程度越大,消耗的CPU也越多。
②innodb_compression_failure_threshold_pct
默认为5,可取值0-100,表示更新一个压缩表时,指定一个压缩失败的临界值。当超过这个临界值,mysql会为每个压缩页添加额外的空间来避免再次压缩失败。值为0表示禁用监控压缩效率,改为动态调整。
③innodb_compression_pad_pct_max
重新压缩时为每个压缩页额外分配的空间比例,默认50,可取值0-75.这个参数值只有当参数innodb_compression_failure_threshold_pct非0时才生效。
2、使用场景
为了尽量避免压缩、解压带来的额外消耗,InnoDB在压缩页中新增了modification log区,通过记录当前的页的修改日志,来避免频繁压缩解压。不同的业务场景,会对压缩效益产生不同的影响,下面几种场景相对适用压缩:
(1)查询操作,查询占了绝大部分,只有很少的更新,那么只有较少的页中会出现modification log空间不足,进而需要重组或者重新压缩,这种场景下是个不错的选择。
(2)插入操作,此时数据的插入按照主键递增的方式组织,即使存在二级索引也基本上不需要频繁重组和重压缩。
(3)删除操作,由于InnoDB删除行采用打标志位的方式来删除,对记录的删除是通过修改页中没有被压缩的元数据的方式实现,所以效率很高。
(4)更新操作,如果不是对索引列或者存储在off-page的blob,text,长字符串的列的更新,这种场景下使用压缩也是可以接受的。
三、聊聊tokudb压缩
1、关于tokudb
TokuDB 是一个支持事务的“新”引擎,有着出色的数据压缩功能,由美国 TokuTek 公司(现在已经被 Percona 公司收购)研发。拥有出色的数据压缩功能,如果数据写多读少,而且数据量比较大,使用tokuDB可以节省空间成本,并大幅度降低存储使用量和IOPS开销,不过相应的会增加 CPU 的压力。
2、tokudb的安装和使用
(1)安装percona mysql
①文件路径权限:必须跟启动的user一致
②初始化数据库:
mysql5.6之前(包括5.6):mysql_install_db
mysql5.7之后 :mysqld --initialize
(2)安装tukodb
①安装libjemalloc库
wget http://dl.Fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
rpm -ivh epel-release-latest-6.noarch.rpm
yum install jemalloc -y
通过yum安装,生成的库文件为/usr/lib64/libjemalloc.so.1
wget http://dl.Fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
②修改配置文件my.cnf
在[mysqld_safe]下设置malloc-lib变量
malloc-lib=/usr/lib64/libjemalloc.so.1
plugin-dir = /data/percona/base/lib/mysql/plugin/
plugin-load = ha_tokudb.so
③禁用Transparent huge pages
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
④拷贝ha_tokudb.so文件到 mysql 的/data/percona/base/lib/mysql/plugin/下
⑤手动加载tukodb
登录mysql客户端,执行如下命令
INSTALL PLUGIN tokudb SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_file_map SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_fractal_tree_info SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_fractal_tree_block_map SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_trx SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_locks SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_lock_waits SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_background_job_status SONAME 'ha_tokudb.so';
⑥配置文件
[mysqld]
#tokudb
#把TokuDB datadir以及logdir和MySQL的datadir分开,也可以不分开,
tokudb-data-dir = /data/mysql/tokudbData
tokudb-log-dir = /data/mysql/tokudbLog
#TokuDB的行模式,建议用 FAST ,如果磁盘空间很紧张,建议用 SMALL
tokudb_row_format = tokudb_fast
tokudb_cache_size = xxG ###建议内存的一半
tokudb_commit_sync = 0
tokudb_directio = 1
tokudb_read_block_size = 128K
tokudb_read_buf_size = 128K
3、压缩参数
tokudb_row_format 可以设置如下的几个值:
tokudb_default: 设置默认的压缩行为。(7.1.0版本,默认zlib 库进行压缩)。
tokudb_zlib: 使用 zlib 库,中等级别的压缩比和中等级别的CPU消耗。
tokudb_quicklz: 使用 quicklz 库, 轻量级的压缩比和较低基本的CPU消耗。
tokudb_lzma: 使用lzma库,高压缩比和高CPU消耗。
tokudb_uncompressed: 不使用压缩模式。
4、使用总结
(1)TokuDB的优点
①高压缩比
②在线添加索引,不影响读写操作
③支持在线字段增加、删除、扩展、重命名操作
④支持完整的ACID特性和事务机制
⑤非常快的写入性能, Fractal-tree在事务实现上有优势
⑥支持show processlist 进度查看
⑦数据量可以扩展到几个TB;
⑧不会产生索引碎片;
⑨支持hot column addition,hot indexing,mvcc
(2)TokuDB缺点
①不支持外键功能
②CPU占用会高,但由于压缩后空间小,IO开销低,平均响应时间大概是2倍左右。
③没有完善的热备工具,只能通过mysqldump进行逻辑备份
(3)适用场景
①访问频率不高的数据或历史数据归档
②数据表非常大并且时不时还需要进行DDL操作
三、压缩性能到底如何?
1、压缩性能
(1)压缩率
- 采用压缩技术,对含有大文本字段的数据,压缩比例都十分惊人,均能达到80%以上
- tokudb的压缩率均高于 innodb的压缩率(80%,62GB的数据压缩完仅剩12GB) , toku_LZMA的压缩率最高,达到93%左右(62GB的数据,压缩完仅剩4.9GB)
(2)压缩时间
- tokudb的压缩耗时(22分钟~24分钟)小于innodb的压缩耗时(30分钟左右)
- tokudb压缩耗时随着压缩登记升高而升高,但增加并不明显
- innodb可以进行在线压缩数据,tokudb进行在线压缩测试失败(24小时未成功)
2、SELECT性能(简单主键查询)
(1)QPS
- Innodb不采用压缩时select请求的QPS在30并发的时候达到峰值,为将近35W,并且随着并发数继续增加时衰减的更为缓慢
- Innodb_compress与toku_QUICKLZ压缩的select性能曲线几乎重合,趋势相近
- 随着tokudb压缩程度的递增,select的性能明显呈下降趋势
(2)平均响应延时
- 在并发数较低的时候(30以下)基本所有压缩和未压缩的数据,访问延时基本相近,均低于50us
- 随着并发数的增加tokudb压缩策略的测试用例在大于30并发时延时开始明显增加,并随着压缩率的等级升高,访问延时增加的速度也更快,极端情况下也均控制在ms的个位数级别
- 在所有压缩策略中, innodb_compress的访问延时在各个并发情况下均是最低的 ,仅次于未使用压缩的用例
3、INSERT性能
- 对于insert操作不开启压缩的性能明显好于压缩(不论是innodb_compress还是tokudb的压缩策略)
- innodb_compress对写性能的影响高于tokudb的各类压缩策略
- toku_QUICKLZ写性能在几种策略中比较有优势
4、CPU使用率
由于经过测试select简单主键查询(如果 SQL 包含大量统计计算、 排序 等操作的情况不适用以下分析)和insert的CPU使用趋势相近,故归并成统图表进行分析
- 压缩与未压缩CPU使用率在任何并发情况下差别都比较明显,尤其在性能达到峰值时,未压缩的用例CPU消耗的资源较低
- innodb_compress、tokudb_ZLIB 、tokudb_quicklz的CPU消耗趋势一致, Innodb_compress的CPU消耗在中低并发时会稍低与其他两种压缩策略
- tokudb_LZMA压缩策略对CPU的压力较大,在50并发时就已经使得24个CPU使用率均达到90%以上
五、总结一下
从根本上说,当CPU时间可用于压缩及解压数据时,压缩效果最佳。如果工作量是由I/O引起的,而不是由CPU引起,压缩便能够提高整体性能。压缩是通过消耗更多的cpu资源来换取减少IO消耗,最终带来性能的提升,如果应用是IO密集型,而不是cpu密集型,那么可以利用剩余的cpu来提升应用性能。
通过对比innodb_compress和tokudb的三种压缩策略,可以得出以下结论:
1、tokudb的压缩率远超innodb_compress(80%),tokudb_LZMA的策略压碎率能达到93%
2、tokudb的压缩耗时低于innodb_compress,但tokudb在线压缩功能不可用(24小时未成功)
3、在高并发场景下innodb_compress的访问延迟低。
4、压缩策略均会对读写性能造成影响,随着压缩成都增加,影响程度越大
5、innodb_compress对写性能的影响均高于tokudb的各类压缩策略
6、对CPU资源的消耗上,innodb_compress消耗CPU资源相对tokudb压缩策略来说较少(与tokudb_ZLIB 、tokudb_quicklz相近),tokudb_LZMA的CPU资源消耗最多
7、在测试中tokudb各种压缩策略均容易出现瞬间延时的毛刺,稳定性较innodb_compress来说低一些
【数据库评测报告】第三期:innodb与tokudb压缩的主要内容就是以上这些了,测试在进行过程中由于网络条件、数据库配置等因素的影响,可能无法发挥出TS90机器的最大性能,但在一定程度上对于数据库压缩的选择也具有一定参考价值。 还想了解测试的参数和细节的朋友可以继续往下读。
附录:环境配置和压测 工具 是哪些?
1、测试环境
(1)软件版本
|
设备型号 |
软件版本 |
|---|---|
|
TS90 |
MySQL-5.7、TokuDB-7.1.0 |
(2)硬件配置
|
设备型号 |
配置描述 |
CPU型号 |
|---|---|---|
|
TS90 |
2个12核CPU,256G内存,12*800G SSD,万兆网卡 |
E5-2670v3 |
2、测试数据结构
(1)表结构
表结构用内容平台部使用的线上文章表的真实结构和数据内容进行测试,数据的特点是单字段占用存储空间大,总条数在百万级,具体结构如下:
CREATE TABLE `t_article` (
`Farticle_id` varchar(14) NOT NULL DEFAULT '',
`Fcontent` longtext NOT NULL,
PRIMARY KEY (`Farticle_id`)
) ENGINE=xxxx
(2)测试用例
|
表名 |
数据量(不压缩) |
记录数 |
平均长度 |
压缩方式 |
|---|---|---|---|---|
|
t_article |
62GB |
1345646 |
48KB |
不压缩 |
|
t_article_1 |
innodb_compress |
|||
|
t_article_2 |
toku_LZMA |
|||
|
t_article_3 |
toku_QUICKLZ |
|||
|
t_article_4 |
toku_ZLIB |
3、测试工具
mydbtest是一款轻量级的mysql数据库压测工具,安装部署操作简单,支持定制化SQL和表结构,非常方便。
配置文件中仅仅包含三个部分,即option (控制选项)、declare ( 声明变量,可以用到压测SQL中,组成动态的SQL)、begin end (在begin和end中间编写压测过程中使用的SQL语句)
(1)option
①Name
指定压测用例名,只体现在测试报告里面
②User
数据库连接信息,格式为 user/password@hostname:ip:database
④Waitop
控制测试执行次数,默认为1亿次
④Wait
两次执行(所有定义的语句被执行算一次)之间的暂停时间,单位为 0.1 毫秒,不是指两个 SQL 语句之间的暂停时间。默认值为 0 表示没有任何停顿,用大并发测试时需要指定一个暂停时间,若未定义则在超过 1000 个并发线程压测时会计算一个默认值
⑤Log
输出日志文件名,默认输出到屏幕
⑥Time
指定测试时间,默认值3600(单位为s),可指定m或h来代表分钟和小时。(此参数与loop参数互斥)
⑦Timeow
报告时间间隔,每隔多少秒输出统计报告。默认值为300s
⑧Tran
事务模式开关,默认值为OFF,表示运行在自动提交模式,每一个SQL会被当作一个事务,执行成功则提交;如果设置为ON,则第一条SQL执行之前会有一个开启事务的调用,所有SQL执行完成后,会有一个事务提交命令
⑨Showmmit
事务大小参数,默认值为1,表示每执行1次测试发1次提交命令,此参数只在事务模式下有效,即tran参数应该配置为ON
(2)Declare
格式:变量名 变量类型 最小值 最大值(变量名 变量类型 值列表)
①seq
自增的32位整数,从最小值递增到最大值,超过最大值从最小值从头开始循环使用
②int
32位的随机整数,随机范围在最小值和最大值之间
③intlist
从给定的值里面随机选择一个整数,多个数值用逗号隔开
④char
字符串类型,需要定义最小长度和最大长度,字符串长度将在最小长度和最大长度之间随机。(生成定长的字符串,将最小长度和最大长度设定为一样的长度)
⑤strlist
从给定的字符串列表中随机选取一个字符串。多个字符串之间用逗号隔开。限制字符串的值不能包含空格,两个字符串之间不能带空格
⑥float and double
低精度浮点数和高精度浮点数,取值在最小值和最大值之间
⑦date
自动生成的具有日期格式YYYY-MM-DD的字符串,需要指定日期范围,开始日期为当前日期减最小值,结束日期为当前日期加最大值。(指定值“-10”表示开始日期为10天前,指定”10”表示10天后)
⑤timestamp
自动生成的具有日期格式YYYY-MM-DD HH24:MI:SS的字符串,需要指定日期范围,开始日期为当前日期减最小值,结束日期为当前日期加最大值。
(3)SQL
在begin和end之间编写你要压测的sql,在sql中可以使用在 “declare” 块声明的变量,变量的引用方式为 :变量名
(4)运行
./mydbtest_linux64.bin query=query.cnf degree=32
- query : 指定具体的配置文件
- degree : 指定压测并发度(压测线程个数)
(5)报告解读
- qtps : 当测试SQL为写操作的时候,为TPS,当测试SQL为读操作的时候,表示QPS,若混合读写,则需要根据读写比例计算TPS和QPS。
- avg : 表示95%平均响应时间,单位为微秒
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 百分点大数据评测报告:开源OLAP引擎综评(HAWQ、Presto、ClickHouse)
- 【ST开发板评测】Nucleo-F411RE开箱报告
- golang压缩和解压缩zip文件
- bitcoin:压缩公钥与未压缩公钥
- 一句话轻松实现压缩图片和文件压缩
- 基于Node.js实现压缩和解压缩的方法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Twenty Lectures on Algorithmic Game Theory
Tim Roughgarden / Cambridge University Press / 2016-8-31 / USD 34.99
Computer science and economics have engaged in a lively interaction over the past fifteen years, resulting in the new field of algorithmic game theory. Many problems that are central to modern compute......一起来看看 《Twenty Lectures on Algorithmic Game Theory》 这本书的介绍吧!