MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

ElasticSearch数据探索的前期准备

2024-02-294.7k 阅读

理解 ElasticSearch 核心概念

索引(Index)

在 ElasticSearch 中,索引是一个非常关键的概念。它类似于关系型数据库中的数据库,是存储和组织数据的逻辑容器。但与传统数据库不同,ElasticSearch 的索引在设计上更侧重于分布式存储和检索。

从结构上讲,索引由多个分片(Shard)组成。每个分片都是一个独立的 Lucene 索引,这使得 ElasticSearch 能够在多台服务器上分布式存储数据,从而实现高可用性和可扩展性。例如,当你创建一个名为 “products” 的索引时,ElasticSearch 会根据配置将这个索引的数据分布到多个分片上,这些分片可以位于不同的节点(Node)上。

在创建索引时,可以指定一些设置,如分片数量和副本数量。以下是使用 ElasticSearch 的 Python 客户端 Elasticsearch-py 创建索引的示例代码:

from elasticsearch import Elasticsearch

# 连接到 ElasticSearch 集群
es = Elasticsearch(['localhost:9200'])

# 创建索引
index_name = 'products'
index_settings = {
    "settings": {
        "number_of_shards": 3,
        "number_of_replicas": 1
    }
}

es.indices.create(index=index_name, body=index_settings)

在上述代码中,我们创建了一个名为 “products” 的索引,设置了 3 个分片和 1 个副本。副本的作用是提供数据冗余和高可用性,当某个分片所在的节点出现故障时,副本分片可以继续提供服务。

文档(Document)

文档是 ElasticSearch 中最小的数据单元,类似于关系型数据库中的行。每个文档都有一个唯一的标识符(ID),可以通过这个 ID 对文档进行检索、更新或删除操作。

文档以 JSON 格式存储,这使得它非常灵活,能够适应各种不同的数据结构。例如,一个表示产品的文档可能如下所示:

{
    "product_id": "P001",
    "product_name": "Widget",
    "description": "A useful widget for all your needs",
    "price": 19.99,
    "category": "Tools"
}

使用 Elasticsearch-py 将上述文档索引到 “products” 索引中:

document = {
    "product_id": "P001",
    "product_name": "Widget",
    "description": "A useful widget for all your needs",
    "price": 19.99,
    "category": "Tools"
}

es.index(index=index_name, id="1", body=document)

在这段代码中,我们将一个产品文档索引到了 “products” 索引中,并指定了文档的 ID 为 “1”。如果不指定 ID,ElasticSearch 会自动生成一个唯一的 ID。

类型(Type)

在 ElasticSearch 7.0 之前,类型用于在一个索引中对文档进行逻辑分组,类似于关系型数据库中的表。例如,在一个 “company” 索引中,可以有 “employees” 类型和 “departments” 类型。

然而,从 ElasticSearch 7.0 开始,类型的概念被逐渐弃用,因为它在实际使用中会带来一些复杂性,尤其是在处理不同类型文档具有相同字段名但不同数据类型的情况。现在,建议在一个索引中存储同构的数据,即具有相似结构的文档。

ElasticSearch 集群搭建与环境配置

安装 ElasticSearch

  1. 下载安装包:首先,你需要从 ElasticSearch 官方网站(https://www.elastic.co/downloads/elasticsearch)下载适合你操作系统的安装包。ElasticSearch 支持多种操作系统,包括 Linux、Windows 和 macOS。
  2. 解压安装包:在 Linux 或 macOS 上,下载的通常是一个压缩文件,解压该文件到你希望安装 ElasticSearch 的目录。例如,在 Linux 上:
tar -xvf elasticsearch-7.17.0-linux-x86_64.tar.gz
cd elasticsearch-7.17.0

在 Windows 上,下载的是一个 ZIP 文件,解压后即可得到 ElasticSearch 的安装目录。

  1. 配置 ElasticSearch:进入安装目录下的 config 文件夹,编辑 elasticsearch.yml 文件。这是 ElasticSearch 的主要配置文件,你可以在这里设置集群名称、节点名称、网络绑定地址等重要参数。

以下是一个简单的配置示例:

cluster.name: my-elasticsearch-cluster
node.name: node-1
network.host: 0.0.0.0
http.port: 9200

在上述配置中,我们设置了集群名称为 “my - elasticsearch - cluster”,节点名称为 “node - 1”,绑定所有网络接口(0.0.0.0),并使用默认的 HTTP 端口 9200。

  1. 启动 ElasticSearch:在安装目录的 bin 文件夹下,执行启动脚本。在 Linux 或 macOS 上:
./elasticsearch

在 Windows 上,运行 elasticsearch.bat 文件。启动成功后,你可以通过浏览器访问 http://localhost:9200,如果看到 ElasticSearch 的欢迎信息,说明安装和启动成功。

安装 Kibana

Kibana 是 ElasticSearch 的官方可视化工具,它为 ElasticSearch 提供了一个直观的用户界面,方便进行数据探索、可视化和管理。

  1. 下载 Kibana:从 Elastic 官方网站(https://www.elastic.co/downloads/kibana)下载与你安装的 ElasticSearch 版本匹配的 Kibana 安装包。版本兼容性非常重要,不匹配的版本可能会导致功能异常。
  2. 解压并配置 Kibana:解压下载的 Kibana 安装包,进入 config 文件夹,编辑 kibana.yml 文件。主要配置项包括 ElasticSearch 的连接地址:
server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://localhost:9200"]

在上述配置中,我们设置 Kibana 监听端口为 5601,绑定所有网络接口,并指定 ElasticSearch 的连接地址为 http://localhost:9200

  1. 启动 Kibana:在安装目录的 bin 文件夹下,执行启动脚本。在 Linux 或 macOS 上:
./kibana

在 Windows 上,运行 kibana.bat 文件。启动成功后,通过浏览器访问 http://localhost:5601,你将看到 Kibana 的登录界面。默认情况下,Kibana 不需要用户名和密码即可访问。

安装 Elasticsearch-py(Python 客户端)

如果你计划使用 Python 与 ElasticSearch 进行交互,安装 Elasticsearch-py 是必不可少的。

  1. 使用 pip 安装:确保你已经安装了 Python 和 pip(Python 的包管理工具)。在命令行中执行以下命令安装 Elasticsearch-py:
pip install elasticsearch
  1. 验证安装:打开 Python 交互式环境,尝试导入 Elasticsearch 模块:
from elasticsearch import Elasticsearch
try:
    es = Elasticsearch(['localhost:9200'])
    print(es.ping())
except Exception as e:
    print(f"Error: {e}")

如果 es.ping() 返回 True,说明 Elasticsearch-py 安装成功并且能够连接到 ElasticSearch 集群。

数据建模与映射

理解数据建模在 ElasticSearch 中的重要性

在 ElasticSearch 中,合理的数据建模是高效数据探索的基础。与关系型数据库不同,ElasticSearch 是基于文档的搜索引擎,数据建模的重点在于如何将数据组织成易于索引和检索的文档结构。

良好的数据建模可以提高查询性能、减少存储开销,并确保数据的一致性。例如,对于一个电子商务应用,产品数据的建模需要考虑如何存储产品的各种属性,如名称、描述、价格、库存等,以及如何关联相关数据,如产品评论和类别信息。

映射(Mapping)的概念与作用

映射定义了文档的字段及其数据类型,类似于关系型数据库中的表结构定义。通过映射,ElasticSearch 知道如何对文档中的字段进行索引和存储。

例如,对于一个包含 “name”(字符串类型)和 “age”(整数类型)字段的文档,映射可以这样定义:

{
    "properties": {
        "name": {
            "type": "text"
        },
        "age": {
            "type": "integer"
        }
    }
}

在上述映射中,“name” 字段被定义为 “text” 类型,适合用于全文搜索;“age” 字段被定义为 “integer” 类型,用于存储整数值。

创建映射的方法

  1. 在创建索引时定义映射:可以在创建索引的同时指定映射。以下是使用 Elasticsearch-py 创建索引并定义映射的示例:
index_name = 'users'
mapping = {
    "properties": {
        "name": {
            "type": "text"
        },
        "age": {
            "type": "integer"
        }
    }
}

es.indices.create(index=index_name, body={"mappings": mapping})
  1. 动态映射:ElasticSearch 支持动态映射,当你索引一个文档时,如果索引中不存在该文档字段的映射定义,ElasticSearch 会根据文档内容自动推断字段类型并创建映射。例如:
document = {
    "name": "John Doe",
    "age": 30
}

es.index(index=index_name, id="1", body=document)

在上述代码中,由于我们没有事先定义 “users” 索引的映射,ElasticSearch 会根据文档内容动态创建一个包含 “name”(text 类型)和 “age”(integer 类型)字段的映射。

然而,动态映射虽然方便,但在一些复杂场景下可能无法满足需求,例如需要对字段进行特殊的索引设置或数据类型转换。在这种情况下,显式定义映射是更好的选择。

映射中的重要设置

  1. 索引选项:可以设置字段是否被索引。例如,对于一些不需要进行搜索的字段,如产品图片的二进制数据,可以将其设置为不索引:
{
    "properties": {
        "image_data": {
            "type": "binary",
            "index": false
        }
    }
}
  1. 分析器(Analyzer):分析器用于对文本字段进行分词和处理。ElasticSearch 提供了多种内置分析器,如标准分析器、简单分析器等。例如,对于一个需要进行全文搜索的 “description” 字段,可以指定使用标准分析器:
{
    "properties": {
        "description": {
            "type": "text",
            "analyzer": "standard"
        }
    }
}

分析器的选择会影响搜索结果的准确性和相关性,在实际应用中需要根据数据特点和搜索需求进行合理选择。

数据导入与预处理

准备数据

在将数据导入 ElasticSearch 之前,需要确保数据的格式正确且符合 ElasticSearch 的要求。通常,数据以 JSON 格式准备。

例如,如果你有一个 CSV 文件包含产品信息,你需要将其转换为 JSON 格式。可以使用 Python 的 pandas 库来完成这个转换:

import pandas as pd

# 读取 CSV 文件
df = pd.read_csv('products.csv')

# 将 DataFrame 转换为 JSON 格式
json_data = df.to_json(orient='records')

print(json_data)

上述代码读取一个 CSV 文件,并将其转换为适合 ElasticSearch 导入的 JSON 格式。

批量导入数据

为了提高数据导入效率,ElasticSearch 提供了批量导入的功能。在 Elasticsearch-py 中,可以使用 bulk 方法实现批量导入。

假设你有一个包含多个产品文档的 JSON 文件 products.json,以下是批量导入的代码示例:

from elasticsearch.helpers import bulk

# 读取 JSON 文件
with open('products.json') as f:
    data = f.readlines()

actions = []
for line in data:
    doc = eval(line)
    action = {
        "_index": "products",
        "_source": doc
    }
    actions.append(action)

bulk(es, actions)

在上述代码中,我们首先读取 JSON 文件中的每一行数据,然后将其转换为适合 bulk 方法的操作列表。每个操作指定了要导入的索引(“products”)和文档内容。

数据预处理

在导入数据之前,通常需要对数据进行一些预处理,以提高数据质量和搜索性能。

  1. 文本清洗:对于文本字段,可能需要去除 HTML 标签、特殊字符等。例如,使用 Python 的 re 模块去除文本中的 HTML 标签:
import re

text = "<p>This is a sample text with <b>HTML tags</b>.</p>"
clean_text = re.sub('<.*?>', '', text)
print(clean_text)
  1. 数据标准化:对于数值字段,可能需要进行标准化处理,例如将价格转换为统一的货币单位。在 Python 中,可以使用 pandas 库对 DataFrame 中的数值列进行标准化:
import pandas as pd

df = pd.read_csv('products.csv')
# 假设 'price' 列是美元价格,转换为人民币价格(假设汇率为 6.5)
df['price_cny'] = df['price'] * 6.5
df = df.drop('price', axis=1)

df.to_csv('products_preprocessed.csv', index=False)

通过数据预处理,可以使数据更适合 ElasticSearch 的索引和检索,从而提高数据探索的效率和准确性。

安全与权限设置

ElasticSearch 安全机制概述

ElasticSearch 提供了一系列安全机制来保护集群和数据的安全,包括身份验证、授权和加密等方面。

身份验证用于验证用户的身份,确保只有合法用户可以访问集群。授权则决定了已认证用户对集群资源(如索引、文档等)的操作权限。加密用于保护数据在传输和存储过程中的保密性。

启用身份验证

  1. 内置用户管理:ElasticSearch 提供了内置的用户管理功能。可以使用 elasticsearch-users 工具来创建、管理用户。例如,在 ElasticSearch 安装目录的 bin 文件夹下,执行以下命令创建一个新用户:
./elasticsearch-users useradd myuser -p mypassword -r superuser

在上述命令中,我们创建了一个名为 “myuser” 的用户,密码为 “mypassword”,并赋予了 “superuser” 角色,该角色具有最高权限。

  1. 配置 HTTP 基本身份验证:编辑 elasticsearch.yml 文件,启用 HTTP 基本身份验证:
xpack.security.enabled: true
xpack.security.http.ssl:
  enabled: true
  keystore.path: certs/elastic-certificates.p12

上述配置启用了 X-Pack 安全功能,并配置了 SSL 证书路径用于加密传输。重启 ElasticSearch 使配置生效。

授权设置

在 ElasticSearch 中,可以通过角色和权限来进行授权管理。角色定义了一组权限,用户通过被赋予相应的角色来获得权限。

例如,创建一个只读角色:

{
    "cluster": [
        "cluster:monitor/main"
    ],
    "indices": [
        {
            "names": ["*"],
            "privileges": ["read"]
        }
    ]
}

上述 JSON 定义了一个名为 “readonly” 的角色,该角色具有集群监控权限和所有索引的只读权限。

然后,可以将这个角色赋予用户:

./elasticsearch-users roleadd readonly -d '{"cluster": ["cluster:monitor/main"], "indices": [{"names": ["*"], "privileges": ["read"]}]}'
./elasticsearch-users useradd readonlyuser -p readonlypassword -r readonly

通过上述设置,“readonlyuser” 用户只能对 ElasticSearch 集群进行只读操作,无法进行写入或删除等操作。

数据加密

  1. 传输层加密:如前面配置中所示,通过配置 SSL 证书来实现传输层加密。ElasticSearch 支持使用 P12 格式的证书。可以使用 elasticsearch-certutil 工具生成证书:
./elasticsearch-certutil ca
./elasticsearch-certutil cert --ca elastic-stack-ca.p12

生成证书后,将其放置在指定的路径(如 certs 文件夹),并在 elasticsearch.ymlkibana.yml 中配置证书路径。

  1. 存储层加密:ElasticSearch 支持对存储的数据进行加密,通过配置 node.attr.encrypt_data: trueelasticsearch.yml 文件中启用。这需要在节点启动时提供加密密钥。

通过以上安全与权限设置,可以确保 ElasticSearch 集群和数据的安全性,为数据探索提供可靠的环境。