PostgreSQL优化简介

1. 优化简介

PostgreSQL数据库优化是多方面的,原则是减少系统的瓶颈,减少资源的占用,增加系统的反应速度,主要优化的方向可考虑如下几点:

1)服务器硬件方面

2)文件系统方面,例如通过优化文件系统,提高磁盘IO的读写速度;通过优化操作系统调度策略,提高PostgreSQL的在高负荷情况下负载能力等。

3)数据库层面,例如数据库参数、表结构、索引、查询语句等优化方面。

接下来我们详细看一下,整体的优化思路:

2. 详细分析

2.1. 硬件配置建议

1)配置较大的内存。足够大的内存,是提高PostgreSQL数据库性能的方法之一。内存的速度比磁盘I/0快得多,可以通过增加系统的缓冲区容量,使数据在内存中停留的时间更长,以减少磁盘I/0。

2)配置高速磁盘系统,以减少读盘的等待时间,提高响应速度。

3)合理分布磁盘I/O,把磁盘I/O分散在多个设备上,以减少资源竞争,提高并行操作能力。

4)配置多处理器,PostgreSQL是多线程的数据库,多处理器可同时执行多个线程。

2.2. 硬件层推荐

1)CPU:CPU数量、核心等越多,以及频率越高,性能越好。

2)内存:内存频率越高,容量越大,性能越强大,一般推荐使用ECC(带有校验的内存),一般情况下为16G~128G。

3)磁盘:如果是机械硬盘,转速越高,速度越快。一般情况下推荐使用SAS机械盘、PCI-E SSD、FLASH等硬盘。

4)raid分配:建议使用raid5、raid10。

5)网卡:如果是多个网卡,建议将多个网卡进行bonding,最好是主备模式。

2.3. 文件系统层面优化

2.3.1. IO调度工具调优

cfq公平调度算法:为每个进程和线程单独创建一个队列来管理该进程的I/O请求,为这些进程和线程均匀分配I/O带宽,适合通用服务器,是linux系统中默认的调度算法。

noop电梯调度算法:它基于FIFO队列实现,所有I/O请求先进先出,适合SSD。

deadline保障算法:它为读和写分别创建FIFO队列,当内核收到请求时,先尝试合并,不能合并则尝试排序放入队列中,并且尽量保证在请求达到最终期限时进行调度,避免有一些请求长时间不能得到处理。适合虚拟机或I/O压力比较重的场景,例如数据库服务器。

1)查看调度算法:

cat sys/block/sda/queue/scheduler

2)修改调度算法:

echo noop >/sys/block/sda/queue/scheduler

grubby —update-kernel=ALL —args=”elevator=noop”

2.3.2. 预读参数调整

在内存中读取数据比从磁盘中读取要快很多,增加Linux内核预读,对于大量顺序读取的操作,可以减少I/O的等待时间。

如果应用场景中有大量的小文件,过多的预读会造成资源的让费。所以该值应该在实际环境中多次测试。

1)查看磁盘预读扇区:

blockdev —getra dev/sda

2)通过命令设置磁盘预读扇区(可以设置到16384或者更大)

blockdev —setra 16384 /dev/sda

echo 16384 /sys/block/sda/queue/read_ahead_kb

永久生效可以将此命令添加到/etc/rc.local

2.3.3. 透明大页

透明大页在运行时动态分配内存,而运行的内存分配会有延误,对于数据库管理员来讲这并不友好,所以建议关闭透明大页:

1)查看透明大页是否开启(never关闭)

cat /sys/kernel/mm/transparent_hugepage/enabled

2)关闭透明大页:

echo never > /sys/kernel/mm/transparent_hugepage/enabled

echo never > /sys/kernel/mm/transparent_hugepage/defrag

3)永久关闭:

vi /etc/rc.d/rc.local

if test -f /sys/kernel/mm/transparent_hugepage/enabled; then

echo never > /sys/kernel/mm/transparent_hugepage/enabled

fi

if test -f /sys/kernel/mm/transparent_hugepage/defrag; then

echo never > /sys/kernel/mm/transparent_hugepage/defrag

fi

2.3.4. NUMA

NUMA架构会优先在请求线程所在的CPU的local内存上分配空间,如果local内存不足,优先淘汰local内存中无用的页面,这样就会导致每个cpu内存分配不均匀,虽然可以通过配置NUMA的轮询机制缓解,但对于数据库管理员仍然不友好,建议关闭numa。

2.3.5. 内核参数方面

proc/sys/net/core/wmem_max

最大socket写buffer,可参考的优化值:873200

/proc/sys/net/core/rmem_max

最大socket读buffer,可参考的优化值:873200

/proc/sys/net/ipv4/tcp_wmem

TCP写buffer,可参考的优化值: 8192 436600 873200

/proc/sys/net/ipv4/tcp_rmem

TCP读buffer,可参考的优化值: 32768 436600 873200

/proc/sys/net/ipv4/tcp_mem

同样有3个值,意思是:

net.ipv4.tcp_mem[0]:低于此值,TCP没有内存压力.

net.ipv4.tcp_mem[1]:在此值下,进入内存压力阶段.

net.ipv4.tcp_mem[2]:高于此值,TCP拒绝分配socket.

上述内存单位是页,而不是字节.可参考的优化值是:786432 1048576 1572864

/proc/sys/net/core/netdev_max_backlog

进入包的最大设备队列.默认是300,对重负载服务器而言,该值太低,可调整到1000

/proc/sys/net/core/somaxconn

listen()的默认参数,挂起请求的最大数量.默认是128.对繁忙的服务器,增加该值有助于网络性能.可调整到256.

/proc/sys/net/ipv4/tcp_max_syn_backlog

进入SYN包的最大请求队列.默认1024.对重负载服务器,可调整到2048

/proc/sys/net/ipv4/tcp_retries2

TCP失败重传次数,默认值15,意味着重传15次才彻底放弃.可减少到5,尽早释放内核资源.

/proc/sys/net/ipv4/tcp_keepalive_time

/proc/sys/net/ipv4/tcp_keepalive_intvl

/proc/sys/net/ipv4/tcp_keepalive_probes

这3个参数与TCP KeepAlive有关.默认值是:

tcp_keepalive_time = 7200 seconds (2 hours)

tcp_keepalive_probes = 9

tcp_keepalive_intvl = 75 seconds

意思是如果某个TCP连接在idle 2个小时后,内核才发起probe.如果probe 9次(每次75秒)不成功,内核才彻底放弃,认为该连接已失效.对服务器而言,显然上述值太大. 可调整到:

/proc/sys/net/ipv4/tcp_keepalive_time 1800

/proc/sys/net/ipv4/tcp_keepalive_intvl 30

/proc/sys/net/ipv4/tcp_keepalive_probes 3

/proc/sys/net/ipv4/ip_local_port_range

指定端口范围的一个配置,默认是32768 61000,已够大.

net.ipv4.tcp_syncookies = 1

表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;

net.ipv4.tcp_tw_reuse = 1

表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;

net.ipv4.tcp_tw_recycle = 1

表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。

net.ipv4.ip_local_port_range = 1024 65000

表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。

net.ipv4.tcp_max_syn_backlog = 8192

表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。

读缓存与交换空间:

将该参数设置为0,代表在内存紧张时优先减少RAM里文件系统缓存大小。

vm.swappiness=0

禁用过度分配内存机制(进程申请多少分配多少,不考虑实际内存)

vm.overcommit_memory=2

在以下示例中,当脏页超过vm.dirty_background_ratio=5时,将启动I/O,即开始刷新/写入磁盘.当脏页总数超过vm.dirty_ratio=10时,所有写入将被阻止,直到某些脏页被写入磁盘为止。

vm.dirty_ratio=10

vm.dirty_background_ratio=5

kernel.shmmax = 509898752

kernel.shmall = 124487

计算共享内存段的最大大小,以及所有进程可以使用的共享内存总页数,可以使用如下脚本进行计算

vi shmsetup.sh

#!/bin/bash

# simple shmsetup script

page_size=getconf PAGE_SIZE

phys_pages=getconf _PHYS_PAGES

shmall=expr $phys_pages / 2

shmmax=expr $shmall \* $page_size

echo kernel.shmmax = $shmmax

echo kernel.shmall = $shmall

内核参数有很多,由于时间原因,本次就分享如上这些,感兴趣的小伙伴可以自行上网查询更多内容。

2.3.6. 其它

除了如上系统优化的内容外,其实还有很多的系统优化项目,例如格式化磁盘时的系统文件格式,selinux以及防火墙的关闭,透明大页的设置,以及文件系统的常用命令等等,这些都可以提高数据库的性能,已经稳定性,感兴趣的同学可以研究一下。

2.4. 数据库优化层面

2.4.1. 数据库版本的选择

说到数据库版本的选择,在这里不得不提到,数据库各个版本之间所增加的一些特性,从而对比到底使用哪个版本的数据库,首先我问先从PG9版本开始聊起:

2.4.1.1. 不同大版本之间的改进

pg9使用继承式分区,pg10实现了声明式分区,pg11完善了功能,pg12提升了性能。

2.4.1.2. pg10版本新特性

1)增加声明式分区

2)pg_stat_activity视图新增信息列,以前版本只是包含用户后台服务进行进程信息

3)增加了安全级别更高的密码验证的方式,SCRAM-SHA-256

4)hash索引可以走流复制,从此可以大胆使用hash索引

5)增加并行功能,引入并行索引,完全支持并行b-tree扫描和bitmap

6)引入Quorum Commit,支持同步复制多个standby

7)提供了逻辑复制功能:发布订阅功能,create publication命令

8)可以把多列组合在一起再创建直方图,让一些关联列的执行计划更准确,可创建跨列统计信息,creat

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值