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

 

posted on 2020-02-05 19:49  toong  阅读(2205)  评论(0编辑  收藏  举报