通过客户端访问阿里云Elasticsearch

本文介绍如何使用PHP、Python、Java和Go语言访问阿里云Elasticsearch实例,并为您提供示例代码和注意事项。

准备工作

  • 安装Java,要求JDK版本为1.8及以上。

    安装方法请参见安装JDK

  • 创建阿里云Elasticsearch实例。

    具体操作请参见创建阿里云Elasticsearch实例

    说明

    建议创建与客户端相同版本的实例,避免出现兼容性问题。Elasticsearch与客户端版本兼容性的详细信息,请参见Compatibility

  • 开启阿里云Elasticsearch实例的自动创建索引功能。

    具体操作请参见配置YML参数

  • 配置阿里云Elasticsearch实例的白名单,确保网络互通。

    • 如果运行代码的服务器在公网环境下,可通过阿里云Elasticsearch实例的公网地址进行连通。连通前,需要开启阿里云Elasticsearch实例的公网地址,并修改公网地址访问白名单,将服务器的公网IP地址加入白名单中。具体操作步骤请参见配置实例公网或私网访问白名单

      注意
      • 如果您使用的是WIFI、宽带等网络,需要将公网出口的跳板机IP地址配置进去。建议您通过淘宝IP地址库查询。

      • 您也可以将白名单配置为0.0.0.0/0,允许所有IPv4地址访问阿里云Elasticsearch实例。此配置会导致实例完全暴露在公网中,增加安全风险,配置前请确认您是否可以接受这个风险。

    • 如果运行代码的服务器与阿里云Elasticsearch实例在同一专有网络VPC(Virtual Private Cloud)中,可通过阿里云Elasticsearch实例的内网地址进行连通。连通前,需要确保VPC私网访问白名单(默认为0.0.0.0/0)中已添加了服务器的内网IP地址。

注意事项

  • Elasticsearch的PHP客户端提供的默认连接池并不适合云上环境。阿里云Elasticsearch提供了负载均衡的域名服务,因此PHP客户端访问程序必须使用SimpleConnectionPool作为连接池,否则在触发阿里云Elasticsearch重启操作时会出现访问连接异常的问题。同时,PHP客户端访问程序必须具备访问连接失败重连的机制。因为在PHP客户端访问程序使用SimpleConnectionPool作为连接池后,不排除在触发阿里云Elasticsearch重启操作时还会出现访问连接异常问题(例如提示No enabled connection)。

  • Java客户端包括3种类型:Transport Client、Low Level REST Client和High Level REST Client,各类型的代码示例请参见概述。本文以6.7版本的High Level REST Client为例。

  • 由于Java Transport Client通过TCP与Elasticsearch进行通信,当客户端与不同版本的Elasticsearch通信时,会存在兼容性问题,所以官方在高版本集群中已弃用Transport Client。如果您已经创建了5.5或5.6版本的Elasticsearch集群,分别使用Transport Client 5.5或5.6版本与Elasticsearch建立连接时会提示NoNodeAvailableException的错误。推荐使用Transport Client 5.3.3或Java Low Level REST Client来访问Elasticsearch集群,以保障版本的兼容性。

  • 使用Go语言连接阿里云Elasticsearch前,您需要先安装Go编译环境,详细信息请参见The Go Programming Language。本文示例使用Go 1.13.4版本。

示例代码

以下列举了常见客户端访问阿里云Elasticsearch实例的代码示例。

//以Go 1.13.4版本为例。
package main

import (
    "context"
    "gopkg.in/olivere/elastic.v5"
    "gopkg.in/olivere/elastic.v5/config"
    "log"
)

const (
    url      = "<YourEsHost>"     
    username = "<UserName>"        
    password = "<YourPassword>"       
)

func main() {
    var sniff = false     //sniff必须设置为false,防止二次探测,导致连接失败。
    cfg := &config.Config{
        URL:      url,
        Username: username,
        Password: password,
    }

    cfg.Sniff = &sniff          
    var client, err = elastic.NewClientFromConfig(cfg)
    if err != nil {
        log.Println(err)
        return
    }

    exists, err := client.IndexExists("<YourEsIndex>").Do(context.Background())   //在阿里云Elasticsearch上新建一个索引,并根据连接状态返回日志信息。
    if err != nil {
        log.Println(err)
    }
    log.Println(exists)
}
//以6.7版本的High Level REST Client为例。
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;

import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class RestClientTest67 {

    private static final RequestOptions COMMON_OPTIONS;

    static {
        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();

        // 默认缓存限制为100MB,此处修改为30MB。
        builder.setHttpAsyncResponseConsumerFactory(
                new HttpAsyncResponseConsumerFactory
                        .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024));
        COMMON_OPTIONS = builder.build();
    }

    public static void main(String[] args) {
        // 阿里云Elasticsearch集群需要basic auth验证。
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
       //访问用户名和密码为您创建阿里云Elasticsearch实例时设置的用户名和密码,也是Kibana控制台的登录用户名和密码。
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("<UserName>", "<YourPassword>"));

        // 通过builder创建rest client,配置http client的HttpClientConfigCallback。
       // 单击所创建的Elasticsearch实例ID,在基本信息页面获取公网地址,即为ES集群地址。
        RestClientBuilder builder = RestClient.builder(new HttpHost("<YourEsHost>", 9200, "http"))
                .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                    @Override
                    public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                        return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                    }
                });

        // RestHighLevelClient实例通过REST low-level client builder进行构造。
        RestHighLevelClient highClient = new RestHighLevelClient(builder);

        try {
            // 创建request。
            Map<String, Object> jsonMap = new HashMap<>();
           jsonMap.put("<YourEsField1>", "<YourEsFieldValue1>");
           jsonMap.put("<YourEsField2>", "<YourEsFieldValue2>");
           IndexRequest indexRequest = new IndexRequest("<YourEsIndex>", "<YourEsType>", "<YourEsId>").source(jsonMap);

            // 同步执行,并使用自定义RequestOptions(COMMON_OPTIONS)。
            IndexResponse indexResponse = highClient.index(indexRequest, COMMON_OPTIONS);

            long version = indexResponse.getVersion();

            System.out.println("Index document successfully! " + version);

            highClient.close();

        } catch (IOException ioException) {
            // 异常处理。
        }
    }
}
<?php
require 'vendor/autoload.php';
use Elasticsearch\ClientBuilder;

$client = ClientBuilder::create()->setHosts([
  [
    'host'   => '<YourEsHost>',
    'port'   => '9200',
    'scheme' => 'http',
    'user'   => '<UserName>',
    'pass'   => '<YourPassword>'
  ]
])->setConnectionPool('\Elasticsearch\ConnectionPool\SimpleConnectionPool', [])
  ->setRetries(10)->build();

$indexParams = [
  'index'  => '<YourEsIndex>',
  'type'   => '<YourEsType>',
  'id'     => '<YourEsId>',
  'body'   => ['<YourEsField>' => '<YourEsFieldValue>'],
  'client' => [
    'timeout'         => 10,
    'connect_timeout' => 10
  ]
];
$indexResponse = $client->index($indexParams);
print_r($indexResponse);

$searchParams = [
  'index'  => '<YourEsIndex>',
  'type'   => '<YourEsType>',
  'body'   => [
    'query' => [
      'match' => [
        '<YourEsField>' => '<YourEsFieldValue>'
      ]
    ]
  ],
  'client' => [
    'timeout'         => 10,
    'connect_timeout' => 10
  ]
];
$searchResponse = $client->search($searchParams);
print_r($searchResponse);
?>
from elasticsearch import Elasticsearch, RequestsHttpConnection
import certifi
es = Elasticsearch(
    ['<YourEsHost>'],
    http_auth=('<UserName>', '<YourPassword>'),
    port=9200,
    use_ssl=False
)
res = es.index(index="<YourEsIndex>", doc_type="<YourEsType>", id=<YourEsId>, body={"<YourEsField1>": "<YourEsFieldValue1>", "<YourEsField2>": "<YourEsFieldValue2>"})
res = es.get(index="<YourEsIndex>", doc_type="<YourEsType>", id=<YourEsId>)
print(res['_source'])

使用代码时,您需要将以下字段替换为对应的值。

参数

说明

<YourEsHost>

阿里云Elasticsearch实例的内网或外网地址,可在基本信息页面获取,获取方法请参见查看实例的基本信息

<UserName>

访问阿里云Elasticsearch实例的用户名,默认为elastic。

<YourPassword>

访问阿里云Elasticsearch实例的密码。elastic用户的密码在创建实例时设定,如果忘记可进行重置,重置密码的注意事项和操作步骤请参见重置实例访问密码

<YourEsIndex>

索引名称。

<YourEsType>

文档类型。

注意

Elasticsearch 7.0以下版本可自定义文档类型,7.0及以上版本固定为

_doc

<YourEsId>

文档ID。

<YourEsField>

字段名称。

<YourEsFieldValue>

<YourEsField>的值。

相关文档

阿里云首页 检索分析服务Elasticsearch版 相关技术圈