blockdev --setra预读优化和IO请求的大小

分类: LINUX

磁盘预读可以改善顺序读的性能,并且测试发现每个读请求的大小也受预读大小的影响,也就是发生了IO合并。

在每次8K的顺序读中,关闭预读时,每个IO是8个扇区(4K); 增大预读,每个IO大概等于预读大小,但最大是设备的单个IO大小的上限(这里是1024)。 下面是详细的测试。

环境

台式机上的CentOS7.1 4核虚机
消费级SSD

准测试数据

dd if=/dev/zero of=testdata bs=8096 count=100000 

关闭预读的测试

  1. 关闭预读

    /sbin/blockdev --setra 0 /dev/mapper/centos-root
    /sbin/blockdev --setfra 0 /dev/mapper/centos-root 
  2. 清缓存

    sync
    echo 3 > /proc/sys/vm/drop_caches 
  3. 执行顺序读操作

    [root@node2 ~]# dd if=testdata bs=8192 count=100000 of=/dev/null
    98828+1 records in
    98828+1 records out
    809600000 bytes (810 MB) copied, 150.268 s, 5.4 MB/s 

    在没有预读的情况下,读取速度5.4 MB/s,说明每个IO大小是8个扇区(4KB),取的是iostat中途的值。

    [root@node2 ~]# iostat -xm 1 100
    avg-cpu:  %user   %nice %system %iowait  %steal   %idle
               0.00    0.00    8.22   15.38    0.00   76.39
    
    Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
    sda               0.00     0.00 1390.00    0.00     5.43     0.00     8.00     0.91    0.65    0.65    0.00   0.65  90.70
    sdb               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    scd0              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    dm-0              0.00     0.00 1389.00    0.00     5.43     0.00     8.00     0.91    0.65    0.65    0.00   0.65  90.90
    dm-1              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    dm-2              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    dm-3              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    dm-6              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    dm-5              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    dm-4              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00 

设置预读大小为256

256是RHEL6.x的默认值,读取速度达到21.1 MB/s

[root@node2 ~]# /sbin/blockdev --setra 256 /dev/mapper/centos-root
[root@node2 ~]# sync
[root@node2 ~]# echo 3 > /proc/sys/vm/drop_caches
[root@node2 ~]# dd if=testdata bs=8192 count=100000 of=/dev/null
98828+1 records in
98828+1 records out
809600000 bytes (810 MB) copied, 38.2959 s, 21.1 MB/s 

相应的每个读请求的大小也也通过IO合并扩大到了256扇区左右。(下面除avgrq-sz,avgqu-sz外,其它值每秒的波动很大,不可作为参考)

[root@node2 ~]# iostat -xm 1 100
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00    0.50   24.81    0.00   74.69

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.00     0.00   38.00    0.00     4.75     0.00   256.00     2.00   51.32   51.32    0.00  26.37 100.20
sdb               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
scd0              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-0              0.00     0.00   38.00    0.00     4.75     0.00   256.00     2.00   51.32   51.32    0.00  26.37 100.20
dm-1              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-2              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-3              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-6              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-5              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-4              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00 

设置预读大小为2048

设置预读大小为2048后,读取速度达到30.6 MB/s

[root@node2 ~]# /sbin/blockdev --setra 2048 /dev/mapper/centos-root
[root@node2 ~]# sync
[root@node2 ~]# echo 3 > /proc/sys/vm/drop_caches
[root@node2 ~]# dd if=testdata bs=8192 count=100000 of=/dev/null
98828+1 records in
98828+1 records out
809600000 bytes (810 MB) copied, 26.4212 s, 30.6 MB/s 

相应的每个读请求的大小也扩大到了1024扇区左右。

[root@node2 ~]# iostat -xm 1 100
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00    1.51   23.62    0.00   74.87

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.00     0.00   67.00    0.00    32.33     0.00   988.18     3.48   51.48   51.48    0.00  14.91  99.90
sdb               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
scd0              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-0              0.00     0.00   68.00    0.00    33.00     0.00   993.88     3.48   50.74   50.74    0.00  14.69  99.90
dm-1              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-2              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-3              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-6              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-5              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-4              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00 

 1024是这个设备每次读请求的最大扇区数,由于预读的大小是2048,所以可以看到IO队列深度提高到了3.48,比前面的256时的2高出将近1倍。

[root@node2 ~]# blockdev --getmaxsect  /dev/mapper/centos-root
1024 


结论


在单个应用进行同步读操作时,可以通过avgrq-sz和 avgqu-sz看出有没有进行预读优化,没有预读时通常avgrq-sz小于等于read()请求的size,avgqu-sz小于等于1。有预读时,avgrq-sz和avgqu-sz会相应增大,充分利用IO设备的处理能力。

参考

关于预读算法的说明可参考下面的第一篇文章,预读算法会尽量避免对随机读的预读,防止无效的预读。

  • http://os.51cto.com/art/200910/159067.htm
  • http://tech.hexun.com/2011-03-28/128268656.html
<think>好的,用户现在想了解如何优化PostgreSQL数据库性能,具体询问调优方法与最佳实践。我需要根据用户之前的对话历史相关引用内容来构建回答。首先,回顾之前的对话,用户之前询问了关于RFID条形码的成本效益分析,现在转向数据库优化,这可能是他们项目中的另一个需求。 用户提供的引用内容主要集中在PostgreSQL的参数调优工具具体参数设置,比如shared_buffers、work_mem等,还提到了postgresqltuner.pl这个工具。用户可能希望得到一个结构化的调优指南,涵盖参数配置、工具使用以及最佳实践。 首先,我需要确定回答的结构。通常,性能调优会涉及多个层面:配置参数、查询优化、硬件索引、维护任务等。引用中提到的参数如shared_buffers、work_mem、effective_cache_size、maintenance_work_memwal_buffers都是关键点,需要详细解释每个参数的作用优化建议。 然后,考虑用户提到的postgresqltuner.pl工具,这是一个自动化的调优脚本,能够分析数据库状态并提供建议。需要介绍如何使用这个工具,包括安装步骤命令示例,并结合引用中的例子,比如具体的命令行参数。 此外,用户可能对查询优化感兴趣,比如避免全表扫描、使用EXPLAIN分析执行计划等。引用中提到的查询优化器生成执行计划依赖于统计信息、表结构SQL写法,这部分需要展开说明,强调统计信息的重要性,并建议定期执行ANALYZE。 还需要包括硬件存储优化的内容,比如使用SSD、调整文件系统参数,虽然引用中没有直接提到,但这是常见的优化点。索引优化部分,可以提到创建合适索引、定期重建索引,引用中提到维护操作如CREATE INDEXVACUUM,可以关联maintenance_work_mem的设置。 维护策略方面,引用中提到了VACUUMANALYZE,需要解释自动清理手动维护的最佳实践,以及如何配置autovacuum参数。 最后,监控工具部分,除了postgresqltuner.pl,还可以提到pg_stat_statementspgBadger,这些虽然在引用中没有出现,但属于常用工具,可以增强回答的全面性。 需要确保回答符合用户要求的格式:使用中文,数学表达式用$...$,独立公式用$$...$$,结构清晰,分步骤说明,并生成相关问题。同时,引用中的内容要正确标注,如[^1]、[^2]等,但用户提供的引用标记可能需要调整,比如引用[1]到[4]对应[^1]到[^4]。 检查是否有遗漏点,例如连接池配置、分区表、并行查询等,这些虽然引用中没有提到,但属于PostgreSQL调优的常见实践,可以简要提及以增加回答的完整性。同时,确保建议具体,比如给出参数设置的示例值,并解释如何根据系统资源调整。 最后,生成的相关问题需要围绕调优的不同方面,如参数配置、工具使用、索引优化、查询分析等,帮助用户进一步探索。</think>### PostgreSQL数据库性能调优方法与最佳实践 以下从**参数配置、查询优化、硬件调优、监控工具**四个核心维度展开,结合引用内容中的技术要点与行业经验: --- #### 一、核心参数调优 根据引用[1][4]的实践经验,优先调整以下关键参数: | **参数** | **作用与优化建议** | **计算公式/示例值** | |-----------------------|---------------------------------------------------------------------------------|--------------------------------------------| | `shared_buffers` | 共享内存缓冲区,减少磁盘IO:<br>- 建议设置为物理内存的**25%-40%**(如64GB内存设为16GB)[^4] | `shared_buffers = 16GB` | | `work_mem` | 单次排序/哈希操作内存:<br>- 避免临时文件写入,根据并发量调整(如并发50时设为`32MB`)[^4] | `work_mem = 32MB` | | `effective_cache_size`| 优化器假设可用内存量:<br>- 设为物理内存的**50%-75%**(如64GB内存设为48GB)[^4] | `effective_cache_size = 48GB` | | `maintenance_work_mem`| 维护操作(VACUUM/INDEX)内存:<br>- 建议设为物理内存的**5%-10%**(如64GB内存设为4GB)[^4] | `maintenance_work_mem = 4GB` | | `wal_buffers` | 事务日志缓冲区:<br>- 默认16MB,高写入场景可提升至`64MB`[^4] | `wal_buffers = 64MB` | **调整方法**: ```sql -- 动态修改(无需重启) ALTER SYSTEM SET shared_buffers = '16GB'; -- 永久生效需修改postgresql.conf后重启 ``` --- #### 二、查询优化策略 1. **避免全表扫描** - 使用`EXPLAIN ANALYZE`分析执行计划,确保查询走索引[^1] - 示例: ```sql EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 100; ``` 2. **统计信息更新** - 定期执行`ANALYZE`更新表统计信息(优化器依赖此生成计划)[^1] - 自动配置: ```sql ALTER TABLE orders SET (autovacuum_analyze_scale_factor = 0.01); ``` 3. **SQL写法优化** - 避免`SELECT *`,明确返回字段 - 使用`JOIN`替代嵌套子查询 - 分页查询用`LIMIT/OFFSET`优化为游标 --- #### 三、硬件与存储优化 | **优化方向** | **具体措施** | |------------------|---------------------------------------------------------------------------| | **存储介质** | 使用SSD替代HDD,IOPS提升10倍以上 | | **文件系统** | 选择XFS或ZFS,调整预读参数:<br>`blockdev --setra 8192 /dev/sda` | | **内存分配** | 确保`shared_buffers + work_mem * max_connections < 总物理内存` | --- #### 四、自动化调优工具 1. **postgresqltuner.pl**(引用[2][3]) - **安装与运行**: ```bash wget https://raw.githubusercontent.com/jfcoz/postgresqltuner/master/postgresqltuner.pl chmod +x postgresqltuner.pl ./postgresqltuner.pl --host=localhost --user=postgres ``` - **核心功能**: - 识别缺失索引 - 检测缓存命中率(建议>99%) - 分析锁竞争与长事务 2. **监控工具扩展** - `pg_stat_statements`:统计SQL执行耗时 - `pgBadger`:日志分析生成性能报告 --- #### 五、维护最佳实践 1. **定期维护任务** - 手动执行`VACUUM FULL`回收空间(低峰时段) - 重建索引提升查询效率: ```sql REINDEX INDEX idx_orders_user_id; ``` 2. **连接池配置** - 使用`pgBouncer`控制连接数,避免`max_connections`过高导致内存溢出 3. **版本升级策略** - 小版本及时更新(如14.5→14.6)修复性能缺陷 --- ### 性能瓶颈排查流程图 ```mermaid graph TD A[发现性能问题] --> B{检查CPU/内存/IO} B -->|IO高| C[分析shared_buffers配置] B -->|CPU高| D[检查慢查询与索引] C --> E[调整shared_buffers或升级SSD] D --> F[优化SQL或添加缺失索引] ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值