VMOD导向器-Varnish导向器模块

SYNOPSIS

import directors [as name] [from "path"]

New xround_robin=directors.round_robin()

    Void xround_robin.addBackend(后端)

    ····························································································后端

    后端xround_robin.ackend()

New xallback=Directors.Fallback(BOOL粘滞=0)

    Void xfall back.add_Backend(后端)

    之后端(Backend)

    Backend xallback.Backend()

New xRanomy=目录。随机()

    之后端(Backend,实数)

    ·········································后端

    Backend x随机.Backend()

New xhash=directors.hash()

    Void xhash.addBackend(Backend,实际权重=1.0)

    Void xhash.移除_后端(Backend)

    后端xhash.ackend(字符串)

New xshard=directors.shard()

    Void xShard.set_warmup(实际概率=0.0)

    Void xShard.set_rampup(持续时间=0)

    Void xShard.Associate(BLOB参数=0)

    Bool xShard.add_Backend(后端后端, [STRING ident] , [DURATION rampup] , [REAL weight] )

    Bool xShard.Remove_Backend( [BACKEND backend] , [STRING ident] )

    Bool xShard.Clear()

    Bool xShard.reconfigure(int plicas=67)

    Int xShard.key(字符串)

    Backend xShard.Backend( [ENUM by] , [INT key] , [BLOB key_blob] , [INT alt] , [REAL warmup] , [BOOL rampup] , [ENUM healthy] , [BLOB param] , [ENUM resolve] )

    VOID xShard.debug(Int)

New xshard_param=directors.shard_param()

    Void xshard_param.lear()

    Void xshard_param.set( [ENUM by] , [INT key] , [BLOB key_blob] , [INT alt] , [REAL warmup] , [BOOL rampup] , [ENUM healthy] )

    字符串xshard_param.get_by()

    Int xshard_param.get_key()

    Int xshard_param.get_alt()

    Real xshard_param.get_warmup()

    Bool xshard_param.get_rampup()

    字符串xshard_param.get_Healthy()

    BLOB xshard_param.use()

后端查找(字符串)

DESCRIPTION

vmod_directors 在Varnish中启用后端负载平衡。

该模块实现了负载平衡技术,也是如何扩展Varnish的负载平衡功能的一个示例。

要启用负载平衡,您必须导入此vmod(控制器)。

然后定义您的后端。一旦声明了后端,就可以将它们添加到控制器。这发生在执行的VCL代码中。如果您想要模仿Varnish 3.0之前的行为,只需在 vcl_init{} ,如下所示:

sub vcl_init {
    new vdir = directors.round_robin();
    vdir.add_backend(backend1);
    vdir.add_backend(backend2);
}

正如你所看到的,没有什么能阻止你操纵VCL其他地方的董事。因此,您可以使用VCL代码在调用某个URL时向指挥交换机添加更多后端。

请注意,控制器可以使用其他控制器作为后端。

New xround_robin=directors.round_robin()

创建循环调度控制器。

这位导演将以循环的方式挑选后端。

示例::

new vdir = directors.round_robin();

Void xround_robin.addBackend(后端)

向循环控制器添加一个后端。

示例::

vdir.add_backend(backend1);

····························································································后端

从循环调度控制器中删除后端。

示例::

vdir.remove_backend(backend1);

后端xround_robin.ackend()

从导演那里选择一个后端。

示例::

set req.backend_hint = vdir.backend();

New xallback=Directors.Fallback(BOOL粘滞=0)

创建一个备用导演。

备用控制器将依次尝试添加的每个后端,并返回第一个健康的后端。

如果 sticky 设置为 true ,控制器将继续使用健康的后端,即使有更高优先级的后端可用。一旦耗尽了整个后端列表,它将从头开始。

示例::

new vdir = directors.fallback();

Void xfall back.add_Backend(后端)

向导向器添加后端。

请注意,完成此操作的顺序对备用主管很重要。

示例::

vdir.add_backend(backend1);

之后端(Backend)

从控制器中删除后端。

示例::

vdir.remove_backend(backend1);

Backend xallback.Backend()

从导演那里选择一个后端。

示例::

set req.backend_hint = vdir.backend();

New xRanomy=目录。随机()

创建一个随机的后端控制器。

随机控制器使用加权随机概率分布在后端上分配负载。

使用varnishd中的“可测试”随机生成器,它允许运行确定性测试(请参见: d00004.vtc )。

示例::

new vdir = directors.random();

之后端(Backend,实数)

向具有给定权重的导演添加一个后端。

每个后端将收到发送到该控制器的流量的大约100%*(Weight/(sum(All_Added_Weight)。

示例::

# 2/3 to backend1, 1/3 to backend2.
vdir.add_backend(backend1, 10.0);
vdir.add_backend(backend2, 5.0);

·········································后端

从控制器中删除后端。

示例::

vdir.remove_backend(backend1);

Backend x随机.Backend()

从导演那里选择一个后端。

示例::

set req.backend_hint = vdir.backend();

New xhash=directors.hash()

创建散列后端控制器。

指挥交换机通过计算给定给的字符串的哈希/摘要来选择后端服务器 xhash.backend()

通常与一起使用 client.ip 或会话cookie以获得粘性会话。

示例::

new vdir = directors.hash();

Void xhash.addBackend(Backend,实际权重=1.0)

给导演增加一个有一定权重的后台。

权重的使用与随机导向器相同。除非有特殊需要,否则建议使用1.0,默认为1.0。

示例::

vdir.add_backend(normal_backend);
vdir.add_backend(larger_backend, 1.5);

Void xhash.移除_后端(Backend)

从控制器中删除后端。

示例::

Vdir.REMOVE_BACKEND(较大后端);

后端xhash.ackend(字符串)

从散列控制器中选择一个后端。

使用提供的字符串或字符串列表选择后端。

示例::

#根据客户端集合req.backend_hint=vdir.backend(req.http.cookie)中的cookie头部选择后台;

New xshard=directors.shard()

创建一个Shard控制器。

引言

分片控制器通过键选择后端,键可以直接提供,也可以从字符串派生。对于相同的key,分片控制器将始终返回相同的后端,除非后端配置或健康状态发生变化。相反,对于不同的密钥,碎片控制器可能会选择不同的后端。在默认配置中,未选择不健康的后端。

碎片控制器类似于散列控制器,但它的主要优势是,当后端配置或健康状态发生变化时,键与后端的关联尽可能保持稳定。

此外,Rampup和预热功能有助于进一步改善用户感知的响应时间。

切分

这一基本技术允许许多应用,如优化后端服务器缓存效率、Varnish集群或在不保持任何状态的情况下保持与服务器的会话,特别是不需要在Varnish服务器集群的节点之间同步状态:

  • 许多应用程序将缓存用于数据对象,因此,在应用程序服务器集群中,从同一服务器请求类似对象可能有助于优化此类缓存的效率。

    例如,按URL或某些 id URL组件已被证明显著提高了许多内容管理系统的效率。

  • 作为前一个例子的特例,在没有额外请求分配逻辑的Varnish服务器集群中,每个缓存将需要存储所有热对象,因此有效缓存大小大约是集群中任何服务器中最小的缓存大小。

    分片允许隔离集群中的对象,以便每个对象只缓存在其中一个服务器上(或者缓存在一个主服务器和一个备份服务器上,长时间缓存在主服务器上,而在其他服务器上缓存,等等)。实际上,这将导致缓存大小达到所有单个缓存总和的顺序,并有可能显著提高效率(根据服务器数量进行扩展)。

  • 另一个应用是实现后端请求的持久化,这样所有共享某个标准(如IP地址或会话ID)的请求都被转发到相同的后端服务器。

当与Varnish服务器集群一起使用时,如果配置相同,碎片控制器将在所有服务器上做出相同的决定。换句话说,无论哪个Varnish服务器处理请求,共享作为分片键的公共标准的请求都将平衡到相同的后端服务器(S)上。

缺点是:

  • 请求的分布取决于每个键的请求数和键值分布的一致性。简而言之,虽然这种技术可能会带来更好的整体效率,但对于特定情况,它也可能导致较差的负载平衡。

  • 当后端服务器变得不可用时,每种持久化技术都必须重新选择新的后端服务器,但一旦它恢复健康,这种技术也会切换回首选服务器,因此,当用于持久化时,它通常比有状态技术(将尽可能长时间地继续使用所选服务器(或由TTL指定))更不稳定。

方法

什么时候 xshard.reconfigure() 显式调用(或在任何包含重新配置的任务结束时隐式调用,如 xshard.add_backend() ),则从SHA256散列值的最后32位构建一致的散列循环数据结构 <ident> <n> (默认 ident 是后端名称)用于每个后端和流水号 n 从1到 replicas 参数为 xshard.reconfigure() 。散列为在一致的散列环上放置后端创建了看似随机的顺序。什么时候 xshard.add_backend() 是用一个 weight 论据, replicas 按该重量进行缩放,以按比例在环上添加更多该后端的副本。

什么时候 xshard.backend() 调用时,除非提供负载平衡密钥,否则将生成负载平衡密钥。查找循环中大于键的最小散列值(顺时针搜索并根据需要环绕)。此散列值的后端是给定键的首选后端。

如果请求健康的后端,只要找到的后端不健康或已经检查了所有后端,搜索就在环上以线性方式继续进行。对于不同的键,环上这些“替代后端”的顺序可能会有所不同。还可以显式选择备用后端。

有关一致散列,请参阅:

错误报告

失败的方法应该使用错误标签向VSL报告错误,因此在配置碎片控制器时,建议您检查::

varnishlog -I Error:^vmod_directors.shard

其他信息可能会以通知的形式提供,您可以使用

Varnishlog-我注意到:^vmod_directors.shard

Void xShard.set_warmup(实际概率=0.0)

设置默认预热概率。请参阅 warmup 的参数 xshard.backend() 。如果 probability 为0.0(默认),则禁用预热。

Void xShard.set_rampup(持续时间=0)

设置默认渐变持续时间。看见 rampup 的参数 xshard.backend() 。如果 duration 为0(默认),则禁用渐变。

Void xShard.Associate(BLOB参数=0)

关联默认设置 directors.shard_param() 对象或清除关联。

它的价值在于 param 参数必须是对 xshard_param.use() 方法。没有任何参数清除关联。

关联可以在每个后端请求中使用 param 的论点 xshard.backend()

Bool xShard.add_Backend(后端后端, [STRING ident] , [DURATION rampup] , [REAL weight] )

BOOL xshard.add_backend(
      BACKEND backend,
      [STRING ident],
      [DURATION rampup],
      [REAL weight]
)

添加一个后端 backend 向导演致敬。

ident :(可选)为此后端指定标识字符串,该字符串将由 xshard.reconfigure() 来构造一致的哈希环。标识字符串默认为后端名称。

ident 允许添加同一后端的多个实例。

rampup :可以选择为此后端指定特定的启动时间。否则,将使用每个控制器的斜坡时间(请参见 xshard.set_rampup() )。

weight: Optionally specify a weight to scale the xshard.reconfigure() replicas parameter. weight is limited to at least 1. Values above 10 probably do not make much sense. The effect of weight is also capped such that the total number of replicas does not exceed UINT32_MAX.

Bool xShard.Remove_Backend( [BACKEND backend] , [STRING ident] )

BOOL xshard.remove_backend(
      [BACKEND backend=0],
      [STRING ident=0]
)

将后端(S)从导演中移除。要么 backendident 必须指定。 ident 删除特定实例。如果 backend 是在没有给出 ident ,则此后端的所有实例都将被删除。

Bool xShard.Clear()

从控制器上删除所有后端。

Bool xShard.reconfigure(int plicas=67)

显式重新配置一致哈希环以反映后端更改以立即生效。

如果未显式调用此方法,则在当前任务结束时(之后)重新配置 vcl_init {} 或者当当前客户端或后端任务完成时)。

Int xShard.key(字符串)

方法来生成切片键以与 key 参数设置为 xshard.backend() 方法,方法是使用SHA256对给定的字符串进行哈希处理。

要使用其他散列生成分片密钥,请使用如下所示的定制vmod vmod blobdigestkey_blob 的论据 xshard.backend() 方法。

Backend xShard.Backend( [ENUM by] , [INT key] , [BLOB key_blob] , [INT alt] , [REAL warmup] , [BOOL rampup] , [ENUM healthy] , [BLOB param] , [ENUM resolve] )

BACKEND xshard.backend(
      [ENUM {HASH, URL, KEY, BLOB} by=HASH],
      [INT key],
      [BLOB key_blob],
      [INT alt=0],
      [REAL warmup=-1],
      [BOOL rampup=1],
      [ENUM {CHOSEN, IGNORE, ALL} healthy=CHOSEN],
      [BLOB param],
      [ENUM {NOW, LAZY} resolve]
)

在一致的哈希环上查找后端。

本文档使用特定分片键的后端顺序的概念。该顺序是确定的,但似乎是随机的,由一致的散列算法确定,并且根据后端的数量和副本的数量,对于不同的密钥可能会有所不同。特别是,这里提到的后端顺序是 _not_ 添加后端时给出的顺序。

  • by 如何确定分片键

    • HASH

      • 在后端上下文和 vcl_pipe {} :使用由设置的Varnish散列值 vcl_hash{}

      • 在非客户端上下文中调用时 vcl_pipe {} :哈希 req.url

    • URL :hash req.url/bereq.url

    • KEY :使用 key 论辩

    • BLOB :使用 key_blob 论辩

  • key 查找密钥为 by=KEY

    这个 xshard.key() 方法可以方便地从自定义字符串生成分片键。

  • key_blob 查找密钥为 by=BLOB

    目前,它以网络字节顺序(高字节顺序)使用给定BLOB的前4个字节,对于小于4个字节的BLOB,使用左填充的零。

  • alt 备用后端选择

    选择 alt -给定对象的第4个备用后端 key

    这对于由于后端错误而重试/重新启动特别有用:通过设置 alt=req.restartsalt=bereq.retries 使用Healthy=All时,将选择另一台服务器。

    加速和预热功能仅在以下情况下有效 alt==0

  • rampup 刚刚正常运行的服务器启动缓慢

    如果 alt==0 并且所选择的后端处于其斜坡周期,其概率与自备份变得健康到斜坡周期的时间成正比,返回下一个备选后端,除非这也处于其斜坡周期。

    默认的Rampup间隔可以使用 xshard.set_rampup() 方法,或专门针对每个后端使用 xshard.add_backend() 方法。

  • warmup 概率备选服务器选择

    可能的值:-1,0..1

    -1 :使用控制器定义中的预热概率

    仅用于 alt==0 :设置当首选后端健康时,转到下一个备用后端进行预热的请求比率(0.0:1.0)。如果任何首选后端或备用后端处于渐变状态,则处于非活动状态。

    warmup=0.5 是一种在正常操作条件下将每个密钥的负载分散到两个后端的便捷方法。

  • healthy

    • 选择:如果可能,返回一个健康的后台。

      alt==0 ,返回第一个健康的后端,否则不返回。

      alt > 0 ,忽略为备用后端选择跳过的后端的健康状态,然后返回下一个健康的后端。如果不存在,则返回被跳过的最后一个健康的后端或无。

    • 忽略:完全忽略后端健康状态

      只需返回第一个或 alt -TH备用后端,忽略健康状态, rampupwarmup

    • 全部:还可以检查运行状况以进行备用后端选择

      alt > 0 ,则返回 alt -所有健康后端的替代后端,找到最后一个健康后端或没有后端。

  • resolve

    默认值: LAZY 在……里面 vcl_init{}NOW 否则

    • NOW :查看后端并返回。

      不能用于 vcl_init{}

    • LAZY :返回该Director的一个实例,以供稍后的后端解析。

      LAZY 引用碎片控制器实例需要模式,例如作为其他控制器的后端(控制器分层)。

      在……里面 vcl_init{} 而在客户端, LAZY 模式不能与任何其他参数一起使用。

      在后端和在 vcl_pipe {} 、自变量或关联参数集的参数会影响后端请求的碎片控制器实例,而不管它在哪里被引用。

  • param

    使用或关联参数集。它的价值在于 param 参数必须是对 xshard_param.use() 方法。

    默认:由设置者 xshard.associate() 或取消设置。

    • resolve=NOW 参数的缺省值 directors.shard_param() 参数集

    • resolve=LAZY 关联 directors.shard_param() 为此后端请求设置的参数

      结合使用参数集的实施说明 resolve=LAZY

      • A param 参数保持关联,一旦控制器解析为实际的后端,对关联参数集的任何更改都会影响分片决策。

      • 如果还给出了其他参数实参,则它们具有首选项并被保留,即使 param 参数随后在相同的后端请求中更改。

      • 每次调用 xshard.backend() 覆盖之前的任何调用。

VOID xShard.debug(Int)

intentionally undocumented

New xshard_param=directors.shard_param()

创建碎片参数集。

参数集允许重复使用 xshard.backend() 跨多个碎片控制器实例的参数,并简化高级用例(例如,碎片控制器具有位于其他控制器下面的自定义参数)。

参数集有两个作用域:

  • 中定义的每VCL作用域 vcl_init{}

  • 每个后端请求范围

每个VCL作用域定义每个后端作用域的默认值。在后端上下文和中对参数集进行的任何更改 vcl_pipe {} 仅影响各自的后端请求。

参数集不能在客户端上下文中使用,除非 vcl_pipe {}

以下是一个典型的使用案例:一个参数集与多个控制器相关联。控制器选择发生在客户端,并在后端更改参数以在备用后端上实施重试:

sub vcl_init {
  new shard_param = directors.shard_param();

  new dir_A = directors.shard();
  dir_A.add_backend(...);
  dir_A.reconfigure();
  dir_A.associate(shard_param.use()); # <-- !

  new dir_B = directors.shard();
  dir_B.add_backend(...);
  dir_B.reconfigure();
  dir_B.associate(shard_param.use()); # <-- !
}

sub vcl_recv {
  if (...) {
    set req.backend_hint = dir_A.backend(resolve=LAZY);
  } else {
    set req.backend_hint = dir_B.backend(resolve=LAZY);
  }
}

sub vcl_backend_fetch {
  # changes dir_A and dir_B behaviour
  shard_param.set(alt=bereq.retries, by=URL);
}

Void xshard_param.lear()

将参数设置重置为默认值,如的文档所示 xshard.backend()

  • 在……里面 vcl_init{} 中,重置此VCL的参数集默认值

  • 后端环境和 vcl_pipe {} ,将此后端请求的参数集重置为VCL默认值

仅限于: vcl_pipebackendhousekeeping

Void xshard_param.set( [ENUM by] , [INT key] , [BLOB key_blob] , [INT alt] , [REAL warmup] , [BOOL rampup] , [ENUM healthy] )

VOID xshard_param.set(
      [ENUM {HASH, URL, KEY, BLOB} by],
      [INT key],
      [BLOB key_blob],
      [INT alt],
      [REAL warmup],
      [BOOL rampup],
      [ENUM {CHOSEN, IGNORE, ALL} healthy]
)

更改参数集的给定参数,如文档所示 xshard.backend()

  • 在……里面 vcl_init{} ,更改此VCL的参数集默认值

  • 在后端环境中和 vcl_pipe {} ,更改此后端请求的参数集,保留此VCL的未指定参数的默认设置。

仅限于: vcl_pipebackendhousekeeping

字符串xshard_param.get_by()

对象的字符串表示形式。 by 枚举参数,表示使用此参数对象的分片控制器将如何派生分片键。看见 xshard.backend()

Int xshard_param.get_key()

获取使用此参数对象的碎片控制器将使用的密钥。看见 xshard.backend()

Int xshard_param.get_alt()

vt.得到. alt 使用此参数对象的碎片控制器将使用的参数。看见 xshard.backend()

Real xshard_param.get_warmup()

vt.得到. warmup 使用此参数对象的碎片控制器将使用的参数。看见 xshard.backend()

Bool xshard_param.get_rampup()

vt.得到. rampup 使用此参数对象的碎片控制器将使用的参数。看见 xshard.backend()

字符串xshard_param.get_Healthy()

对象的字符串表示形式。 healthy 使用此参数对象的碎片控制器将使用的枚举参数。看见 xshard.backend()

BLOB xshard_param.use()

用于与 param 的论点 xshard.backend() 若要将此碎片参数集与碎片控制器相关联,请执行以下操作。

仅限于: vcl_pipebackendhousekeeping

后端查找(字符串)

按名称查找后端。

仅限于: housekeeping

ACKNOWLEDGEMENTS

之前版本的碎片控制器的开发部分是由德国电信股份公司-产品和创新公司赞助的。

之前版本的碎片导演的开发部分是由Bild GmbH&Co KG赞助的。