我正在使用python编写索引器,该索引器为文档建立索引并将其插入数据库中,在此之前是单个进程,但现在我运行了4个并行进程进行多处理。每次提取文本后,它将插入数据库并进行提交。
现在,它遇到了IO问题,主要的IO问题不是我的进程,而是EXT4的jdb2监视系统。它达到了99.99%,并导致CPU在每个MySQL Commit中等待IO。
我看到许多人在互联网上遇到了这个问题,他们的解决方案是使用barrier = 0进行安装。那会完全禁用日记功能吗?我的服务器具有UPS,并且很愿意这样做吗?
我正在使用python编写索引器,该索引器为文档建立索引并将其插入数据库中,在此之前是单个进程,但现在我运行了4个并行进程进行多处理。每次提取文本后,它将插入数据库并进行提交。
现在,它遇到了IO问题,主要的IO问题不是我的进程,而是EXT4的jdb2监视系统。它达到了99.99%,并导致CPU在每个MySQL Commit中等待IO。
我看到许多人在互联网上遇到了这个问题,他们的解决方案是使用barrier = 0进行安装。那会完全禁用日记功能吗?我的服务器具有UPS,并且很愿意这样做吗?
Answers:
将数据库放在非日志文件系统上。至少较大的服务器(oracle,sql服务器)具有自己的日志功能(事务日志),并相应地优化其IO。您将日志和数据库放在单独的文件系统和光盘上,并依靠数据库内部功能来处理不良IO。通常,除了写入日期外,文件系统通常都不会发生任何更改(较大的设置),因为文件不会扩展-它们将以“最终”大小生成(好了,管理员可以更改),并且更改是我所说的数据库跟踪的级事务日志。
您可能还想告诉我们您的硬件层是什么。大多数人低估了IOPS是数据库的限制因素,并认为小型磁盘集是大型数据库的合适环境。尽管我们中的一些人在使用大量光盘的数据库上工作,因此潜在地支持更多的IOPS。
在弹性和性能之间总会有一个权衡。
在ext4上使用MySQL时,默认的barriers = 1确实会导致速度变慢,但是第一个操作不应是禁用日记功能或打开data = writeback。
首先,如果恢复能力至关重要,那么电池供电的RAID当然是值得的。
我选择的安装选项,尤其是在非电池支持的RAID上:
/dev/mapper/vg-mysql--data /var/lib/mysql/data ext4 defaults,noatime,nodiratime,barrier=1,data=ordered 0 0
这是有意不使用data = writeback的,因为我不想冒文件系统损坏的风险,导致“崩溃和日志恢复后,旧数据出现在文件中”(引用来自man mount)。
为了使I / O相关设置具有全面的弹性,my.cnf中的理想配置是:
[mysqld]
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
我选择了以下折衷顺序以提高性能:
sync_binlog = 0:这是我第一个脱离完全弹性的MySQL配置。这样做的原因是,它可以显着提高性能,尤其是在某些情况下binlog_format=row(不幸的是,对于Jira而言)。我在集群中使用了足够的MySQL副本,如果binlog因断电而损坏,我将从另一个副本进行二进制复制。innodb_flush_log_at_trx_commit = 2:虽然要完全符合ACID的要求,值为1,但值为2“,则在每次提交时,日志缓冲区都会写到文件中,但不会对其执行刷新到磁盘的操作。值也为2时,日志文件也会每秒发生一次。请注意,由于流程调度问题,每秒刷新一次并不能保证100%每秒发生一次。” (引自MySQL文档)data=writeback。请注意,如果这是您的根文件系统,则还需要传递内核命令行选项。我在coderwall上做了一些步骤。innodb_flush_method。显示O_DIRECT可以在某些工作负载中提高性能,但是并不能在您的环境中正常工作。innodb_io_capacity,并调整设置,如innodb_adaptive_flushing,innodb_read_io_threads,innodb_write_io_threads,innodb_purge_threads,和其他可能的设置。您的I / O后端很可能无法很好地应对负载。您应确保文件系统未记录数据。我建议使用data=writeback,relatime,nobarrier参数来为数据库的数据分区安装,这是第一个快速,肮脏的优化。
同样,从症状中推论出,您显然没有在控制器上使用写缓存。您应该确保在控制器上使用电池备份或闪存备份写缓存并启用它-这应该在不大幅增加数据丢失或损坏风险的情况下显着提高性能。请注意,在没有电池或闪存备份的情况下使用写缓存确实会大大增加数据丢失或损坏的风险 -因此,仅出于测试目的和/或您可以承担丢失的目的而这样做。
nobarrier一样的barrier=0吗?
这是一个老问题,但是上周我们在一台新的专用服务器上遇到了相同的问题(高IO等待和可怕的插入/更新速度),此解决方案直接解决了这个问题。
禁用tune2fs -O "^has_journal" /dev/<drive>日记功能是最快的解决方案,因为它消除了JDB2流程带来的IO等待。但是,除非有电池驱动器,否则不建议这样做,因为如果发生崩溃,数据将会丢失。如果您doublewrite在MySQL中启用了InnoDB表,则它是安全的。但是.frm,日志等文件并不安全。我们尝试将这些文件移动到另一个驱动器(尤其是bin日志),但是jdb2 IO等待仍然持续。因此,这并没有使我们感到很自在。
data=writeback,relatime,nobarrier与在整个分区上禁用日志记录一样,它并没有帮助它加快写入/读取速度。ext4的更多选项在EXT4文档中。
在我们这个案例中,真正的罪魁祸首是sync_binlog。我们已成立是1在/etc/mysql/my.cnf它被杀死的性能。
Percona在这里对此进行了验证。我们将其设置为默认值,0性能猛增了500%以上。
您正在使用哪个数据库引擎来插入此数据?
如果是MyISAM:必须在写入过程中锁定整个表,那么运行并发插入线程将杀死任何系统,无论其功能多么强大。
确保您将InnoDB用于这些表。
另外,与mysql没有直接关系,但是某些HD由于积极的电源管理而使ext4出现问题...发生这种情况时,机器负载增加而没有任何明显的活动。
尝试禁用它。首先检查您拥有的任何值(如果需要在不重新启动的情况下将其放回原处),然后将其禁用。
检查当前值:
hdparm -B /dev/sda
禁用它
hdparm -B 255 /dev/sda
(或您的高清硬盘)并进行测试。可能对大多数问题都无济于事,但可能对那里的某些用户有所帮助。重新启动将重置该值,或手动将255替换为先前的值。
如果有帮助,请通过在启动时进行设置来检查/etc/default/hdparm或/etc/hdparm.conf以获得更永久的配置。