VSM:共享内存日志记录和统计

Varnish使用共享内存来导出参数、日志记录和统计数据,因为它比常规文件更快、更高效。

“Varnish共享内存”或VSM是维护共享内存文件集的整体机制,每个共享内存文件集由两部分的名称(类、标识)标识的内存块组成。

类指示块中存储的数据类型,例如,命令行参数的“arg”用于建立到varnishd的CLI连接,“Stat”用于统计计数器(VSC),“Log”用于日志记录(VSL)。

Ident名称部分主要与统计计数器一起使用,其中它们标识动态计数器,例如:

SMA.Transient.c_bytes

共享内存骗局

共享内存比常规文件更快,但与常规日志文件不同的是,它也略显棘手。

当你在“追加”模式下打开一个文件时,操作系统保证你写的任何东西都不会覆盖文件中的现有数据。这样做的巧妙结果是,写入同一文件的多个进程或线程甚至不需要知道彼此的情况,其工作方式与您预期的完全相同。

使用共享内存日志,我们不会从内核获得这样的帮助,写入者需要确保他们不会互相践踏,他们需要使读取者能够安全地访问数据。

解决这一问题的“CS101”方法是引入锁,并且花费大量时间来检查可用的多种锁的相对优点。

在varnishd(Worker)进程中,我们使用互斥锁来保证分配、日志条目和统计信息计数器的一致性。

我们不希望varnishncsa试图通过停滞的ssh连接来推送数据以阻止内容的交付,因此像这样的阅读器是纯只读的,它们不会影响varnishd进程,这意味着它们不会被锁定。

相反,我们使用了“稳定存储”的概念,以确保读者所看到的视图始终是一致的。

只要你只添加一些东西,那是微不足道的,但是移除一些东西,比如当后端被从配置中移除时,我们需要给读者一个机会来发现这一点,一个“冷却”时期。

瓦尼什的方式:

当varnishd启动时,它会打开锁定的共享内存文件,如果试图运行多个同名的varnishd实例,建议使用不同的-n参数。

每个子进程都使用自己的共享内存文件,因为工作进程重新启动无论如何都标志着操作的彻底中断。

在可能的范围内,通过将alloc_seq字段设置为零来将旧的共享内存文件标记为已放弃,VSM的所有读取器都应该监视该字段。

长期订阅VSM文件的进程应注意VSM文件是否变为“静默”状态,并检查该文件是否因子进程重新启动而被重命名。

共享内存文件中的块形成了一个链表,每当该列表改变时,aloc_seq字段就会改变。

VSM文件中的链表和其他元数据使用相对于VSM文件内存映射位置的起始地址的偏移量,因此不需要将其映射到任何特定地址。

当分配新的区块时,例如当添加新的后端时,无论它们位于VSM文件中的什么位置,它们都会被附加到列表中。

当一个块被释放时,它将从链接的分配列表中移除,其长度将被设置为零,并将更改alloc_seq以指示布局的更改。在接下来的60秒内,该块将不会被触摸或重复使用,从而让其他订户有机会发现取消分配的情况。

包含文件<vapi/vsm.h>提供了访问VSM文件所支持的API。