在安装MariaDB的时候了解到代替InnoDB的TokuDB,看简介非常的棒,这里对ToduDB做一个初步的整理,使用后再做更多的分享。
什么是TokuDB? 在MySQL最流行的支持全事务的引擎为INNODB。其特点是数据本身是用B-TREE来组织,数据本身即是庞大的根据主键聚簇的B-TREE索引。 所以在这点上,写入速度就会有些降低,因为要每次写入要用一次IO来做索引树的重排。特别是当数据量本身比内存大很多的情况下,CPU本身被磁盘IO纠缠的做不了其他事情了。这时我们要考虑如何减少对磁盘的IO来排解CPU的处境,常见的方法有:
TokuDB 是一个支持事务的“新”引擎,有着出色的数据压缩功能,由美国 TokuTek 公司(现在已经被 Percona 公司收购)研发。拥有出色的数据压缩功能,如果您的数据写多读少,而且数据量比较大,强烈建议您使用TokuDB,以节省空间成本,并大幅度降低存储使用量和IOPS开销,不过相应的会增加 CPU 的压力。 TokuDB 的特性 1.丰富的索引类型以及索引的快速创建 TokuDB 除了支持现有的索引类型外, 还增加了(第二)集合索引, 以满足多样性的覆盖索引的查询, 在快速创建索引方面提高了查询的效率 2.(第二)集合索引 也可以称作非主键的集合索引, 这类索引也包含了表中的所有列, 可以用于覆盖索引的查询需要, 比如以下示例, 在where 条件中直接命中 index_b 索引, 避免了从主键中再查找一次。 见: http://tokutek.com/2009/05/introducing_multiple_clustering_indexes/ 3.索引在线创建(Hot Index Creation) TokuDB 允许直接给表增加索引而不影响更新语句(insert, update 等)的执行。可以通过变量 tokudb_create_index_online 来控制是否开启该特性, 不过遗憾的是目前还只能通过 CREATE INDEX 语法实现在线创建, 不能通过 ALTER TABLE 实现。 这种方式比通常的创建方式慢了许多, 创建的过程可以通过 show processlist 查看。不过 tokudb 不支持在线删除索引, 删除索引的时候会对标加全局锁。 4.在线更改列(Add, Delete, Expand, Rename) TokuDB 可以在轻微阻塞更新或查询语句的情况下, 允许实现以下操作:
这些操作通常是以表锁级别阻塞(几秒钟时间)其他查询的执行, 当表记录下次从磁盘加载到内存的时候, 系统就会随之对记录进行修改操作(add, delete 或 expand), 如果是 rename 操作, 则会在几秒钟的停机时间内完成所有操作。 TokuDB的这些操作不同于 InnoDB, 对表进行更新后可以看到 rows affected 为 0, 即更改操作会放到后台执行, 比较快速的原因可能是由于 Fractal-tree 索引的特性, 将随机的 IO 操作替换为顺序 IO 操作, Fractal-tree的特性中,会将这些操作广播到所有行, 不像 InnoDB, 需要 open table 并创建临时表来完成。
看看官方对该特性的一些指导说明:
5.数据压缩 TokuDB中所有的压缩操作都在后台执行, 高级别的压缩会降低系统的性能, 有些场景下会需要高级别的压缩. 按照官方的建议: 6核数以下的机器建议标准压缩, 反之可以使用高级别的压缩。每个表在 create table 或 alter table 的时候通过 ROW_FORMAT 来指定压缩的算法: ROW_FORMAT默认由变量 tokudb_row_format 控制, 默认为 tokudb_zlib, 可以的值包括:
6.Read free 复制特性 得益于 Fracal Tree 索引的特性, TokuDB 的 slave 端能够以低于读IO的消耗来应用 master 端的变化, 其主要依赖 Fractal Tree 索引的特性,可以在配置里启用特性
不好的是, 如果启用了 Read Free Replication 功能, Server 端需要做如下设置:
slave 端的设置可以在一台或多台 slave 中设置:MySQL5.5 和 MariaDB5.5中只有定义了主键的表才能使用该功能, MySQL 5.6, Percona 5.6 和 MariaDB 10.X 没有此** 7.事务, ACID 和恢复
8.过程追踪
TokuDB 提供了追踪长时间运行语句的机制. 对 LOAD DATA 命令来说,SHOW PROCESSLIST 可以显示过程信息, 第一个是类似 “Inserted about 1000000 rows” 的状态信息, 下一个是完成百分比的信息, 比如 “Loading of data about 45% done”; 增加索引的时候, SHOW PROCESSLIST 可以显示 CREATE INDEX 和 ALTER TABLE 的过程信息, 其会显示行数的估算值, 也会显示完成的百分比; SHOW PROCESSLIST 也会显示事务的执行情况, 比如 committing 或 aborting 状态。 9.迁移到 TokuDB 可以使用传统的方式更改表的存储引擎, 比如 “ALTER TABLE … ENGINE = TokuDB” 或 mysqldump 导出再倒入, INTO OUTFILE 和 LOAD DATA INFILE 的方式也可以。 10.热备 Percona Xtrabackup 还未支持 TokuDB 的热备功能, percona 也为表示有支持的打算 http://www.percona.com/blog/2014/07/15/tokudb-tips-mysql-backups/ ;对于大表可以使用 LVM 特性进行备份, https://launchpad.net/mylvmbackup , 或 mysdumper 进行备份。TokuDB 官方提供了一个热备插件 tokudb_backup.so, 可以进行在线备份, 详见 https://github.com/Tokutek/tokudb-backup-plugin, 不过其依赖 backup-enterprise, 无法编译出 so 动态库, 是个商业的收费版本, 见 https://www.percona.com/doc/percona-server/5.6/tokudb/tokudb_installation.html 总结 TokuDB的优点:
TokuDB缺点:
适用场景:
TokuDB的索引结构分形树的实现 TokuDB和InnoDB最大的不同在于TokuDB采用了一种叫做Fractal Tree的索引结构,使其在随机写数据的处理上有很大提升。目前无论是SQL Server,还是MySQL的innodb,都是用的B Tree(SQL Server用的是标准的B-Tree)的索引结构。InnoDB是以主键组织的B Tree结构,数据按照主键顺序排列。对于顺序的自增主键有很好的性能,但是不适合随机写入,大量的随机I/O会使数据页**产生碎片,索引维护开销很多大。TokuDB解决随机写入的问题得益于其索引结构,Fractal Tree 和 B-Tree的差别主要在于索引树的内部节点上,B-Tree索引的内部结构只有指向父节点和子节点的指针,而Fractal Tree的内部节点不仅有指向父节点和子节点的指针,还有一块Buffer区。当数据写入时会先落到这个Buffer区上,该区是一个FIFO结构,写是一个顺序的过程,和其他缓冲区一样,满了就一次性刷写数据。所以TokuDB上插入数据基本上变成了一个顺序添加的过程。 BTree和Fractal tree的比较: Fractal tree(分形树)简介 分形树是一种写优化的磁盘索引数据结构。 在一般情况下, 分形树的写操作(Insert/Update/Delete)性能比较好,同时它还能保证读操作近似于B 树的读性能。据Percona公司测试结果显示, TokuDB分形树的写性能优于InnoDB的B 树), 读性能略低于B 树。 ft-index的磁盘存储结构 ft-index采用更大的索引页和数据页(ft-index默认为4M, InnoDB默认为16K), 这使得ft-index的数据页和索引页的压缩比更高。也就是说,在打开索引页和数据页压缩的情况下,插入等量的数据, ft-index占用的存储空间更少。ft-index支持在线修改DDL (Hot Schema Change)。 简单来讲,就是在做DDL操作的同时(例如添加索引),用户依然可以执行写入操作, 这个特点是ft-index树形结构天然支持的。 此外, ft-index还支持事务(ACID)以及事务的MVCC(Multiple Version Cocurrency Control 多版本并发控制), 支持崩溃恢复。正因为上述特点, Percona公司宣称TokuDB一方面带给客户极大的性能提升, 另一方面还降低了客户的存储使用成本。 ft-index的索引结构图如下: 灰色区域表示ft-index分形树的一个页,绿色区域表示一个键值,两格绿色区域之间表示一个儿子指针。 BlockNum表示儿子指针指向的页的偏移量。Fanout表示分形树的扇出,也就是儿子指针的个数。 NodeSize表示一个页占用的字节数。NonLeafNode表示当前页是一个非叶子节点,LeafNode表示当前页是一个叶子节点,叶子节点是最底层的存放Key-value键值对的节点, 非叶子节点不存放value。 Heigth表示树的高度, 根节点的高度为3, 根节点下一层节点的高度为2, 最底层叶子节点的高度为1。Depth表示树的深度,根节点的深度为0, 根节点的下一层节点深度为1。 分形树的树形结构非常类似于B 树, 它的树形结构由若干个节点组成(我们称之为Node或者Block,在InnoDB中,我们称之为Page或者页)。 每个节点由一组有序的键值组成。假设一个节点的键值序列为[3, 8], 那么这个键值将(-00, 00)整个区间划分为(-00, 3), [3, 8), [8, 00) 这样3个区间, 每一个区间就对应着一个儿子指针(Child指针)。 在B 树中, Child指针一般指向一个页, 而在分形树中,每一个Child指针除了需要指向一个Node的地址(BlockNum)之外,还会带有一个Message Buffer (msg_buffer), 这个Message Buffer 是一个先进先出(FIFO)的队列,用来存放Insert/Delete/Update/HotSchemaChange这样的更新操作。 按照ft-index源代码的实现, 对ft-index中分形树更为严谨的说法:
分形树的Insert/Delete/Update实现 我们说到分形树是一种写优化的数据结构, 它的写操作性能要优于B 树的写操作性能。 那么它究竟如何做到更优的写操作性能呢?首先, 这里说的写操作性能,指的是随机写操作。 举个简单例子,假设我们在MySQL的InnoDB表中不断执行这个SQL语句: insert into sbtest set x = uuid(), 其中sbtest表中有一个唯一索引字段为x。 由于uuid()的随机性,将导致插入到sbtest表中的数据散落在各个不同的叶子节点(Leaf Node)中。 在B 树中, 大量的这种随机写操作将导致LRU-Cache中大量的热点数据页落在B 树的上层(如下图所示)。这样底层的叶子节点命中Cache的概率降低,从而造成大量的磁盘IO操作, 也就导致B 树的随机写性能瓶颈。但B 树的顺序写操作很快,因为顺序写操作充分利用了局部热点数据, 磁盘IO次数大大降低。
下面来说说分形树插入操作的流程。 为了方便后面描述,约定如下:
详细流程如下: 1、加载Root节点; 2、判断Root节点是否需要**(或合并),如果满足**(或者合并)条件,则**(或者合并)Root节点。 具体**Root节点的流程,感兴趣的同学可以开开脑洞。 3、当Root节点height |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|