zumba/elasticsearch-index-rotate

安全旋转索引,对最终用户无停机时间。

1.2.2 2018-07-31 21:30 UTC

README

一个库,让您能够安全地旋转索引,而不会对最终用户造成停机。

Build Status

我为什么需要使用这个?

在许多情况下,Elasticsearch 被用作临时数据存储,用于快速搜索结构化或关系型数据。通常这是通过计划作业,从永久数据存储(如 MySQL 或 Postgres)读取数据并将其转换为 Elasticsearch 索引来实现的。

在许多情况下,重建索引需要一个干净的起点,以便整个索引被重建。如何在不中断最终用户对索引的搜索的情况下完成此操作?答案是旋转索引。

User search disrupted by rebuild

在这种情况下,当索引最初被移除时,用户的搜索会被完全中断,并且在索引重建期间,搜索只能部分可用。在索引重建期间,用户只能获得不完整的数据。

User search contiguous

在这种情况下,用户的搜索永远不会被中断,因为我们构建一个新的索引,在它构建/稳定后,我们通过客户端更改要搜索的索引。

安装

composer require zumba/elasticsearch-index-rotate

Elasticsearch Index Rotator 支持多个版本的 ElasticSearch 服务器,并使用 官方 elasticsearch 库来执行命令。确保在您的应用程序中包含此包,并指定与您的 Elasticsearch 服务器兼容的版本。有关版本信息,请参阅库文档。

用法

示例搜索

<?php

$client = new \Elasticsearch\Client();
$indexRotator = new \Zumba\ElasticsearchRotator\IndexRotator($client, 'pizza_shops');
$client->search([
	'index' => $indexRotator->getPrimaryIndex(), // Get the current primary!
	'type' => 'shop',
	'body' => [] //...
]);

示例构建

<?php

$client = new \Elasticsearch\Client();
$indexRotator = new \Zumba\ElasticsearchRotator\IndexRotator($client, 'pizza_shops');
// Build your index here
$newlyBuiltIndexName = 'my_new_built_index_name';
$indexRotator->copyPrimaryIndexToSecondary();
$indexRotator->setPrimaryIndex($newlyBuiltIndexName);
// optionally remove the old index right now
$indexRotator->deleteSecondaryIndices();

综合起来

<?php

use \Elasticsearch\Client;
use \Zumba\ElastsearchRotator\IndexRotator;

class MySearchIndex {

	const INDEX_PREFIX = 'pizza_shops';

	public function __constructor(\Elasticsearch\Client $client) {
		$this->client = $client;
	}

	public function search($params) {
		$indexRotator = new IndexRotator($this->client, static::INDEX_PREFIX);
		return $client->search([
			'index' => $indexRotator->getPrimaryIndex(), // Get the current primary!
			'type' => 'shop',
			'body' => $params
		]);
	}

	public function rebuildIndex() {
		$indexRotator = new IndexRotator($client, static::INDEX_PREFIX);
		$newlyBuiltIndexName = $this->buildIndex($client);
		$indexRotator->copyPrimaryIndexToSecondary();
		$indexRotator->setPrimaryIndex($newlyBuiltIndexName);
		// optionally remove the old index right now
		$indexRotator->deleteSecondaryIndices();
	}

	private function buildIndex(\Elasticsearch\Client $client) {
		$newIndex = static::INDEX_PREFIX . '_' . time();
		// get data and build index for `$newIndex`
		return $newIndex;
	}

}

使用策略

您现在可以自定义获取/设置主索引的策略。默认情况下,使用 ConfigurationStrategy,但我们还包含了一个 AliasStrategy。主要区别在于当调用 setPrimaryIndex 时,而不是在配置索引中创建条目,它在指定的索引上添加了一个别名(由 alias_name 选项指定),并删除了所有其他旧主索引的别名(由 index_pattern 指定)。

使用 AliasStrategy

<?php

$client = new \Elasticsearch\Client();
$indexRotator = new \Zumba\ElasticsearchRotator\IndexRotator($client, 'pizza_shops');
$aliasStrategy = $indexRotator->strategyFactory(IndexRotator::STRATEGY_ALIAS, [
	'alias_name' => 'pizza_shops',
	'index_pattern' => 'pizza_shops_*'
]);
// Build your index here
$newlyBuiltIndexName = 'pizza_shops_1234102874';
$indexRotator->copyPrimaryIndexToSecondary();
$indexRotator->setPrimaryIndex($newlyBuiltIndexName);

// Now that the alias is set, you can search on that alias instead of having to call `getPrimaryIndex`.
$client->search([
	'index' => 'pizza_shops',
	'type' => 'shop',
	'body' => [] //...
])

由于别名(《pizza_shops》)映射到主索引(《pizza_shops_1234102874》),您可以直接在客户端应用程序中使用别名,而无需在 IndexRotator 上调用 getPrimaryIndex()。但话虽如此,调用 getPrimaryIndex 不会返回别名,而是返回它所代表的确切索引。配置索引中的次要条目仍然被使用,并引用实际的索引名称,因为别名可以随时更新,并且不会有一个引用来删除旧的别名。