
总 结
PostgreSQL 通过调用系统 fsync() 或者其他使得事务内容写入到物理磁盘,这样可以保证 *** 作系统或者数据库出现宕机后,仍然可以恢复到某一个一致性的状态。理论上讲 PostgreSQL 的 fsync 功能关闭,可以实现性能的提升,但是带来的影响就是需要承担数据的丢失,因为出现系统宕机或者数据库崩溃的时候有一些数据是没有落盘的。
本文将验证 fsync 参数的性能影响,以及参数关闭时数据库宕机后的影响。
数据量:1000W
fsync 参数:on
初始化表:user_info
pgbench 压测
pgbench 结果
pgbench 压测
pgbench 结果
数据量:1000W
fsync 参数:off
初始化表:user_info
pgbench 压测
pgbench 结果
pgbench 压测
pgbench 结果
通过对比发现,将 fsync 改为 off,对于读 TPS,参数 fsync 的影响不大,对于写 TPS,性能有一定提升。
现在验证参数关闭时数据库宕机后的影响
首先,使用将数据库性能跑起来
然后,模拟服务器断电
之后,启动数据库
提示信息:比致命错误还过分的错误。
结果:数据库无法启动,原因就是因为无法找到一个有效的 checkpoint 记录,这就是因为 fsync 设置为 off,由于数据库异常宕机导致。可以通过使用 pg_resetxlog 恢复数据库,但是会造成部分数据无法找回,数据丢失;也可以通过备份恢复,同样也会丢失部分数据。
fsync 参数对于读 TPS 的性能影响不大,对于写 TPS 的性能有一些影响,设置为 off,写 TPS 性能有一定提升,但是存在数据库宕机后无法正常启动,即使恢复后启动数据库,也会有数据丢失的很大风险。因此生产环境非必要时,不要将此参数设置为 off,还是使用默认的 on 比较稳妥。
sequence 是 pg 自带的高效的自增id工具(也叫序列)。sequence 使用了轻量级锁的方式来做到高效自增id的,所以会比 UPDATE 行锁快。sequence 的返回数据类型默认是64位的整数,pg 10 可以自定 smallint, integer 或者是 bigint。
sequence 是可以保证自增数据不重复的,也就是说每次自增后都会持久化保存,那么为了继续提高性能,可以加上 CACHE 参数(默认为1),每个进程(连接)可以缓存一个子序列在当前进程内存里面,当子序列用完了才会去原序列取新的子序列。
这个用个例子简单说一下,创建 sequence temp_seq3 时用了 CACHE 10,A session 可以获取到的值是 1...10,B session 可以获取到的值是 11...20,那么获取顺序可能是 (A, A, B, A),返回值是 (1, 2, 11, 3),这个不是严格自增的序列,但可以保证回次返回都是唯一的,用了 CYCLE 参数的除外。
根据文档和源码( link 第80行),缓存在内存里面的最大值(cached)是每个进程都不一样的,所以如果要求严格自增的服务不能用 CACHE。
这里写三种用 pg 做自增id的方式
测试命令,在 MacOS 上用 docker 开一个 pg 在里面运行一下 pgbench 脚本,其中 sql.sql 的内容替换成对应的压测脚本。
TPS: 986
TPS: 7332
TPS: 7451
看看微信的分布式id生成器,原理都差不多,"实际应用中每次提升的步长为10000" = "CACHE 10000"。 link
以上优化已经是用在友好速搭电商系统的订单号和优惠券号生成服务中,为商家提供更快更可靠的服务。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)