选择器
连接池维护连接链表,并决定连接节点何时从活跃状态转换为消亡状态(反之亦然)。可是,选择哪个连接是没有逻辑性的。这个工作属于选择器类。
选择器的任务是从提供的连接列表中返回单个连接。和连接池一样,这里有几个实现好的选择器可供选择。
RoundRobinSelector (默认)
这个选择器通过轮询调度的方式来返回链接。例如在第一次请求中选择节点 1,第二次请求中选择节点 2,等等。这确保集群中的节点平均负担流量。轮询调度是基于每一个请求来执行的(例如,一个 PHP 脚本的所有请求轮流发送到不同的节点中)。
RoundRobinSelector
是默认选择器, 如果你想明确地配置该选择器,可以这么做:
$client = ClientBuilder::create()
->setSelector('\Elasticsearch\ConnectionPool\Selectors\RoundRobinSelector')
->build();
注意:要通过命名空间加类型的方式来指定选择器。
StickyRoundRobinSelector
这个选择器比较『任性』,它更喜欢重用同一个连接。例如,在第一个请求中选择节点 1,选择器会重用节点 1 来发送随后的请求,直到节点请求失败。在节点 1 请求失败后,选择器会轮询至下一个可用节点,然后一直重用这个节点。
对许多 PHP 脚本来说,这是一个理想的策略。由于 PHP 脚本是无共享架构且会快速退出,为每个请求创建新连接通常是一种次优策略且会引起大量的开销。相反,在脚本运行期间『钟情于』单个节点会更好。
这个选择器会默认会在初始化时把 hosts 随机打乱,但仍然保证集群中的节点平均负担流量。它动态地更改轮询方式,把轮询每个请求变成轮询每个脚本。
如果你使用 [未来模式] ,这种选择器的『任性』行为就不理想了,因为所有并行的请求会发送到集群中的同一个节点而非多个节点。当使用 Future 模式时,默认的 RoundRobinSelector
选择器会更好。
如果你要使用该选择器,你要这样做:
$client = ClientBuilder::create()
->setSelector('\Elasticsearch\ConnectionPool\Selectors\StickyRoundRobinSelector')
->build();
注意:要通过命名空间加类名的方法来指定选择器。
随机选择器
无论什么状态下,该选择器只返回一个随机的节点。常被用于测试。
你可以这样来使用随机选择器:
$client = ClientBuilder::create()
->setSelector('\Elasticsearch\ConnectionPool\Selectors\RandomSelector')
->build();
请注意,使用时需要指定类的完整命名空间。
自定义选择器
你可以自定义选择器。但是必须实现 SelectorInterface
类的方法
namespace MyProject\Selectors;
use Elasticsearch\Connections\ConnectionInterface;
use Elasticsearch\ConnectionPool\Selectors\SelectorInterface
class MyCustomSelector implements SelectorInterface
{
/**
* 选择一个连接
*
* @param array $connections Array of Connection objects
*
* @return ConnectionInterface
*/
public function select($connections)
{
// 详细代码
}
}
你可以通过对象注入或者实例化来使用自定义选择器:
$mySelector = new MyCustomSelector();
$client = ClientBuilder::create()
->setSelector($mySelector) // object injection
->setSelector('\MyProject\Selectors\FirstSelector') // or namespace
->build();