RSS Telegram YouTube Apple Яндекс Spotify Amazon Почта

74. gofpdf, PostgreSQL HOT & fillfactor

20.10.2024

Скачать

К списку выпусков

Ссылки выпуска:

gofpdf и subset шрифтов

На этой неделе возникло острое желание сократить размер PDF-файла, который я генерирую. Нужный мне документ - это этикетка, лейбл, который наносят на посылки размером 6 на 4 дюйма. Это стандартный размер для печати на специализированных термопринтерах для последующего нанесения на посылки. Так вот лейбл, который я генерирую занимает 180Кб и мне стало интересно как можно его уменьшить.

Для начала стоит разобраться, а действительно ли PDF - это подходящий формат? Какие у нас есть варианты? Можно, например, раздавать изображение, но у изображения нет метаданных о размере документа, т.е. размере листа, на котором нужно будет это изображение распечатать. Еще один вариант - это ZPL. Это декларативный язык программирования, с помощью которого можно описать документ, его размер, содержимое. Однако, ZPL без специальных ритуалов нельзя посмотреть на десктопе. Еще один вариант - это LaTeX. Это текстовый язык разметки, созданный около 40 лет назад и до сих пор активно используемый для написания научных публикаций и т.д. Документ в LaTeX легко конвертируется в PDF. Имея некоторый опыт, считаю, что PDF подходит идеально, т.к. он содержит информацию о размере листа, поддерживает встраивание шрифтов и его понимают большинство платформ.

Изучив подробно свой PDF файл я обнаружил, что из 180Кб примерно 140Кб - это встроенные шрифты. Оказалось, что я встраиваю шрифт целиком, тогда как экономнее встраивать только подмножество глифов, которые используются в документе. Оказалось, что gofpdf, если работает не с UTF текстом, то не сокращает встраиваемый шрифт до набора глифов, которые есть в документа, а встраивает шрифт целиком. Я перешел на UTF текст и автоматически получил документ размером в 30Кб вместо 180Кб. Шестикратное уменьшение документа удешевляет их хранение.

Посмотреть глифы, встроенные шрифты в PDF можно утилитой FontForge. Позволяет как раз посмотреть глифы шрифта, подправить их при необходимости и т.д. Свободное ПО под лицензией GNU GPL.

Key-Value сторадж на базе PostgreSQL

Стоит понимать, что PostgreSQL никогда не станет более эффективным key-value хранилищем, чем специализированный продукт. Если у вас уже есть etcd или Valkey (форк Redis), то переиспользуйте его, но если вы думаете расширять ли стек и у вас уже есть реляционная СУБД, то предлагаю сегодня обсудить какие ограничения связаны с её использованием в этом контексте. Мы сегодня будем говорить о простейшем использовании PostgreSQL как хранилища значений key-value.

Если размер ваших данных целиком помещается, в shared_buffers (напомню, этот конфигурационный параметр задает размер кеша в оперативной памяти, в котором хранятся страницы памяти диска - нужен для снижения частоты обращение к жесткому диску, обычно равен 30-40% объема доступного RAM), то производительность будет умеренно высокой.

Для повышения производительности key-value на базе PostgreSQL стоит также учесть работу HOT (Heap Only Tuple) и помочь по возможности PostgreSQL. Что такое HOT? Это механизм оптимизации, снижающий разбухание индексов. B-Tree индекс - это сбалансированное дерево (каждый лист дерева на одинаковой глубине) и указывает на страницу памяти (обычно 8Кб) и тупл внутри этой страницы. Без работающего HOT когда мы делаем обновление записи, то на самом деле удаляется старая и создается новая запись и в индекс добавляется новая запись с тем же PK. Т.е. ситуация когда у нас в индексе есть две записи с первичным ключем - это нормальная ситуация. VACUUM потом проходится и удаляет старые данные из страниц памяти (Heap) и из индекса. Если новая запись может уместится на той же 8Кб странице памяти, то срабатывает HOT оптимизация: индекс останется неизменен, а старый тупл будет помечен как устаревший и у него будет ссылка (редирект) на новый тупл. Чтобы HOT использовался чаще данные должны быть компактными! Так новая запись будет чаще умещаться в той же странице памяти. Другой немаловажный параметр - это свободное место на странице памяти, которое управляется конфгурационным параметром fillfactor. fillfactor задает количество занимаемого места при вставках туплов.

Естественно, если возможно, стоит отключить WAL (Write-Ahead Loggin). Вы жертвуете надежностью и возможностью создавать реплики, но выигрываете в производительности. В среднем без WAL производительность выше в 3 раза.

Выводы надо делать каждому самостоятельно в своей конкретной ситуации и под свою нагрузку.