Elasticsearch 作为搜索和分析数据的首选分布式引擎在技术领域脱颖而出,尤其是在处理日志、事件和综合文本搜索时。 它的与众不同之处在于它如何让你使用各种块选项调整对其索引的访问。 这对于那些负责技术项目的人(比如管理员和编码员)来说非常方便,他们需要保持数据可靠、管理资源或遵守严格的安全规则。
通常,我们必须停止对索引设置的任何调整。 诀窍是依靠 Elasticsearch 的块设置,更准确地说,依靠 blocks.metadata 设置。 将此设置翻转为 true 意味着没有人可以弄乱索引的元数据,无论是读取还是写入。
假设你正在处理一个多租户 SaaS 应用程序,每个租户都有自己的索引。 你已经整理了所有这些索引及其独特的设置和映射。 现在,你希望确保所有内容都按照 你在每个租户中设置的方式保持不变。 这就是 blocks.metadata 设置发挥作用的地方。 使用方法如下:
PUT my_data/_settings
{
"blocks.metadata": true
}
一旦设定这个,比如我再也无法改变它的元数据。我们可以进行如下的尝试:
PUT twitter/_doc/1
{
"content": "This is Xiaoguo from Elastic"
}
在上面,我们创建了一个叫做 twitter 的索引。我们可以看到它的设置:
GET twitter/_settings
{
"twitter": {
"settings": {
"index": {
"routing": {
"allocation": {
"include": {
"_tier_preference": "data_content"
}
}
},
"number_of_shards": "1",
"provided_name": "twitter",
"creation_date": "1714352386891",
"number_of_replicas": "1",
"uuid": "azY4f_smTymShGLc8R6m1g",
"version": {
"created": "8503000"
}
}
}
}
}
如上所示,我们可以看到 number_of_replicas 的值为 1。我们可以通过如下的方法来进行修改它的值为 0:
PUT twitter/_settings
{
"number_of_replicas": 0
}
我们再次进行查看它的设置:
GET twitter/_settings
{
"twitter": {
"settings": {
"index": {
"routing": {
"allocation": {
"include": {
"_tier_preference": "data_content"
}
}
},
"number_of_shards": "1",
"provided_name": "twitter",
"creation_date": "1714352386891",
"number_of_replicas": "0",
"uuid": "azY4f_smTymShGLc8R6m1g",
"version": {
"created": "8503000"
}
}
}
}
}
很显然,number_of_replicas 的值现在变为 0。假如我们不想任何人对这个值进行改变,那么我们可以通过如下的命令来进行设置:
PUT twitter/_settings
{
"blocks.metadata": true
}
那么它现在的设置为:
GET twitter/_settings
{
"error": {
"root_cause": [
{
"type": "cluster_block_exception",
"reason": "index [twitter] blocked by: [FORBIDDEN/9/index metadata (api)];"
}
],
"type": "cluster_block_exception",
"reason": "index [twitter] blocked by: [FORBIDDEN/9/index metadata (api)];"
},
"status": 403
}
显然,我们现在读取不了它的任何的设置,并且我们来尝试对它进行修改:
PUT twitter/_settings
{
"number_of_replicas": 1
}
{
"error": {
"root_cause": [
{
"type": "cluster_block_exception",
"reason": "index [twitter] blocked by: [FORBIDDEN/9/index metadata (api)];"
}
],
"type": "cluster_block_exception",
"reason": "index [twitter] blocked by: [FORBIDDEN/9/index metadata (api)];"
},
"status": 403
}
我们也不能对它做任何的修改。除非我们再次把上面的 blocks.metadata 设置为 false:
PUT twitter/_settings
{
"index.blocks.metadata": false
}
然后,我们再次修改 number_of_replicas 的值为 1:
PUT twitter/_settings
{
"number_of_replicas": 1
}
我们再次通过如下的命令来进行确认:
GET twitter/_settings
{
"twitter": {
"settings": {
"index": {
"routing": {
"allocation": {
"include": {
"_tier_preference": "data_content"
}
}
},
"number_of_shards": "1",
"blocks": {
"metadata": "false"
},
"provided_name": "twitter",
"creation_date": "1714352386891",
"number_of_replicas": "1",
"uuid": "azY4f_smTymShGLc8R6m1g",
"version": {
"created": "8503000"
}
}
}
}
}
为什么使用索引 blocks?
你可能想知道为什么有人会选择使用索引块。 以下是一些常见原因:
- 维护和升级:当系统维护或升级时,管理员必须锁定数据以保持一切一致。
- 数据完整性:在数据必须保持不变的情况下(例如存档日志或历史记录),write blocks 会派上用场。
- 资源管理:有时,索引可能会占用太多资源。 在这种情况下,管理员可能会暂时停止读取或写入。
- 安全性:对于特别敏感的数据,read blocks 是一个很好的工具,可以防止不应该访问的人进入。
现在,你可能会想,“使用 RBAC(基于角色的访问控制)怎么样?” 这是一个有效的观点。 确实,为什么不呢? 你可以在这里更深入地了解这一点:
User authorization | Elasticsearch Guide [8.13] | Elastic。你也可以深入阅读文章 “Elasticsearch:用户安全设置” 及 “Elasticsearch:将文档级安全性 (DLS) 添加到你的内部知识搜索”。
让我们分解不同类型的块
Elasticsearch 附带了一系列块设置,每个块设置都有特定的用途:
- block.read_only:这就像主开关。 它停止对索引数据及其元数据的任何读取。 当您需要确保索引中的任何内容(无论是数据还是元数据)都不会被读取时,这是首选选项。
- block.read:名副其实; 此设置停止所有读取操作。
- blocks.write:这个是关于停止写操作的。 如果索引中的数据应保持原样,那么此设置是您的朋友。
- blocks.metadata:这会阻止索引元数据的读取和写入。 元数据包括设置、映射和其他配置。 通过阻止元数据操作,可以确保索引配置保持不变。
设置和拆除 blocks
将块放置到位非常简单 - 使用 PUT 请求,如我们在前面的示例中看到的那样。 当提升该块时,你只需调整索引设置,将块值切换为 false。 例如,如果您想摆脱 write block:
PUT sample-01/_settings
{
"index.blocks.write": false
}
以上面的例子为例,我们首先运行如下的命令:
PUT twitter/_settings
{
"index.blocks.write": true
}
我们尝试写如下一个数据:
PUT twitter/_doc/2
{
"content": "This is a test"
}
{
"error": {
"root_cause": [
{
"type": "cluster_block_exception",
"reason": "index [twitter] blocked by: [FORBIDDEN/8/index write (api)];"
}
],
"type": "cluster_block_exception",
"reason": "index [twitter] blocked by: [FORBIDDEN/8/index write (api)];"
},
"status": 403
}
很显然,我们这次不能写入数据了。这个是因为 twitter 索引的设置 "index.blocks.write": true。我们可以通过如下的命令来对它进行解锁:
PUT twitter/_settings
{
"index.blocks.write": false
}
我们再次对她进行写入:
PUT twitter/_doc/2
{
"content": "This is a test"
}
{
"_index": "twitter",
"_id": "2",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
很显然,这次的操作是成功的。
根据 Elastic 官方文档,我们也可以通过如下格式的命令来对它进行操作:
PUT /my-index-000001/_block/write
比如:
PUT /twitter/_block/write
运行完上面的命令后,它讲阻止我们向 twitter 写入:
PUT twitter/_doc/3
{
"content": "This is a another test"
}
上述命令将会失败。
结论
Elasticsearch 提供了一组可靠的关键索引块设置来管理对索引的访问。 接触这些设置至关重要,尤其是当您的目标包括保持数据完整性、有效处理资源或提高安全性时。 与任何强大的工具一样,明智地使用这些设置并清楚地了解它们的含义至关重要。