On iki kurulum

64 GB EPYC örneği için doğru ayarlanmış Postgres

E-8 üzerinde önemli olan her ayar, her sayının arkasındaki aritmetik, devasa sayfalar, bağlantı havuzlama ve herhangi birinin etkili olup olmadığını söyleyen bir pgbench çalıştırması.

Ne inşa edildiği

E-8 üzerinde, kendisine verilen donanımı kullanan tek bir Postgres örneği: sekiz özel Zen 4 çekirdeği, 64 GB kayıtlı ECC DDR5 ve güç kaybı korumalı Gen4 NVMe. Kutudan çıktığı gibi, Postgres 2009'dan kalma bir dizüstü bilgisayarda başlayacak şekilde yapılandırılmıştır. Bu şekilde bırakılırsa, bu makinedeki belleğin yaklaşık yüzde birini kullanacak ve neden yavaş olduğunu merak edecektir.

Aşağıdaki her sayı kopyalanmak yerine türetilmiştir. Örneğinizin farklı bir bellek miktarı varsa, aritmetik yeniden yapabilmeniz için gösterilmiştir. Bu, çoğunluğu işlemsel ve biraz raporlama içeren bir iş yükü için yazılmıştır; bu, ne söylerlerse söylesinler çoğu insanın gerçekte sahip olduğu şeydir.

Başlamadan önce

  • E-8 veya daha büyüğü. 64 GB'ın altında oranlar hâlâ geçerlidir ancak mutlak sayılar geçerli değildir ve büyük sayfalar zahmete değmez.
  • EPYC serisinde bulunan ve Ryzen serisinde bulunmayan ECC bellek. Paylaşılan arabelleklerdeki bir bellek hatası, uyarı vermeden diske geri yazılan bozuk bir sayfadır.
  • PostgreSQL 17'yi paketleyen Debian 13.

1. Kurulum ve başlatma

apt update && apt install -y postgresql postgresql-contrib numactl
systemctl stop postgresql
pg_dropcluster 17 main
pg_createcluster 17 main -- --data-checksums --encoding=UTF8 --locale=C.UTF-8

Veri sağlama toplamları başlatma sırasında seçilmelidir ve verimin yüzde birkaçına mal olur. Bozuk bir sayfanın raporlanması ile sunulması arasındaki farktır; bu yüzden o yüzde ikiyi kabul edin.

2. Bellek

Dört ayar, dört hesaplama:

  • shared_buffers RAM'in dörtte biri: 16GB. Daha büyük değerler eskiden önerilmezdi; modern çekirdeğe sahip özel bir makinede, dörtte biri iyi test edilmiş başlangıç noktasıdır ve çalışma kümeniz daha büyükse üçte biri savunulabilir.
  • effective_cache_size RAM'in dörtte üçü: 48GB. Bu hiçbir şey ayırmaz; çekirdeğin ne kadarını önbelleğe almış olabileceğini planlayıcıya söyler ve çok düşük ayarlamak, planlayıcının seçmesi gereken dizin taramalarını reddetmesine neden olur.
  • work_mem bağlantı başına değil, sıralama düğümü başına: 200 bağlantı ve belki her birinde iki sıralama ile, 64 GB'lık bir kutuda 32MB savunulabilir bir tavan değerdir. Raporlama sorguları için oturum başına yükseltin, genel olarak değil.
  • maintenance_work_mem vakum ve dizin oluşturma için: 2GB, autovacuum_work_mem onu devralacak şekilde bırakılır.
shared_buffers = 16GB
effective_cache_size = 48GB
work_mem = 32MB
maintenance_work_mem = 2GB
huge_pages = try

3. Büyük sayfalar

Dört kilobaytlık sayfalarla eşlenen on altı gigabayt paylaşılan arabellek, arka uç başına dört milyon sayfa tablosu girişi anlamına gelir. İki megabaytlık sayfalar bunu beş yüz kat azaltır ve kazanç, başlık rakamı olarak değil, eşzamanlılık altında daha düşük CPU olarak ortaya çıkar.

systemctl start postgresql
sudo -u postgres psql -c "SHOW shared_memory_size_in_huge_pages;"

Yazdırılan sayıyı alın, pay için yüzde on ekleyin ve not edin:

echo "vm.nr_hugepages = 8600" > /etc/sysctl.d/60-postgres.conf
echo "vm.overcommit_memory = 2" >> /etc/sysctl.d/60-postgres.conf
echo "vm.overcommit_ratio = 90" >> /etc/sysctl.d/60-postgres.conf
echo "vm.swappiness = 1" >> /etc/sysctl.d/60-postgres.conf
sysctl --system
echo never > /sys/kernel/mm/transparent_hugepage/enabled

Açık büyük sayfalar evet, şeffaf büyük sayfalar hayır. İkincisi, öngörülemeyen anlarda belleği birleştirir ve insanların haftalarca depolamalarına yorduğu gecikme artışları üretir.

4. Yazma öncesi günlüğü ve denetim noktaları

Varsayılan denetim noktası ayarları, yük altında her birkaç saniyede bir veri boşaltmaya zorlar ve NVMe'nizi küçük eşzamanlı yazma kuyruğuna dönüştürür.

wal_level = replica
max_wal_size = 16GB
min_wal_size = 2GB
checkpoint_timeout = 15min
checkpoint_completion_target = 0.9
wal_compression = zstd
wal_buffers = 64MB
synchronous_commit = on
full_page_writes = on

synchronous_commit açık bırakın. Kapatmak, mevcut en büyük verim kazancıdır ve güç kaybının yiyebileceği işlemleri onaylamak anlamına gelir. Sürücülerimiz kapasitör destekli yazma önbelleklerine sahiptir, bu nedenle fsync burada gerçekten ucuzdur; verimi dürüst bir yerden satın alın.

5. Depolama ve planlayıcı

random_page_cost = 1.1
seq_page_cost = 1.0
effective_io_concurrency = 200
maintenance_io_concurrency = 200
default_statistics_target = 200
jit = off

random_page_cost değeri dört, bir sabit disk sayısıdır ve doğadaki en yaygın tek yanlış yapılandırmadır. NVMe'de rastgele okuma, sıralı okumayla hemen hemen aynı maliyete sahiptir ve planlayıcıya aksini söylemek, büyük tablolarda dizinlerden kaçınmasına neden olur. JIT derlemesi kapalıdır çünkü kısa işlemsel sorgular için derlemeye yürütmeden daha fazla zaman harcar; analitik sorgular için oturum başına açın.

6. Paralellik, otovakum ve bağlantılar

max_connections = 200
max_worker_processes = 8
max_parallel_workers = 8
max_parallel_workers_per_gather = 4
max_parallel_maintenance_workers = 4

autovacuum_max_workers = 4
autovacuum_naptime = 15s
autovacuum_vacuum_scale_factor = 0.02
autovacuum_analyze_scale_factor = 0.01
autovacuum_vacuum_cost_limit = 3000

shared_preload_libraries = 'pg_stat_statements'
track_io_timing = on
log_min_duration_statement = 500ms
log_checkpoints = on
log_autovacuum_min_duration = 0

İşçi sayıları sekiz özel çekirdekle eşleşir, çünkü onlar özeldir. Aşırı satılmış bir ana bilgisayarda bu sayılar yalan olur ve size gerçekte satılan çekirdek fraksiyonuna göre bunları düşürürdünüz; burada böyle bir sorununuz yok.

Varsayılan otovakum ölçek faktörü 0,2, yüz milyon satırlık bir tablonun herhangi bir şey olmadan önce yirmi milyon ölü demet beklemesi anlamına gelir. Yüzde yirmi yerine yüzde iki, vakumun nadiren ve feci şekilde değil, sık sık ve kısa süre çalışmasını sağlar.

7. Havuzlama

Sekiz çekirdekte iki yüz arka uç paralellik değildir; ekstra bellek yükü olan bir kuyruktur. Önüne bir havuzlayıcı koyun:

apt install -y pgbouncer
[databases]
app = host=/var/run/postgresql dbname=app

[pgbouncer]
listen_addr = 10.9.0.1
listen_port = 6432
auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
default_pool_size = 32
max_client_conn = 2000
server_idle_timeout = 60

Otuz iki sunucu bağlantısıyla işlem havuzlaması, çekirdek başına dört verir; bu, bu silikonda verimin iyileşmeyi bıraktığı yerdir. Danışma kilitleri veya hazırlanmış ifadeler gibi oturum düzeyi özellikleri kullanan uygulamalar, oturum havuzlamasına ihtiyaç duyar ve daha küçük bir sayı alır.

systemctl restart postgresql pgbouncer

Doğrulayın

Önce ayarlar. Etkili olmayan herhangi bir şey, üç hafta sonra değil, burada açıkça görülecektir:

sudo -u postgres psql -c "SELECT name, setting, unit FROM pg_settings WHERE name IN ('shared_buffers','effective_cache_size','work_mem','huge_pages','random_page_cost','max_wal_size');"
grep -E "HugePages_(Total|Free)" /proc/meminfo

HugePages_Free, HugePages_Total değerinin birkaç bin sayfa altında olmalıdır; bu, Postgres'in bunları gerçekten eşlediği anlamına gelir. Eşit değerler, küçük sayfalara geri döndüğü ve huge_pages = try hatayı sessizce yuttuğu anlamına gelir.

Sonra ölçün. İlginç olacak kadar büyük, ancak paylaşılan arabelleklerde duracak kadar küçük bir veri kümesi oluşturun:

sudo -u postgres createdb bench
sudo -u postgres pgbench -i -s 800 bench
sudo -u postgres pgbench -c 32 -j 8 -T 60 -S bench
sudo -u postgres pgbench -c 32 -j 8 -T 60 bench

Bir E-8'de salt okunur çalışma saniyede yüz binlerce işlem, okuma-yazma çalışması ise birkaç bin aralığında kalır. Kesin rakamlar siteye ve veri kümesine bağlıdır; bu nedenle yararlı sinyal büyüklük sırasıdır: yalnızca seçme testi yüz binlerce yerine on binlerce döndürürse, shared_buffers etkili olmamıştır veya hâlâ ilk çalıştırmada soğuk önbellekle kıyaslama yapıyorsunuzdur.

Son olarak, istatistik uzantısının yüklendiğini doğrulayın, çünkü sonrasında her hafta gerçekten kullanacağınız şey budur:

sudo -u postgres psql bench -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;"
sudo -u postgres psql bench -c "SELECT calls, round(mean_exec_time::numeric,2) AS ms, query FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5;"

Sonrasında

Bu veritabanında özleyeceğiniz bir şey olmadan önce başka bir şehirdeki ikinci bir örneğe WAL arşivlemeyi açın. Hiç test etmediğiniz bir temel yedeği geri yüklemek bir yedek değil, bir umuttur ve konumlar sayfası kısmen yedek sunucunuzun birincil sunucunuzla aynı binada olmaması için vardır.

Hazır olduğunda

Bir şehir seç. Bir boyut seç. Kripto ile öde.

Kim olduğunuzla ilgili formlar yok, onay için insan bekleme yok, doğrulama için telefon görüşmesi yok. Ödeme onaylanır ve kimlik bilgileri gelen kutunuza düşer.