Налаштування Nginx_сервер_імена_hash_max_size та сервер_імена_hash_bucket_size


22

Ми використовуємо Nginx як зворотний проксі для Apache в сервісі, який надає комусь свій власний веб-сайт. Під час створення облікового запису система створює новий файл nginx conf для домену з двома записами: один для порту 80, інший для 443. Ми помічаємо, що на кожні 30 доменів ми отримуємо помилку:

Restarting nginx: nginx: [emerg] could not build the server_names_hash, 
you should increase either server_names_hash_max_size: 256 
or server_names_hash_bucket_size: 64.

Маючи близько 200 доменів і зростаючи, нам довелося збільшити розмір сервера_назви_гаш_макс до 4112, і ми стурбовані тим, що це не буде добре масштабуватися. Я хочу зрозуміти, як працюють ці конфігурації та які оптимальні параметри були б для того, щоб ми могли перерости до тисяч доменів за допомогою цього методу.

Крім того, при цьому розмір хеша nginx починає займати кілька секунд, щоб перезавантажити, що спричиняє недоступність системи під час її перезавантаження.

Ось загальні налаштування (працює на сервері Ubuntu 10.10 nginx / 1.0.4):

user www-data;
worker_processes 4;
pid /var/run/nginx.pid;

events {
    worker_connections 4096;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 300;
    types_hash_max_size 2048;
    # server_tokens off;

    server_names_hash_bucket_size 64;
    # server_name_in_redirect off;
    # server_names_hash_max_size 2056;
    server_names_hash_max_size 4112;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_disable "msie6";

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;

ssl_session_cache shared:SSL:10m;
ssl_ciphers ALL:!kEDH:-ADH:+HIGH:+MEDIUM:-LOW:+SSLv2:-EXP;
}

(Нижче шифрів пара основних конфігурацій сайту та спіймання всіх):

include /etc/user-nginx-confs/*;

server {
listen 80;
server_name .domain.com;
location / {
proxy_pass http://127.0.0.1:8011;
proxy_set_header host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-SystemUse-Header 111;
}
}

server {
listen 443 ssl;
server_name .suredone.com;
ssl_certificate /etc/apache2/sddbx/sdssl/suredone_chained.crt;
ssl_certificate_key /etc/apache2/sddbx/sdssl/suredone.key;
location / {
proxy_pass http://127.0.0.1:44311;
proxy_set_header host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-SystemUse-Header 111;
}
}

server {
listen 80 default_server;
listen 443 default_server ssl;
server_name _;
ssl_certificate /ssl/site_chained.crt;
ssl_certificate_key /ssl/site.key;
return 444;
}

(І зразок файлу конфіденційності користувача)

server {
listen 80;
server_name username.domain.com;
location / {
proxy_pass http://127.0.0.1:8011;
proxy_set_header host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-SystemUse-Header 1111;
}
}

server {
listen 443 ssl;
server_name username.domain.com;
ssl_certificate /ssl/site_chained.crt;
ssl_certificate_key /ssl/site.key;
location / {
proxy_pass http://127.0.0.1:44311;
proxy_set_header host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-SystemUse-Header 1111;
}
}

Будь-яка допомога та напрямок дуже вдячні !!

Відповіді:


14

Список serverімен, які nginx обслуговує, зберігається у хеш-таблиці для швидкого пошуку . Зі збільшенням кількості записів вам доведеться збільшувати розмір хеш-таблиці та / або кількість відрізків хеш-таблиць.

Враховуючи характер вашої установки, я не можу придумати жодного способу, щоб ви легко зменшили кількість serverімен, які ви зберігаєте в таблиці. Я хоч би запропонував вам не "перезавантажувати" nginx, а просто просто перезавантажити його конфігурацію. Наприклад:

service nginx reload

Це чудово для останньої частини питання, дякую. Тож чи варто мене турбувати, що розмір сервера_назви_гаш_макс_розмір буде десь близько 20000, щоб дістатися до 10000 доменів?
jasonspalace

Це лише проблема при перезапуску nginx. Як я вже казав, reloadнатомість, коли це можливо, уникнути проблеми.
Майкл Хемптон

23

Лише деякі технічні деталі, які я викопав, утворюють вихідний код:

  • Загальною рекомендацією було б зберігати обидва значення як можна менше.
  • Якщо скарга nginx збільшується max_sizeспочатку, поки вона скаржиться. Якщо число перевищує велике число (наприклад, 32769), збільште bucket_sizeдо кратного значення за замовчуванням на вашій платформі до тих пір, поки воно скаржиться. Якщо він більше не скаржиться, зменшуйте max_sizeназад до тих пір, поки він не скаржиться. Тепер у вас є найкраща настройка для вашого набору імен серверів (кожен набір імен серверів може потребувати різної настройки).
  • Більший max_sizeозначає більше споживаної пам’яті (раз на одного працівника чи сервера, будь ласка, прокоментуйте, якщо знаєте).
  • Більший bucket_sizeозначає більше циклів процесора (для кожного пошуку доменних імен) і більше передач з основної пам'яті в кеш.
  • max_sizeне пов'язано безпосередньо з кількістю імен серверів, якщо кількість серверів подвоюється, можливо, вам доведеться збільшити в max_size10 разів або навіть більше, щоб уникнути зіткнень. Якщо ви не можете їх уникнути, вам доведеться збільшувати bucket_size.
  • bucket_size як вважається, збільшується до наступної потужності в два, з вихідного коду я вважаю, що цього має бути достатньо, щоб воно було кратним за замовчуванням, це повинно підтримувати передачі в кеш оптимальними.
  • Середнє доменне ім’я повинно вписуватися в 32 байти, навіть із накладними хеш-масивами. Якщо ви збільшите bucket_sizeдо 512 байтів, у ньому розміститься 16 доменних імен зі збіжним хеш-ключем. Це не те, що ви хочете, якщо зіткнення трапляється, воно шукає лінійно . Ви хочете мати якомога менше зіткнень.
  • Якщо у вас max_size менше 10000 і малих bucket_size, ви можете зіткнутися з тривалим часом завантаження, оскільки nginx намагатиметься знайти оптимальний розмір хешу в циклі.
  • Якщо у вас max_sizeбільше 10000, перед виконанням скарги буде виконано 1000 лише петель.

Це чудова інформація; спасибі за дослідження та рецензування.
живіт

@brablc Мені цікаво, як ти, наприклад, потрапив до 32769. Де можна побачити, який розмір поточної купи?
Уль Хостинг

Зайнята пам’ять буде max_size * bucket_size (але я не знаю, поділяється чи на одного працівника). У мене було 8000 імен серверів, і 32769 відчували себе занадто високими. Але якщо у вас багато пам’яті, можливо, ви захочете піднятися вище.
brablc

4

Збільште конфігурацію "server_names_hash_bucket_size" всередині вашого nginx.conf.

У мене було 64 і змінилося на 128.

Проблема вирішена.


2

@Michael Hampton абсолютно прав у своїй відповіді. Ця хеш-таблиця побудована та складена під час перезавантаження чи перезавантаження, а потім працює дуже швидко. Я думаю, що ця хеш-таблиця може вирости набагато більше, не погіршуючи продуктивність. Але я б запропонував використовувати розмір, потужність якого два, як 4096, через характер коду С.


Потужність двох з якою базою. Чи правильно вирощувати кратні за замовчуванням 512?
jasonspalace

Так, абсолютно.
Fleshgrinder

1

Я не на 100% впевнений у вашому випадку, але я отримував таке ж попередження, оскільки я двічі дзвонив proxy_set_header для X-Forwarded-Proto:

proxy_set_header X-Forwarded-Proto ...;

Це сталося тому, що я включав proxy_params, і він містить цей рядок серед інших:

proxy_set_header X-Forwarded-Proto $scheme;

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


1
реальні $$$ поради, дякую.
sjas

-2

Зміна

proxy_set_header X-Forwarded-For $remote_addr;

до

proxy_set_header X-Real-IP $remote_addr;

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.