广告系统索引应用HugePage调研

本文探讨了广告系统中如何利用HugePage优化内存管理,以提高性能。介绍了启用和使用HugePage的方法,包括通过mmap接口和hugetlbfs文件系统。实验表明,HugePage在乱序访问时性能提升明显,但在实际应用中需考虑文件系统限制、内存浪费和管理复杂性等问题。
摘要由CSDN通过智能技术生成

一 背景

在广告系统中,在投广告的信息作为核心数据,具有改动频繁、实时性要求高的特点。为了设计并实现一个满足业务需求的广告系统,目前业界比较常见的解决方案是在广告检索集群每一台服务器的内存中存放索引数据,并通过mmap技术进行持久化(也可以直接使用tmpfs,不进行磁盘级别的持久化)。
众所周知,为了方便内存管理,提高内存使用效率,操作系统对内存进行了分段分页处理,其中分段管理的粒度较粗,分页管理的粒度较细。特别的,Linux默认的内存分页大小为4KB/page。内存具有对密集访问友好的特性,即连续访问内存性能上要优于跳跃访问。主要原因有两方面因素:
1、现代计算机配有高速cache,连续访问内存能更好的利用cache进行快速访问
2、虚拟内存->物理内存的映射表(页表)也具有缓存的特性,最近被访问的页表会存放在cahce的快表(TLB)中
当内存不连续访问时,会出现频繁的cache换页,影响性能。但是在内存索引的应用中,难免会遇到跳跃访问内存的场景,此时除了想办法“变跳跃为连续”以外,还有没有其他的思路能对性能进行优化?Linux中的hugepage为我们提供了另外一种思路。既然跳跃无法避免,我们可不可以减小跳跃带来的开销,也就是减小换页的概率?一个很直接的方式就是加大每个内存页的大小。hugepage就是这样一种内存管理策略。
使用大内存页有哪些好处:
1、减少页表(Page Table)大小。每一个Huge Page,对应的是连续的2MB物理内存(默认),这样12GB的物理内存只需要48KB的Page Table,与原来的24MB相比减少很多。
2、Huge Page内存只能锁定在物理内存中,不能被交换到交换区。这样避免了交换引起的性能影响。
3、由于页表数量的减少,使得CPU中的TLB(可理解为CPU对页表的CACHE)的命中率大大提高。
4、针对Huge Page的页表,在各进程之间可以共享,也降低了Page Table的大小。实际上这里可以反映出Linux在分页处理机制上的缺陷。而其他操作系统,比如AIX,对于共享内存段这样的内存,进程共享相同的页表,避免了Linux的这种问题。

二 HugePage的使用

2.1 启用hugepage

1、首先用

cat /proc/meminfo | grep Huge

命令来查看操作系统是否支持hugepage,若支持则返回如下

AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

其中HugePages_Total指系统中分配的hugepage的大内存页数,HugePages_Free指的是未被使用的大内存页数,HugePages Rsvd表示已经分配但是还未使用的页面数,Hugepagesize表示大内存页面大小,这里为2MB
2、修改/etc/sysctl.conf文件,增加如下行:

vm.nr_hugepages=1000

然后执行sysctl –p命令,使配置生效。
这里vm.nr_hugepages是大内存页数量。然后检查/proc/meminfo,如果HugePages_Total小于设置的数量,那么表明没有足够的连续物理内存用于这些大内存页,需要重启服务器。
重启后运行

cat /proc/meminfo | grep Huge

正常返回如下

AnonHugePages:         0 kB
HugePages_Total:    1000
HugePages_Free:     1000
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
2.2 使用hugepage

目前总结出的hugepage有两种使用方法。

2.2.1 利用mmap内核接口的MAP_HUGETLB参数

例程如下:

#include <sys/mman.h>
#include <stdio.h>
#include <memory.h>

int main(int argc, char *argv[]) {
   
  char *m;
  size_t s = (8UL * 1024 * 1024);
  m = mmap(NULL, s, PROT_READ | PROT_WRITE,
                    MAP_PRIVATE | MAP_ANONYMOUS | 0x40000 /*MAP_HUGETLB*/, -1, 0);
  if (m == MAP_FAILED) {
   
    perror("map mem");
    m = NULL;
    return 1;
  }
  memset(m, 0, s);
  printf("map_hugetlb ok, press ENTER to quit!\n");
  getchar();
  munmap(m, s);
  return 0;
}

在这种使用方法中,进程使用mmap打开了8MB大小的一块hugepage内存,并进行了清零。在程序暂定的时候使用

cat /proc/meminfo | grep Huge

可以看到

AnonHugePages:         0 kB
HugePages_Total:    1000
HugePages_Free:      996
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

可以看出,大内存页被占用8MB/2MB=4页,还剩余1000-4=996页。
十分需要注意的是,在这种使用方法中,mmap的0x40000(MAP_HUGETLB)参数必须同时配合MAP_PRIVATE和MAP_ANONYMOUS使用,缺一不可,否则mmap调用不会成功。因此,这种方法限制了hugepage只能有一个进程共访问&#

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值