Nginx การตั้งค่า server_names_hash_max_size และ server_names_hash_bucket_size


22

เราใช้ Nginx เป็น reverse proxy ให้ 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 โดเมนและที่เพิ่มขึ้นเราจึงต้องเพิ่มขนาดเซิร์ฟเวอร์_names_hash_maxเป็น 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;
}

(ด้านล่าง ciphers คือการกำหนดค่าเว็บไซต์หลักคู่และจับทั้งหมด):

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;
}

(และไฟล์ conf ผู้ใช้ตัวอย่าง)

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

นั่นเป็นสิ่งที่ยอดเยี่ยมสำหรับส่วนท้ายของคำถามขอบคุณ ดังนั้นฉันจึงควรกังวลว่า server_names_hash_max_size จะอยู่ที่ประมาณ 20,000 ถึง 10,000 โดเมน?
jasonspalace

เป็นเพียงปัญหาเมื่อคุณรีสตาร์ท nginx อย่างที่ฉันพูดreloadแทนที่จะทำทุกอย่างเพื่อหลีกเลี่ยงปัญหา
Michael Hampton

23

รายละเอียดทางเทคนิคที่ฉันขุดในรูปแบบซอร์สโค้ด:

  • คำแนะนำทั่วไปจะทำให้ค่าทั้งสองมีขนาดเล็กที่สุดเท่าที่จะทำได้
  • หาก nginx บ่นเพิ่มขึ้นmax_sizeเป็นครั้งแรกตราบเท่าที่มันบ่น หากจำนวนเกินจำนวนมาก (ยกตัวอย่างเช่น 32769) ให้เพิ่มbucket_sizeค่าเริ่มต้นหลาย ๆ ค่าบนแพลตฟอร์มของคุณตราบใดที่มันยังบ่นอยู่ ถ้ามันไม่บ่นอีกต่อไปลดลงmax_sizeตราบใดที่มันไม่บ่น ตอนนี้คุณมีการตั้งค่าที่ดีที่สุดสำหรับชุดชื่อเซิร์ฟเวอร์ของคุณ (แต่ละชุด server_name อาจต้องตั้งค่าที่แตกต่างกัน)
  • ใหญ่ขึ้นmax_sizeหมายถึงการใช้หน่วยความจำมากขึ้น (หนึ่งครั้งต่อผู้ปฏิบัติงานหรือเซิร์ฟเวอร์โปรดแสดงความคิดเห็นหากคุณรู้)
  • ใหญ่ขึ้นbucket_sizeหมายถึงรอบการทำงานของ CPU ที่มากขึ้น (สำหรับการค้นหาชื่อโดเมนทุกครั้ง) และการถ่ายโอนเพิ่มเติมจากหน่วยความจำหลักไปยังแคช
  • max_sizeไม่เกี่ยวข้องกับจำนวนชื่อเซิร์ฟเวอร์โดยตรงหากจำนวนเซิร์ฟเวอร์เพิ่มขึ้นเป็นสองเท่าคุณอาจต้องเพิ่มmax_size10 ครั้งขึ้นไปเพื่อหลีกเลี่ยงการชน bucket_sizeถ้าคุณไม่สามารถหลีกเลี่ยงพวกเขาคุณจะต้องมีการเพิ่ม
  • bucket_size กล่าวกันว่าเพิ่มขึ้นเป็นพลังงานต่อไปของสองจากรหัสที่มาฉันจะตัดสินว่ามันควรจะเพียงพอที่จะทำให้มันหลายค่าเริ่มต้นนี้ควรให้การถ่ายโอนไปยังแคชที่ดีที่สุด
  • ชื่อโดเมนโดยเฉลี่ยควรมีขนาดพอดีกับ 32 ไบต์แม้จะมีค่าใช้จ่ายของอาร์เรย์แฮช หากคุณเพิ่มbucket_sizeเป็น 512 ไบต์จะรองรับชื่อโดเมนที่ 16 ด้วยรหัสแฮชคีย์ นี้ไม่ได้เป็นสิ่งที่คุณต้องการถ้าการปะทะกันเกิดขึ้นจะค้นหาเป็นเส้นตรง คุณต้องการให้มีการชนน้อยที่สุดเท่าที่จะทำได้
  • หากคุณมีmax_size น้อยกว่า 10,000และน้อยbucket_sizeคุณสามารถเจอเวลาโหลดนานเพราะ nginx จะพยายามหาขนาดแฮชที่ดีที่สุดในลูป
  • หากคุณมีmax_sizeมากกว่า 10,000 จะมีการดำเนินการ "เฉพาะ" 1,000 ลูปก่อนที่มันจะบ่น

นี่คือข้อมูลที่ดี; ขอบคุณสำหรับการวิจัยและการเขียน
womble

@brablc ฉันอยากรู้ว่าคุณไปถึง 32769 ได้อย่างไร จะเห็นขนาดฮีปปัจจุบันได้ที่ไหน?
Uhl Hosting

หน่วยความจำที่ถูกครอบครองจะเป็น max_size * bucket_size (แต่ฉันไม่รู้ว่ามันถูกแชร์หรือต่อคนงาน) ฉันมีชื่อเซิร์ฟเวอร์ 8000 ชื่อและ 32769 รู้สึกว่าสูงเกินไป แต่ถ้าคุณมีหน่วยความจำมากมายคุณอาจต้องการที่จะสูงขึ้น
brablc


2

@Michael Hampton ถูกต้องแน่นอนกับคำตอบของเขา ตารางแฮชนี้ถูกสร้างและรวบรวมในระหว่างการรีสตาร์ทหรือโหลดซ้ำและหลังจากนั้นมันก็ทำงานได้อย่างรวดเร็ว ฉันเดาว่าตารางแฮชนี้สามารถเติบโตได้มากขึ้นโดยไม่ทำให้ประสิทธิภาพการทำงานลดลง แต่ฉันขอแนะนำให้ใช้ขนาดที่มีกำลังสองเช่น 4096 เนื่องจากลักษณะของรหัส C


พลังของสองกับฐานใดถูกต้องหรือไม่ที่จะเติบโตเป็นทวีคูณของค่าเริ่มต้นที่ 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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.