postgresql调优实践

1、性能优化

1.1 目标

10Gbps流量,按每秒10w条/s日志量估算,每个日志按500B算。需要50MB/s磁盘写入,一天4T日志量。

1.2  磁盘性能测试

在10.67.5.69上测试,宿主机215,做了raid。

 iops(每秒执行的IO次数)、bw(带宽,每秒的吞吐量)、lat(每次IO操作的延迟)

当每次IO操作的block较小时,如512bytes/4k/8k等,测试的主要是iops。

当每次IO操作的block较大时,如256k/512k/1M等,测试的主要是bw。

1.2.1 dd测试

(i/oflag,不用缓存,直接写盘,测实际速度)

iops——写测试 dd if=/dev/zero of=./a.dat bs=512 count=1000000 oflag=direct                   8000左右         

iops——读测试 dd if=./a.dat of=/dev/null bs=512 count=1000000 iflag=direct                      10278左右 

bw——写测试 dd if=/dev/zero of=./a.dat bs=1M count=8000 oflag=direct                            354MB/s

bw——读测试 dd if=./a.dat of=/dev/null bs=1M count=8000 iflag=direct                                1.1GB/s            

1.2.2 fio测试

随机顺序及混合读写。更准确、精细。

测试脚本参考:run_fio.sh

1.3 优化方向

1、事务

2、配置

synchronous_commit:off            写到缓存中就会向客户端返回提交成功,但也不是一直不刷到磁盘,延迟写入磁盘  参考:https://blog.csdn.net/DB_su/article/details/78224137

shared_buffers:            通过 shared_buffers 和内核和磁盘打交道,因此应该尽量大,让更多的数据缓存在 shared_buffers 中。通常设置为实际 RAM 的 10% 是合理的。要在系统中设置 kernel.shamax 的值,该值决定了进程可调用最 大共享内存数量(ipcs -l)。kernel.shmmax = postgres shared_buffers + 32MB(不按此法算)

work_mem:增加 work_mem 有助于提高排序的速度。通常设置为实际 RAM 的 2% – 4%

effective_cache_size:设置稍大,优化器更倾向使用索引扫描而不是顺序扫描,建议的设置为可用空闲内存的 25%,这里的可用空闲内存指的是主机物理内存在运行 pg 时的空闲值。

maintenance_work_mem:这里定义的内存只是在 CREATE INDEX, VACUUM 等时用到,因此用到的频率不高,但是往往这些指令消耗比较多的资源,因此应该尽快让这些指令快速执行完毕:给 maintence_work_mem 大的内存,比如 512M(524288)

max_connections:max_connections 的目的是防止 max_connections * work_mem 超出了实际内存大小。

fsync:设定 sync=no 关闭 fsync 的话, PostgreSQL 不会等待 WAL 写回硬盘,就直接返回 query 成功。通常这个会带来 15-25% 的性能提升.但是缺点就是,如果系统崩溃(断电, PostgreSQL 挂掉)的时候,你将有可能丢失最后那个 transcation. 不过这个并不会造成你系统的数据结构问题。如果说在系统出问题的时候丢失1-2笔数据是可以接受的,那么 25% 的性能提升是很可观的。

wal:依赖于fsync

commit_delay:延迟提交

3、copy插入 延后写

4、prepare预规划

5、多行插入(和4选一种)

6、多连接/多线程插入:速度上有优势,但是把握不好容易造成资源占用率过高,连接数太大也容易影响其他应用;

7、写入更新:写入更新是postgresql新特性,使用会造成一定的性能消耗(相对直接插入);

8、触发器和存储过程能不用则不用

9、索引在插入时慢,查询时快,重建索引:减少索引使用

10、大页内存使用

11、表结构,分库分表

12、unlogged table::Create unlogged table。。unlogged table 在遇到Postgre服务器异常重启后会丢失全部数据,所以如果你的数据不允许丢失,请不要使用。

13、autovacuum:off              手动定期vacuum

14、多个字段联合为一个字段,json化

1.4 优化验证

以字段最多的storage_sample为例,进行全字段插入优化。

分析手段:explain analyze

1.4.1 具体手段

无优化:插入10000条数据,26s,平均384条/s,调试版程序和非调试版程序无差别,磁盘tps在700-800左右

加了事务:10000条/s(每轮事务提交多少条要测试给出)

改了一段当前配置,效果提升不大,可能在大的异构数据量的时候有效

默认采用prepared预规划

unlogged table:有效,大数据量稳定的10000/s

copy导入:命令行操作,1000000/12s=83333,单线程。实现起来有两种方案,都比较耗时:

          1、结合文件copy,需要先弄到文件再执行copy命令;

          2、结合snprintf,用数组缓存。预分配一个大的内存做缓存,然后用snprintf、strncat操作,实测,50000条日志就花了57s。

多线程:已实施,在写入能力上应该是倍数关系。每张日志表创建一个连接来进行事务写入。

多个字段json:目前没有实施,考虑到两个问题,1、转化为json,需要使用snprintf,会有性能影响;2、目前web前端查询还是用的单字段查询,改了之后会影响当前的web显示。

编码引起的入库失败问题:对于非法字符,建议在应用层进行过滤,在数据库中转换,影响写入速度,同时会使得数据库的开销变大。实在是万不得已的行为。入库失败的根因就是同时使用UTF8和GBK编码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值