ApsaraDB for SelectDB permet d'interroger directement les données Elasticsearch via un catalog Elasticsearch, ce qui rend possible l'analyse OLAP fédérée sans déplacement des données. Ce catalog mappe automatiquement les métadonnées des index Elasticsearch et prend en charge les jointures multi-index au sein d'Elasticsearch ainsi que les jointures inter-systèmes entre SelectDB et Elasticsearch.
Versions prises en charge : Elasticsearch 5.X et ultérieures.
Prérequis
Avant de commencer, assurez-vous que les conditions suivantes sont remplies :
Tous les nœuds de votre cluster Elasticsearch doivent être connectés à l'instance SelectDB. Ils doivent partager le même Virtual Private Cloud (VPC), ou bien une connectivité inter-VPC doit être configurée. Pour plus de détails, consultez Que faire si la connexion entre une instance ApsaraDB for SelectDB et une source de données échoue ?
Les adresses IP de tous les nœuds du cluster Elasticsearch doivent figurer dans la liste d'autorisation d'adresses IP de l'instance SelectDB. Reportez-vous à Configurer une liste d'autorisation d'adresses IP
Si le cluster Elasticsearch impose une liste d'autorisation, les adresses IP VPC de l'instance SelectDB doivent y être ajoutées. Pour obtenir ces adresses, consultez Comment afficher les adresses IP du VPC auquel appartient mon instance ApsaraDB SelectDB ?
Une connaissance de base des catalogs SelectDB est requise. Consultez Data lakehouse
Créer un catalog Elasticsearch
CREATE CATALOG test_es PROPERTIES (
"type"="es",
"hosts"="http://127.0.0.1:9200",
"user"="test_user",
"password"="test_passwd",
"nodes_discovery"="false"
);
Elasticsearch ne possédant pas de concept de base de données, SelectDB crée automatiquement une base de données unique nommée default_db sous ce catalog. Après avoir basculé vers le catalog avec la commande SWITCH, SelectDB accède automatiquement à default_db ; aucune instruction USE default_db n'est nécessaire.
Paramètres
| Paramètre | Obligatoire | Valeur par défaut | Description |
|---|---|---|---|
hosts |
Oui | — | URL de la source de données Elasticsearch. Accepte une ou plusieurs URL, ou l'URL d'une instance Server Load Balancer (SLB) placée devant le cluster. |
user |
Non | — | Compte utilisé pour accéder à la source de données Elasticsearch. |
password |
Non | — | Mot de passe associé au compte. |
doc_value_scan |
Non | true | Active le stockage orienté colonne (doc_values) pour l'interrogation des valeurs de champs. |
keyword_sniff |
Non | true | Détecte les champs TEXT et effectue les requêtes via leurs sous-champs KEYWORD correspondants. Si défini sur false, les requêtes correspondent aux termes tokenisés du champ TEXT. |
nodes_discovery |
Non | true | Active la découverte automatique des nœuds. Définissez cette valeur sur false lors de l'utilisation d'Alibaba Cloud Elasticsearch, car le trafic transite par une instance SLB et les nœuds ne sont pas exposés directement. |
ssl |
Non | false | Active l'accès HTTPS. SelectDB approuve toutes les requêtes HTTPS provenant des nœuds frontend (FE) et backend (BE), quelle que soit la validité du certificat SSL. |
mapping_es_id |
Non | false | Mappe le champ de métadonnées _id de l'index Elasticsearch. |
like_push_down |
Non | true | Convertit les conditions LIKE en wildcards Elasticsearch et les délègue à Elasticsearch. Cela augmente l'utilisation du CPU côté Elasticsearch. |
include_hidden_index |
Non | false | Inclut les index masqués. |
Seule l'authentification de base HTTP est prise en charge. Le compte doit disposer d'un accès en lecture aux endpoints/_cluster/state/et_nodes/http, ainsi que des permissions de lecture sur les index. Si HTTPS n'est pas activé, le compte et le mot de passe sont facultatifs. Pour les index Elasticsearch 5.x ou 6.x contenant plusieurs types, SelectDB lit uniquement les données du premier type.
Interroger les données
Une fois le catalog créé, interrogez les tables Elasticsearch de la même manière que les tables internes SelectDB. Les trois approches suivantes sont équivalentes :
-- Switch to the catalog, then query
SWITCH test_es;
SELECT * FROM es_table LIMIT 10;
-- Use the fully qualified database path
USE test_es.default_db;
SELECT * FROM es_table LIMIT 10;
-- Use the fully qualified table name directly
SELECT * FROM test_es.default_db.es_table LIMIT 10;
Les fonctionnalités Rollup, pré-agrégation et vues matérialisées ne sont pas disponibles pour les tables Elasticsearch externes.
Requêtes de base
SELECT * FROM es_table WHERE k1 > 1000 AND k3 = 'term' OR k4 LIKE 'fu*z_';
Requête étendue esquery
Utilisez esquery(field, QueryDSL) pour déléguer à Elasticsearch des requêtes inexprimables en SQL, telles que match_phrase et geo_shape. Le paramètre field associe la requête à un index. Le paramètre QueryDSL est un objet JSON comportant exactement une clé racine.
Requête match_phrase :
SELECT * FROM es_table WHERE esquery(k4, '{"match_phrase": {"k4": "selectdb on es"}}');
Requête geo_shape :
SELECT * FROM es_table WHERE esquery(k4, '{"geo_shape": {"location": {"shape": {"type": "envelope", "coordinates": [[13, 53], [14, 52]]}, "relation": "within"}}}');
Requête bool :
SELECT * FROM es_table WHERE esquery(k4, '{"bool": {"must": [{"terms": {"k1": [11, 12]}}, {"terms": {"k2": [100]}}]}}');
Mappage des types de colonnes
| Type Elasticsearch | Type SelectDB | Notes |
|---|---|---|
| NULL | NULL | |
| BOOLEAN | BOOLEAN | |
| BYTE | TINYINT | |
| SHORT | SMALLINT | |
| INTEGER | INT | |
| LONG | BIGINT | |
| UNSIGNED_LONG | LARGEINT | |
| FLOAT | FLOAT | |
| HALF_FLOAT | FLOAT | |
| DOUBLE | DOUBLE | |
| SCALED_FLOAT | DOUBLE | |
| DATE | DATE | Formats pris en charge : par défaut, yyyy-MM-dd HH:mm:ss, yyyy-MM-dd, epoch_millis |
| KEYWORD | STRING | |
| TEXT | STRING | |
| IP | STRING | |
| NESTED | STRING | |
| OBJECT | STRING | |
| OTHER | UNSUPPORTED |
Type ARRAY
Bien qu'Elasticsearch ne possède pas de type ARRAY explicite, un champ peut contenir zéro ou plusieurs valeurs. Pour déclarer un champ comme tableau dans SelectDB, ajoutez une entrée array_fields sous _meta.selectdb dans le mapping de l'index.
Exemple de structure de données pour l'index doc :
{
"array_int_field": [1, 2, 3, 4],
"array_string_field": ["selectdb", "is", "the", "best"],
"id_field": "id-xxx-xxx",
"timestamp_field": "2022-11-12T12:08:56Z",
"array_object_field": [{"name": "xxx", "age": 18}]
}
Mettez à jour le mapping pour déclarer les champs de type tableau :
# Elasticsearch 7.x and later
curl -X PUT "localhost:9200/doc/_mapping?pretty" -H 'Content-Type: application/json' -d '
{
"_meta": {
"selectdb": {
"array_fields": [
"array_int_field",
"array_string_field",
"array_object_field"
]
}
}
}'
# Elasticsearch 6.x and earlier
curl -X PUT "localhost:9200/doc/_mapping?pretty" -H 'Content-Type: application/json' -d '
{
"_doc": {
"_meta": {
"selectdb": {
"array_fields": [
"array_int_field",
"array_string_field",
"array_object_field"
]
}
}
}
}'
Bonnes pratiques
Délégation des conditions de filtrage
SelectDB délègue les conditions de filtrage à Elasticsearch afin que seules les données correspondantes soient retournées, réduisant ainsi la charge CPU, mémoire et E/S sur les deux systèmes. Le tableau suivant illustre la correspondance entre les opérateurs SQL et le Query DSL d'Elasticsearch.
| Syntaxe SQL | Requête Elasticsearch |
|---|---|
= |
term query |
IN |
terms query |
>, <, >=, <= |
range query |
AND |
bool.filter |
OR |
bool.should |
NOT |
bool.must_not |
NOT IN |
bool.must_not + terms query |
IS NOT NULL |
exists query |
IS NULL |
bool.must_not + exists query |
esquery |
Query DSL natif |
Activer le scan colonnaire pour accélérer les requêtes
Définissez enable_docvalue_scan sur true pour lire les valeurs des champs depuis le stockage orienté colonne (doc_values) plutôt que depuis le champ _source. Lorsque seules quelques colonnes sont interrogées, le scan colonnaire s'avère plus de dix fois plus rapide que la lecture depuis _source.
Lorsque le scan colonnaire est activé, SelectDB applique deux principes :
Au mieux : Si tous les champs interrogés ont
doc_valueactivé, SelectDB lit intégralement les données depuis le stockage orienté colonne.Rétrogradation automatique : Si l'un des champs interrogés ne dispose pas de
doc_value, SelectDB revient à la lecture depuis_sourcepour l'ensemble des champs.
Les champs TEXT ne peuvent pas utiliser le stockage orienté colonne. Si un champ TEXT figure dans la requête, SelectDB lit les données depuis
_source.Lors de l'interrogation de 25 champs ou plus, la différence de performance entre le scan colonnaire et
_sourcedevient négligeable.
Détecter les champs KEYWORD
Définissez enable_keyword_sniff sur true pour que SelectDB utilise automatiquement les sous-champs KEYWORD lors des requêtes d'égalité sur des champs STRING.
Lorsqu'Elasticsearch crée automatiquement un index, les champs STRING reçoivent à la fois un champ TEXT et un sous-champ KEYWORD :
"k4": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
Sans la détection de mots-clés, la condition SQL k4 = "SelectDB On ES" génère le Query DSL suivant :
"term": {"k4": "SelectDB On ES"}
Puisque k4 est un champ TEXT, sa valeur est tokenisée en selectdb, on et es. Aucun de ces termes ne correspondant à l'expression complète, aucun résultat n'est retourné.
Avec enable_keyword_sniff défini sur true, SelectDB réécrit automatiquement la condition pour cibler le sous-champ KEYWORD :
"term": {"k4.keyword": "SelectDB On ES"}
Le champ KEYWORD stockant la valeur originale non modifiée, l'expression exacte correspond correctement.
Activer la découverte de nœuds
Définissez nodes_discovery sur true pour permettre à SelectDB de découvrir tous les nœuds de données Elasticsearch possédant des shards alloués.
Alibaba Cloud Elasticsearch achemine le trafic via une instance SLB, ce qui empêche l'accès direct aux nœuds individuels du cluster. Définissez toujoursnodes_discoverysurfalselors de la connexion à Alibaba Cloud Elasticsearch.
Activer HTTPS
Définissez ssl sur true pour vous connecter au cluster Elasticsearch via HTTPS. SelectDB approuve toutes les requêtes HTTPS provenant des nœuds FE et BE, indépendamment de la validité du certificat SSL.
Gérer les champs temporels
Les instructions de cette section s'appliquent uniquement aux tables Elasticsearch externes. Pour les catalogs Elasticsearch, les champs temporels sont automatiquement mappés vers le type DATE ou DATETIME.
Configurez le format du champ de date dans Elasticsearch pour prendre en charge un large éventail d'entrées :
"dt": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
Dans SelectDB, définissez le champ comme date, datetime ou varchar. Toutes les conditions de filtrage suivantes sont correctement déléguées :
SELECT * FROM doe WHERE k2 > '2020-06-21';
SELECT * FROM doe WHERE k2 < '2020-06-21 12:00:00';
SELECT * FROM doe WHERE k2 < 1593497011;
SELECT * FROM doe WHERE k2 < now();
SELECT * FROM doe WHERE k2 < date_format(now(), '%Y-%m-%d');
Si aucun
formatn'est défini dans Elasticsearch, la valeur par défaut eststrict_date_optional_time||epoch_millis.Lors de l'importation de valeurs d'horodatage dans un champ DATE sous Elasticsearch, l'horodatage doit être exprimé en millisecondes. Elasticsearch exige une précision en millisecondes pour son traitement interne ; toute autre unité provoque des erreurs.
Interroger le champ _id
Elasticsearch attribue automatiquement un identifiant _id globalement unique à chaque document lorsqu'aucun n'est spécifié lors de l'importation. Pour interroger _id depuis une table externe, déclarez-le comme une colonne VARCHAR :
CREATE EXTERNAL TABLE `doe` (
`_id` varchar COMMENT "",
`city` varchar COMMENT ""
) ENGINE=ELASTICSEARCH
PROPERTIES (
"hosts" = "http://127.0.0.1:8200",
"user" = "root",
"password" = "root",
"index" = "doe"
);
Pour interroger _id depuis un catalog Elasticsearch, définissez mapping_es_id sur true.
Filtrez le champ
_iduniquement avec l'opérateur=ouIN.Le champ
_iddoit être de typeVARCHAR.
Limitations
Rollup, pré-agrégation, vues matérialisées : Ces fonctionnalités ne sont pas prises en charge pour les tables Elasticsearch externes.
Fonctionnement
+----------------------------------------------+
| |
| SelectDB +------------------+ |
| | FE +--------------+-------+
| | | Request Shard Location
| +--+-------------+-+ | |
| ^ ^ | |
| | | | |
| +-------------------+ +------------------+ | |
| | | | | | | | |
| | +----------+----+ | | +--+-----------+ | | |
| | | BE | | | | BE | | | |
| | +---------------+ | | +--------------+ | | |
+----------------------------------------------+ |
| | | | | | |
| | | | | | |
| HTTP SCROLL | | HTTP SCROLL | |
+-----------+---------------------+------------+ |
| | v | | v | | |
| | +------+--------+ | | +------+-------+ | | |
| | | | | | | | | | |
| | | DataNode | | | | DataNode +<-----------+
| | | | | | | | | | |
| | | +<--------------------------------+
| | +---------------+ | | |--------------| | | |
| +-------------------+ +------------------+ | |
| Same Physical Node | |
| | |
| +-----------------------+ | |
| | | | |
| | MasterNode +<-----------------+
| ES | | |
| +-----------------------+ |
+----------------------------------------------+
Le flux de requête se déroule comme suit :
Le FE envoie une requête à l'hôte configuré pour obtenir les informations de port HTTP de tous les nœuds ainsi que la distribution des shards de l'index. En cas d'échec, le FE parcourt séquentiellement la liste des hôtes jusqu'à ce qu'une requête aboutisse.
Le FE génère un plan d'exécution de requête basé sur les métadonnées des nœuds et de l'index, puis le transmet aux BE concernés.
Chaque BE récupère simultanément les données des shards d'index Elasticsearch qui lui sont assignés, en mode streaming via l'API HTTP Scroll. La lecture s'effectue soit depuis
_source(orienté ligne), soit depuis doc_values (orienté colonne), selon la requête.SelectDB calcule les résultats finaux et les retourne.