如何通过更新(软件和硬件)为重I / O优化数据库


20

这种情况 我有一个PostgreSQL 9.2数据库,它一直在大量更新。因此,该系统受I / O限制,我目前正在考虑进行另一次升级,我只需要一些有关从何开始改进的指导。

这是过去三个月情况的图片:

在此处输入图片说明

如您所见,更新操作占据了大多数磁盘利用率。这是在更详细的3小时窗口中情况的另一幅图片:

在此处输入图片说明

如您所见,峰值写入速率约为20MB / s

软件 服务器正在运行ubuntu 12.04和postgresql 9.2。更新类型通常是在ID标识的各个行上进行小更新。例如UPDATE cars SET price=some_price, updated_at = some_time_stamp WHERE id = some_id。我已经尽可能地删除和优化了索引,并且服务器配置(Linux内核和postgres conf)也都进行了优化。

硬件 硬件是一台专用服务器,在RAID 10阵列中具有32GB ECC ram,4个600GB 15.000 rpm SAS磁盘,由带BBU的LSI RAID控制器和Intel Xeon E3-1245 Quadcore处理器控制。

问题

  • 对于这种口径的系统(读/写),图表显示的性能是否合理?
  • 因此,我应该集中精力进行硬件升级还是对软件进行更深入的研究(内核调整,conf,查询等)?
  • 如果进行硬件升级,磁盘数量是性能的关键吗?

------------------------------更新------------------- ----------------

我现在已经用四个Intel 520 SSD而不是旧的15k SAS磁盘升级了我的数据库服务器。我正在使用相同的RAID控制器。事情已经大大改善了,从下面的内容可以看出,I / O的峰值性能提高了6到10倍左右-太好了! 在此处输入图片说明 但是,根据答案和新SSD的I / O功能,我期望有20-50倍的改进。因此,这里还有另一个问题。

新问题 我当前的配置中有什么限制我的系统的I / O性能(瓶颈在哪里)?

我的配置:

/etc/postgresql/9.2/main/postgresql.conf

data_directory = '/var/lib/postgresql/9.2/main'
hba_file = '/etc/postgresql/9.2/main/pg_hba.conf'
ident_file = '/etc/postgresql/9.2/main/pg_ident.conf'
external_pid_file = '/var/run/postgresql/9.2-main.pid'
listen_addresses = '192.168.0.4, localhost'
port = 5432
unix_socket_directory = '/var/run/postgresql'
wal_level = hot_standby
synchronous_commit = on
checkpoint_timeout = 10min
archive_mode = on
archive_command = 'rsync -a %p postgres@192.168.0.2:/var/lib/postgresql/9.2/wals/%f </dev/null'
max_wal_senders = 1
wal_keep_segments = 32
hot_standby = on
log_line_prefix = '%t '
datestyle = 'iso, mdy'
lc_messages = 'en_US.UTF-8'
lc_monetary = 'en_US.UTF-8'
lc_numeric = 'en_US.UTF-8'
lc_time = 'en_US.UTF-8'
default_text_search_config = 'pg_catalog.english'
default_statistics_target = 100
maintenance_work_mem = 1920MB
checkpoint_completion_target = 0.7
effective_cache_size = 22GB
work_mem = 160MB
wal_buffers = 16MB
checkpoint_segments = 32
shared_buffers = 7680MB
max_connections = 400 

/etc/sysctl.conf

# sysctl config
#net.ipv4.ip_forward=1
net.ipv4.conf.all.rp_filter=1
net.ipv4.icmp_echo_ignore_broadcasts=1
# ipv6 settings (no autoconfiguration)
net.ipv6.conf.default.autoconf=0
net.ipv6.conf.default.accept_dad=0
net.ipv6.conf.default.accept_ra=0
net.ipv6.conf.default.accept_ra_defrtr=0
net.ipv6.conf.default.accept_ra_rtr_pref=0
net.ipv6.conf.default.accept_ra_pinfo=0
net.ipv6.conf.default.accept_source_route=0
net.ipv6.conf.default.accept_redirects=0
net.ipv6.conf.default.forwarding=0
net.ipv6.conf.all.autoconf=0
net.ipv6.conf.all.accept_dad=0
net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.all.accept_ra_defrtr=0
net.ipv6.conf.all.accept_ra_rtr_pref=0
net.ipv6.conf.all.accept_ra_pinfo=0
net.ipv6.conf.all.accept_source_route=0
net.ipv6.conf.all.accept_redirects=0
net.ipv6.conf.all.forwarding=0
# Updated according to postgresql tuning
vm.dirty_ratio = 10
vm.dirty_background_ratio = 1
vm.swappiness = 0
vm.overcommit_memory = 2
kernel.sched_autogroup_enabled = 0
kernel.sched_migration_cost = 50000000

/etc/sysctl.d/30-postgresql-shm.conf

# Shared memory settings for PostgreSQL
# Note that if another program uses shared memory as well, you will have to
# coordinate the size settings between the two.
# Maximum size of shared memory segment in bytes
#kernel.shmmax = 33554432
# Maximum total size of shared memory in pages (normally 4096 bytes)
#kernel.shmall = 2097152
kernel.shmmax = 8589934592
kernel.shmall = 17179869184
# Updated according to postgresql tuning

输出 MegaCli64 -LDInfo -LAll -aAll

Adapter 0 -- Virtual Drive Information:
Virtual Drive: 0 (Target Id: 0)
Name                :
RAID Level          : Primary-1, Secondary-0, RAID Level Qualifier-0
Size                : 446.125 GB
Sector Size         : 512
Is VD emulated      : No
Mirror Data         : 446.125 GB
State               : Optimal
Strip Size          : 64 KB
Number Of Drives per span:2
Span Depth          : 2
Default Cache Policy: WriteBack, ReadAhead, Direct, Write Cache OK if Bad BBU
Current Cache Policy: WriteBack, ReadAhead, Direct, Write Cache OK if Bad BBU
Default Access Policy: Read/Write
Current Access Policy: Read/Write
Disk Cache Policy   : Disk's Default
Encryption Type     : None
Is VD Cached: No

(1)。如果未对列进行索引,则可以利用HOT(请参见git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/…)。(2)。synchronous_commit = off阅读postgresql.org/docs/9.2/static/wal-async-commit.html中的文档后,尝试使用。(3)。您的配置是什么样的?例如。该查询的结果:SELECT name, current_setting(name), source FROM pg_settings WHERE source NOT IN ('default', 'override');
bma

@bma让我添加以下警告synchronous_commit'异步提交是一个选项,它可以使事务更快地完成,但如果数据库崩溃,最新的事务可能会丢失。
dezso

@dezso我应该更清楚地了解我所指的文档部分。感谢您的澄清。我之所以提出这一建议,是因为我们的一台服务器处于高负载(使用Hibernate)时遭受了痛苦,所以我做出了明智的决定,决定切换到异步提交,而40%的负载实际上消失了。不建议在大多数系统上使用,但是在某些情况下,它可以为您提供服务器升级和应用程序更改之间的时间。
bma 2013年

Answers:


10

如果进行硬件升级,磁盘数量是性能的关键吗?

是的,因为硬盘(甚至SAS)的磁头需要一些时间才能移动。

要升级吗?

杀死SAS光盘,然后转到SATA。插入SATA SSD-企业级产品,例如Samsung 843T。

结果?每个驱动器可以执行大约60.000(即60,000)IOPS。

这就是SSD成为DB空间中的杀手and并且比任何SAS驱动器便宜得多的原因。Phyiscal旋转光盘只是跟不上光盘的IOPS功能。

首先,您的SAS光盘是一个中等的选择(太大而无法获得很多IOPS)。对于使用量更大的数据库(更多的较小的光盘将意味着更多的IOPS),但是最后,SSD改变了游戏规则。

关于软件/内核。任何体面的数据库都会执行很多IOPS并刷新缓冲区。为了保证基本的ACID条件,需要写入日志文件。您唯一可以做的内核调整将使您的事务完整性无效-您可以部分摆脱这一点。处于回写模式的Raid控制器将执行此操作-确认写入是否已刷新(即使未刷新)-但之所以可以这样做是因为假定BBU在停电的那天是安全的。您在内核中做得更高的任何事情-更好地知道您可以承受负面影响。

最后,数据库需要IOPS,您可能会惊讶地发现与此处的其他设置相比,您的设置有多小。我已经看到有100多个光盘的数据仓库,只是为了获得所需的IOPS。但是,实际上,今天,您购买了SSD并对其进行了尺寸测试-它们在IOPS功能方面非常出色,因此与SAS驱动器抗衡这场比赛毫无意义。

是的,您的IOPS编号对于硬件来说还不错。在我所期望的范围内。


6

如果负担得起,请将pg_xlog放在其自己的控制器上的单独RAID 1驱动器对上,并配置了电池供电的RAM用于回写。即使在其他所有内容都在SSD上时也需要对pg_xlog使用旋转​​锈蚀也是如此。

如果使用SSD,请确保它具有超级电容器或其他方法,以在断电时持久保存所有缓存的数据。

通常,更多的主轴意味着更多的I / O带宽。


不幸的是,我在RAID控制器中只有四个硬盘插槽。如果所有其他磁盘都是SSD的,为什么还要将pg_xlogs放在单独的阵列上?
尼尔斯·克里斯蒂安

2
@NielsKristian我说对了,当我说在大多数系统中,事务日志是光盘上写得最多的东西。另外,写入它基本上与写入数据并行。由于磁头位于pg_xlog或数据文件夹上,因此无法使用HDD同时完成两者。(严重的简化警报!)将两个任务分开可以将IO负担分散到两个独立的磁盘/阵列上。
dezso 2013年

2
除了什么@dezso说,硬盘是存储专用于WAL OK,因为访问是几乎完全连续的,所以寻道时间是最小的...
kgrittn

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.