Postgresql 和 ZFS
为什么我需要 ZFS 而不是内置的 TOAST?
对于 tghub,我使用了一个相当便宜的 VPS,只有 1TB 的存储空间。所以我需要压缩我的数据。尽管 Postgresql 有 TOAST 功能(大型属性存储技术),但它不适合我。默认情况下,TOAST 针对大小为 2 kB 的文本数据触发。我的项目 tghub 的消息表有将近 30 亿行,并且还在不断增长,但它们通常都很小,因此 TOAST 对我不起作用。我决定尝试将消息数据存储在单独的表空间中并将其移动到 ZFS 文件系统。
高层级架构
当前性能
我设法在不同的驱动器之间达到了良好的平衡。
- sda -- 默认表空间
- sdb -- ZFS 表空间
- sdc -- 索引表空间
在正常工作负载下,索引盘是最忙的,这是预期的。该盘有 2 个索引,通过随机插入(每秒大约 800 行)进行更改。最好不要过度加载具有默认表空间的驱动器,因为它有用于搜索的索引。当很多用户同时决定搜索某些东西时,这个磁盘应该有足够的容量。
调整 Postgresql 和 ZFS
我为 zfs 和 postgresql 做了一些额外的配置:
- 关闭 TOAST,不要重复压缩数据:
sql
ALTER TABLE channel_message
ALTER COLUMN text SET STORAGE EXTERNAL;
- 遵循 zfs 的数据库建议,将扇区大小设置为 32K。默认大小是 128K。太大了,会导致不必要的读取。我们甚至可以将扇区大小设置为 8K,但这会降低压缩比。所以在读取速度(较小的扇区)和压缩比(较大的扇区)之间找到平衡很重要。
shell
sudo zfs set recordsize=32K datapool
- 关闭更新时间,这真的没有意义:
shell
sudo zfs set atime=off datapool
- 设置压缩为 zstd,它比 lz4 慢,但有更好的压缩比(对于文本数据可以达到 x2):
shell
sudo zfs set atime=off datapool
目前,我的 channel_message 表有将近 30 亿行,在 ZFS 驱动器中未压缩时占用 1061Gb,而压缩后为 291Gb。压缩比超过 3 倍!