数据库随机IO优化总结.

数据库随机IO优化总结.

 
IO性能衡量标准:
1. IOPS: 每秒的读写次数, 对于随机IO的应用, IOPS是主要的衡量标准.
2. 吞吐量: 单位时间内的数据传输量, 对于顺序IO的应用, 吞吐量是主要的衡量标准.
 
影响IOPS和吞吐量的磁盘性能要素:
1. 寻道时间: 读写磁头移动至正确的磁道上所需要的时间, 当前磁盘寻道时间一般为3ms-15ms.
2. 旋转延迟: 盘片旋转将请求数据所在扇区移至读写磁头下方所需要的时间, 旋转延迟取决于磁盘转速. 1.5Krpm的平均旋转时间为2ms.
3. 数据传输时间: 完成传输所请求的数据所需要的时间,取决于数据传输率. 目前SATA II的传输率可达300MB/S
 
传统机械磁盘IOPS计算:
IOPS(每秒IO次数) = 1s/(寻道时间+旋转延迟/2+数据传输时间), 数据传输时间由于很短, 几乎可以忽略.
IOPS(7200rpm) = 1000 / (3 + 60000/7200/2)  = 140
IOPS(10K) = 1000 / (3 + 60000/10000/2) = 167
IOPS(15Krpm)= 1000 / (3 + 60000/15000/2) = 200
所以对于大量随机IO的应用,尽量避免数据库单机磁盘随机读写是一个非常重要的优化.
 
SSD固态硬盘: 
一种电子装置, 避免了传统的磁盘寻道和旋转的时间, 不过成本高.
随机读IOPS = 1s/数据传输时间. 理论上读IOPS可以上10w.
由于SSD采用的写策略的不同, 随机写的IOPS平均值大概为5K.
 
数据随机IO问题:
1. 当数据量超过内存大小的时候, 随机IO的问题出现.
2. 页级缓存在大量全随机IO的情况下内存利用率低,同时页级缓存还带来了大量额外连续IO的问题.
3. B+树当索引大于内存量, 每次随机的索引搜索,插入和删除都将有至少一次随机IO.
4. 索引组织表(HashTable)占用内存太大, 同时每次随机的索引搜索,插入和删除都将有一次随机IO.
 
随机IO解决方案:
1. SSD磁盘可以缓解随机读的问题, 但不能解决随机写的问题.
2. 记录级的缓存, 如果访问模式符合Zipf分布, 那可以通过10%的内存解决90%随机IO读
    * Memcached: 非常好的记录级缓存, 不过存在几个问题:
        > 缓存和数据库的一致性, 通常通过TTL,数据库事务来保证.如果通过事务来保证,存在两个系统之间一个毫秒级的锁定.
        > Memcached不能解决随机写的问题.
    * 数据库内置记录缓存: 可以很好的缓解随机IO读写问题, 不过内存管理,数据一致性,数据恢复等的实现比较复杂.
 
数据库内置记录缓存的基本设计:
1. 优先读内置缓存, 不命中在读磁盘.
2. 更新只更新缓存.
3. 定时或者定量将缓存dump到磁盘, 用顺序IO写, 不用更新原有磁盘文件.
4. 如果是对象数据库,更新是在原来对象基础上,比如只更新部分属性, 则需要将原记录首先读出,在将更新后的对象放入缓存.
5. 为了防止丢记录, 可以在更新写入缓存之前, 顺序IO记录log.
6. 记录级缓存必须限制单个记录大小, 提高缓存利用率.
7. 如果因为重启等原因导致缓存数据丢失,必须根据log进行数据恢复.
 
索引随机IO解决方案:
1. B+树: 搜索、插入和删除理论上复杂度为O(log(B)(N))次IO, 如果非叶子节点都在内存中, 则是一次随机IO.
2. LSM-Tree: 主要针对写远多与读的场景, 将索引数据写入内存和log, 定期批量写入磁盘. 采用分级索引块批量更新的方式将随机写IO的开销降低到log(N)/B.
    这样随机写变为了连续写,但是读需要读内存和多个索引文件, 然后merge,开销比较大, 一般采用BloomFilter来过滤随机读,以减少不必要的随机读. 
    现在HBase,Cassandra都采用这种方式.
3. Fractal Tree(分形树): 结构上也是多级索引块,从小到大, 随机写性能和LSM-Tree一样. 随机读采用了Fractional Cascading.
    Facebook上有一遍对FC的介绍: http://www.facebook.com/pages/Fractional-cascading/145152932165841
    FC简单点说,就是给每个分级索引块中的每个索引元素加上2个指针,一个指向它前面一个索引块中最小比它大的索引元素,一个指向它后面一个索引块中最小比它大的索引元素.
    据说Range Tree+FC的搜索性能已经逼近了B+树. (题外话, HBase什么时候也考虑考虑引进FC呀.)
 
随机IO优化总结:
1. 采用SSD固态硬盘替换传统机械硬盘,可以大大的提高IOPS.
2. 采用记录级缓存可以大大缓解随机读的压力.
3. 采用数据库内置记录缓存可以缓解随机IO读写问题.
4. 采用LSM-Tree和Fractal Tree可以很好的解决索引的随机插入和删除问题.
5. 采用Bloom Filter可以消除绝大部分不必要的随机读
6. 采用Fractional Cascading算法, 可以很大程度提升Range Tree的搜索性能.
 
参考:
http://wangyuanzju.blog.163.com/blog/static/13029201132154010987/
http://blog.zephyrleaves.net/?p=88
http://en.wikipedia.org/wiki/Fractional_cascading
posted @ 2012-05-19 01:09  明轩  阅读(2364)  评论(0编辑  收藏  举报
作者:Jenvin
出处:http://mingxuan.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。