[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 ]
完