[nginx] nginx的hash與bucket size分析


問題描述

我們已知有一個map命令,可以用在http block和stream block中。

用於定義個新的變量,變量的取值由map里邊的key和value定義。

如我在前文有個SNI的使用中,便用到了這個方式。[nginx][tls] nginx配置https與ssl/tls的sni的方法

       map $ssl_server_name $sni_string {
               test1.www.local test1;
               test2.www.local test2;
               test3.www.local test3;
       }

當key的字符串(test1.www.local)長度特別長的時候,nginx讀取配置會失敗,並打印如下的錯誤信息:

could not build map_hash, you should increase map_hash_bucket_size: 64

[classic_tong@ https://www.cnblogs.com/hugetong/p/12266235.html ]

 

問題分析

map命令由 ngx_http_map_module 提供。之后調用 nginx_hash,並在函數 ngx_hash_init()函數中由於構建hash表失敗返回以上錯誤信息。

通過閱讀代碼,我們知道。ngx_hash主要是為了在鏈接處理過程中加速訪問,在配置文件的初始化階段便構建完成。

使用開放定址法實現,hash的key放置在bucket中,bucket根據key的長度變長。並放置在連續的數組中。

故上文報錯中的bucket size實際指的是這個用來裝key的bucket的最大長度。

同時,另外一個參數,map_hash_max_size也與該數組密切相關。

 

此外,bucket size需要cache line對齊,並與性能相關。(沒有細致的閱讀該部分代碼,有關性能的內容,並不能給出一個准確的結論。)

但是在SNI場景里,由於SNI的每鏈接會產生IO操作,所以該部分的性能損失,似乎可以忽略?

(SNI的IO問題見:[nginx] nginx源碼分析--SNI性能分析

 

參考

1,參考nginx的配置手冊:

https://nginx.org/en/docs/http/ngx_http_map_module.html#map_hash_bucket_size

https://nginx.org/en/docs/hash.html

2,一篇隨手google的文字。(其中提到的“開放鏈表法”為筆誤,應更正為“開放定址法”。)

https://www.cnblogs.com/chengxuyuancc/p/3782808.html

 

----

[classic_tong@ https://www.cnblogs.com/hugetong/p/12266235.html ]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM