0
点赞
收藏
分享

微信扫一扫

nginx【26】哈希表的max_size与bucket_size如何配置

暮晨夜雪 2022-02-22 阅读 133

Nginx容器是许多nginx高级功能的实现基础,即使我们不需要编辑第三方模块或者查看nginx的源代码;但我们需要变更我们的nginx配置文件,以达到最大化的性能;

我们也需要了解Nginx容器是怎么样使用的;下面我们来看下nginx最主要的内部容器;
在这里插入图片描述

  • (1):首先就是数组,也就是ngx_array_t;这里的数组和我们平常所理解的数组还是有所不同的;它是多块连续内存,其中每一块连续内存中可以存放很多元素;

  • (2):而链表就是ngx_list_t;

  • (3):对列是ngx_queue_t;

这些结构体它们所实现的功能是类似的;只不过它们的操作方法会有所不同;

而nginx中最重要的两个数据结构一个是哈希表,一个是红黑树;基数数是自平衡排序二叉树中的一种;只不过它的key只能是整型;像geo等模块在使用基数数;其它使用基数数的场景并不多;

  • (4):哈希表

我们先重点来看下哈希表使用的时候有哪些注意事项;

那么nginx的哈希表跟我们正常所见到的哈希表还是有所不同的;

我们只是从它的实现层面来看;和正常的哈希表是相似的;就是每一个元素会顺序的放到一块连续的内存当中;每一个元素它的key同样是通过哈希函数来映射的;

如下:
在这里插入图片描述
这是一段存放哈希表内容的连续内存;那么如下的一个结构体就是哈希表的描述;

在这里插入图片描述
 每一段大小的内容如下:
 在这里插入图片描述
它的name就是它的key;它的value是一个指针;指向我们实际的内容:
在这里插入图片描述
 一个key和另外一个key是连续放在一起的;这和大部分的哈希表是一样的;

完整图示如下:

在这里插入图片描述
哈希表与通常的哈希表有哪里不同尼?

它的应用场景不同,它仅仅应用于静态不变的内容,也就是说我们在运行过程中,这个哈希表通常是不会出现插入和删除的;

也就是说我们nginx刚启动的时候,就可以已经确定这个哈希表中一共有多少个元素,所以当使用哈希表的这些模块,通常会暴漏出来一个叫max_sizebucket size的参数 ,这两个参数给我们的时候,我们的max_size仅仅控制了最大的哈希表bucket的个数;而不是实际上bucket的个数;比如说我们的max size配置可能是100;但是实际上只有十个元素使用了哈希表;这个实际上它与实际的bucket size 是不符的;但max size这个意义在于我可以限制最大快的使用;因为这里消耗了我们的内存;

我们再来看一看所有使用哈希表的模块,有些什么样的特点?

比如说在httpstream的核心模块里,它们所有的变量使用了哈希表,因为变量在我们模块编译的时候就已经定义清楚了;

还有像map,还有像反向代理;因为反向代理中我们需要对很多header在配置文件中定义好header做哈希来提升它的访问性能;

refererssi也是同样的道理;因为哈希表在访问的时候它是一个O(1)的复杂度,速度非常的快;

而哈希表中我们会发现有一个叫bucket size;这个bucket size往往会有些默认值;这个默认值有时我们会发现nginx的配置文档中说是cpu_cache_line会对齐到这样一个值;这是什么意思尼?这实际上是影响了我们怎么样去配置bucket size;也就是说现在的主流的CPU,它实际上是有了L1,L2,L3缓存的;它在取我们内存上的数据时,并不是按照大家所想象的那样,按照所有的64位,或者32位这样去取,现在主流的CPU一次从内存上取数据的字节数就是cpu_cache_line,现在是64字节的;

而为什么哈希表要向64字节对齐尼?假设我们现在每一个哈希表的bucket是59字节,如果我们是紧密的排列在一起的;那么你取第一个哈希表元素;只需要访问一次,还多取了一个字节,但你取第二个元素的时候,你实际上需要访问组成两次;包括第一个64字节当中的最后一个字节,以及第二个单元里面的58个字节;所以为了避免这种取两次的问题,nginx在它的代码中自动的向上对齐了,所以我们在配置bucket size的时候,需要注意两个问题,如果我们配置的不是cpu_cache_line;而是70字节;它就会向上给我们分配每个元素是128字节;如果有可能的话,尽量不要超过64字节,以减少CPU来访问我们哈希表的次数;

总结:以上我们介绍了哈希表的使用,实际上还有更多的第三方模块都在使用哈希表,注意:哈希表只为静态的不变的内容服务,哈希表的bucket size需要考虑cpu_cache_line的对齐问题;

举报

相关推荐

0 条评论