es translog 减少磁盘io_文件系统

 

IO性能优化
    应用程序优化
        用追加写代替随机写,减少寻址开销,加快 I/O 写的速度
        借助缓存 I/O ,充分利用系统缓存,降低实际 I/O 的次数。
        应用程序内部构建自己的缓存
             外部缓存系统Redis
                能在应用程序内部,控制缓存的数据和生命周期
             C 标准库提供的 fopen、fread 等库函数,都会利用标准库的缓存,减少磁盘的操作。而你直接使用 open、read 等系统调用时,就只能利用操作系统提供的页缓存和缓冲区等,而没有库函数的缓存可用。
        同一块磁盘空间时用mmap 代替 read/write,减少内存的拷贝次数。
        需要同步写的场景中
            尽量将写请求合并,而不是让每个请求都同步写入磁盘,即可以用 fsync() 取代 O_SYNC。(redis的持久化就调用的fsync而非O_SYNC)
        多个应用程序共享相同磁盘时
            为了保证 I/O 不被某个应用完全占用,推荐你使用 cgroups 的 I/O 子系统,来限制进程 / 进程组的 IOPS 以及吞吐量。
    文件系统优化
        选择最适合的文件系统
            大数据xfs性能较好,例如MPP数据库
            Ubuntu 默认使用 ext4 文件系统,而 CentOS 7 默认使用 xfs 文件系统
            ext4和xfs 优缺点
                xfs 支持更大的磁盘分区和更大的文件数量,如 xfs 支持大于 16TB 的磁盘。但是 xfs 文件系统的缺点在于无法收缩,而 ext4 则可以
        优化文件系统的配置选项
            文件系统的特性(如 ext_attr、dir_index)、日志模式(如 journal、ordered、writeback)、挂载选项(如 noatime)
            tune2fs 这个工具,可以调整文件系统的特性(tune2fs 来查看文件系统超级块的内容)
            通过 /etc/fstab ,或者 mount 命令行参数调整文件系统的日志模式和挂载选项
        优化文件系统的缓存
            优化 pdflush 脏页的刷新频率
                比如设置 dirty_expire_centisecs 和 dirty_writeback_centisecs
            脏页的限额
                比如调整 dirty_background_ratio 和 dirty_ratio 
            优化内核回收目录项缓存和索引节点缓存的倾向
                调整 vfs_cache_pressure(/proc/sys/vm/vfs_cache_pressure,默认值 100),数值越大,就表示越容易回收。
        使用内存文件系统 tmpfs
            tmpfs 把数据直接保存在内存中
(spark中常使用该文件系统)
                比如 /dev/shm/ 多数 Linux 默认配置的一个内存文件系统,它的大小默认为总内存的一半
    磁盘优化
        有钱就是豪:  SSD 替代 HDD
        一般豪: 使用 RAID, 提高数据的可靠性,又可以提升数据的访问性能
        穷B: 选择最适合的 I/O 调度算法
SSD 和虚拟机中的磁盘,通常用的是 noop 调度算法。数据库应用使用 deadline 算法。
        调整预读大小
            调整内核选项 /sys/block/sdb/queue/read_ahead_kb,默认大小是 128 KB,单位为 KB。
            使用 blockdev 工具设置,比如 blockdev --setra 8192 /dev/sdb,注意这里的单位是 512B(0.5KB),所以它的数值总是 read_ahead_kb 的两倍
        调整磁盘队列的长度
            /sys/block/sdb/queue/nr_requests,适当增大队列长度,可以提升磁盘的吞吐量(当然也会导致 I/O 延迟增大)

IO故障排查
    dmesg
    使用 badblocks、smartctl 等工具,检测磁盘的硬件问题
     e2fsck 等来检测文件系统的错误
    使用 fsck 等工具来修复

如何精确模拟应
用程序的 I/O 模式呢
    1、blktrace /dev/sdb
blktrace 跟踪磁盘 I/O,注意指定应用程序正在操作的磁盘
2、查看 blktrace 记录的结果
ls
sdb.blktrace.0 sdb.blktrace.1
3、blkparse sdb -d sdb.bin
将结果转化为二进制文件
4、fio --name=replay --filename=/dev/sdb --direct=1 --read_iolog=sdb.bin
 fio --name=replay重放日志

磁盘 I/O 性能优化的几个思路
    I/O 基准测试fio(Flexible I/O Tester)
        安装
            yum install -y fio
        选项
            # 随机读
fio -name=randread -direct=1 -iodepth=64 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb
                READ: bw=24.2MiB/s (25.3MB/s), 24.2MiB/s-24.2MiB/s (25.3MB/s-25.3MB/s), io=1024MiB (1074MB), run=42397-42397msec
            # 随机写
fio -name=randwrite -direct=1 -iodepth=64 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb
             # 顺序读
fio -name=read -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb
                READ: bw=109MiB/s (114MB/s), 109MiB/s-109MiB/s (114MB/s-114MB/s), io=1024MiB (1074MB), run=9393-9393msec
             # 顺序写
fio -name=write -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb 
        测试指标参数解读
            slat
                指从 I/O 提交到实际执行 I/O 的时长(Submission latency)
            clat
                指从 I/O 提交到 I/O 完成的时长(Completion latency)
            lat
                指的是从 fio 创建 I/O 到 I/O 完成的总时长
        参数解读
            direct,表示是否跳过系统缓存。设置的 1 ,就表示跳过系统缓存。
            iodepth,表示使用异步 I/O(asynchronous I/O,简称 AIO)时,同时发出的 I/O 请求上限
            表示 I/O 模式。我的示例中, read/write 分别表示顺序读 / 写,而 randread/randwrite 则分别表示随机读 / 写。
            ioengine,表示 I/O 引擎,它支持同步(sync)、异步(libaio)、内存映射(mmap)、网络(net)等各种 I/O 引擎。
            bs,表示 I/O 的大小
            filename,可以是文件路径(测试文件系统性能)/ 磁盘路径(测试磁盘性能).
注意:  用磁盘路径测试写,会破坏这个磁盘中的文件系统,所以在使用前,你一定要事先做好数据备份。
    hdparm
         hdparm /dev/vda
            ECS:/dev/vda:
 HDIO_DRIVE_CMD(identify) failed: Inappropriate ioctl for device
 readonly      =  0 (off)
 readahead     = 8192 (on)
 geometry      = 208050/16/63, sectors = 209715200, start = 0
        读取速度hdparm -T /dev/vda
            /dev/vda:
 Timing cached reads:   17648 MB in  1.99 seconds = 8866.28 MB/sec