选择器

连接池维护连接链表,并决定连接节点何时从活跃状态转换为消亡状态(反之亦然)。可是,选择哪个连接是没有逻辑性的。这个工作属于选择器类。

选择器的任务是从提供的连接列表中返回单个连接。和连接池一样,这里有几个实现好的选择器可供选择。

RoundRobinSelector (默认)

这个选择器通过轮询调度的方式来返回链接。例如在第一次请求中选择节点 1,第二次请求中选择节点 2,等等。这确保集群中的节点平均负担流量。轮询调度是基于每一个请求来执行的(例如,一个 PHP 脚本的所有请求轮流发送到不同的节点中)。

RoundRobinSelector 是默认选择器, 如果你想明确地配置该选择器,可以这么做:

  1. $client = ClientBuilder::create()
  2. ->setSelector('\Elasticsearch\ConnectionPool\Selectors\RoundRobinSelector')
  3. ->build();

注意:要通过命名空间加类型的方式来指定选择器。

StickyRoundRobinSelector

这个选择器比较『任性』,它更喜欢重用同一个连接。例如,在第一个请求中选择节点 1,选择器会重用节点 1 来发送随后的请求,直到节点请求失败。在节点 1 请求失败后,选择器会轮询至下一个可用节点,然后一直重用这个节点。

对许多 PHP 脚本来说,这是一个理想的策略。由于 PHP 脚本是无共享架构且会快速退出,为每个请求创建新连接通常是一种次优策略且会引起大量的开销。相反,在脚本运行期间『钟情于』单个节点会更好。

这个选择器会默认会在初始化时把 hosts 随机打乱,但仍然保证集群中的节点平均负担流量。它动态地更改轮询方式,把轮询每个请求变成轮询每个脚本。

如果你使用 [未来模式] ,这种选择器的『任性』行为就不理想了,因为所有并行的请求会发送到集群中的同一个节点而非多个节点。当使用 Future 模式时,默认的 RoundRobinSelector 选择器会更好。

如果你要使用该选择器,你要这样做:

  1. $client = ClientBuilder::create()
  2. ->setSelector('\Elasticsearch\ConnectionPool\Selectors\StickyRoundRobinSelector')
  3. ->build();

注意:要通过命名空间加类名的方法来指定选择器。

随机选择器

无论什么状态下,该选择器只返回一个随机的节点。常被用于测试。

你可以这样来使用随机选择器:

  1. $client = ClientBuilder::create()
  2. ->setSelector('\Elasticsearch\ConnectionPool\Selectors\RandomSelector')
  3. ->build();

请注意,使用时需要指定类的完整命名空间。

自定义选择器

你可以自定义选择器。但是必须实现 SelectorInterface 类的方法

  1. namespace MyProject\Selectors;
  2. use Elasticsearch\Connections\ConnectionInterface;
  3. use Elasticsearch\ConnectionPool\Selectors\SelectorInterface
  4. class MyCustomSelector implements SelectorInterface
  5. {
  6. /**
  7. * 选择一个连接
  8. *
  9. * @param array $connections Array of Connection objects
  10. *
  11. * @return ConnectionInterface
  12. */
  13. public function select($connections)
  14. {
  15. // 详细代码
  16. }
  17. }

你可以通过对象注入或者实例化来使用自定义选择器:

  1. $mySelector = new MyCustomSelector();
  2. $client = ClientBuilder::create()
  3. ->setSelector($mySelector) // object injection
  4. ->setSelector('\MyProject\Selectors\FirstSelector') // or namespace
  5. ->build();