ElasticSearch (三)Java集成Elasticsearch RestHighLevelClient

 

1.在spring原有及基础上新增Maven依赖


        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>6.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>6.3.2</version>
        </dependency>

2.ES 配置参数

创建 ElasticSearchProperties类
@ConfigurationProperties(prefix = "com.commons.es")
public class ElasticSearchProperties {
    private String host = "localhost";
    private int port = 9200;
    private String schema = "http";
    private int connectTimeOut = 1000;
    private int socketTimeOut = 30000;
    private int connectionRequestTimeOut = 500;
    private int maxConnectNum = 100;
    private int maxConnectPerRoute = 100;
    private boolean uniqueConnectTimeConfig = true;
    private boolean uniqueConnectNumConfig = true;
    private Integer shades = 3;//分片数
    private Integer replicas = 2;//副本数
}

3.ES Java客户端连接

创建ElasticSearchAutoConfig类
@Configuration
//可根据自己所在的目录要扫描的参数,如下图
@ComponentScan(basePackages = "com.manager.commons.es") 
@EnableConfigurationProperties(ElasticSearchProperties.class)
public class ElasticSearchAutoConfig {
    private HttpHost httpHost;
    private RestClientBuilder builder;
    private RestHighLevelClient client;

    @Autowired
    private ElasticSearchProperties elasticSearchProperties;

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        httpHost = new HttpHost(elasticSearchProperties.getHost(), elasticSearchProperties.getPort(), elasticSearchProperties.getSchema());
        builder = RestClient.builder(httpHost);
        if (elasticSearchProperties.isUniqueConnectTimeConfig()) {
            setConnectTimeOutConfig();
        }
        if (elasticSearchProperties.isUniqueConnectNumConfig()) {
            setMutiConnectConfig();
        }
        client = new RestHighLevelClient(builder);
        return client;
    }

    /**
     * 异步httpclient的连接延时配置
     */
    public void setConnectTimeOutConfig() {
        builder.setRequestConfigCallback(requestConfigBuilder -> {
            requestConfigBuilder.setConnectTimeout(elasticSearchProperties.getConnectTimeOut());
            requestConfigBuilder.setSocketTimeout(elasticSearchProperties.getSocketTimeOut());
            requestConfigBuilder.setConnectionRequestTimeout(elasticSearchProperties.getConnectionRequestTimeOut());
            return requestConfigBuilder;
        });
    }


    /**
     * 异步httpclient的连接数配置
     */
    public void setMutiConnectConfig() {
        builder.setHttpClientConfigCallback(httpClientBuilder -> {
            httpClientBuilder.setMaxConnTotal(elasticSearchProperties.getMaxConnectNum());
            httpClientBuilder.setMaxConnPerRoute(elasticSearchProperties.getMaxConnectPerRoute());
            return httpClientBuilder;
        });
    }

    /**
     * 关闭连接
     */
    public void close() {
        if (client != null) {
            try {
                client.close();
            } catch (IOException e) {
                log.error("es close error", e);
            }
        }
    }
}

4.创建索引并验证结果


/**
 * 数据类型
 *
 * @author CHANG
 * @date 2019/7/21 14:43
 */
public interface DailyEsEntity {

    Map<String, Object> genInitMap();

    Map<String, String> DATE_MAP = Collections.unmodifiableMap(new HashMap() {
        {
            put("type", "date");
        }
    });
    Map<String, String> LONG_MAP = Collections.unmodifiableMap(new HashMap() {
        {
            put("type", "long");
        }
    });
    Map<String, String> KEYWORD_MAP = Collections.unmodifiableMap(new HashMap() {
        {
            put("type", "keyword");
        }
    });
    Map<String, String> INTEGER_MAP = Collections.unmodifiableMap(new HashMap() {
        {
            put("type", "integer");
        }
    });
    Map<String, String> BOOLEAN_MAP = Collections.unmodifiableMap(new HashMap() {
        {
            put("type", "boolean");
        }
    });
    Map<String, String> TEXT_MAP = Collections.unmodifiableMap(new HashMap() {
        {
            put("type", "text");
        }
    });

}
/**
 *自定义注解标识文档
 * @author Chang
 * @date 2019/3/27 14:09
 */
@Qualifier
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface ESDocument {
    /**
     * 标识文档
     * @return indexName
     */
    String indexName();

    /**
     *是否是文档
     * @return  boolean
     */
    boolean dailyIndex() default false;
}
/**
 *es文档mapping及类型
 * @author CHANG
 * @date 2019/7/21 14:34
 */
@Data
@ESDocument(indexName = "user_result", dailyIndex = true)
public class User implements DailyEsEntity {
    public static final String USER_INDEX = "user_result";

    private Long id;
    private String name;
    private Integer age;
    private Boolean isDelete;
    private Data createTime;

    @Override
    public Map<String, Object> genInitMap() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", LONG_MAP);
        map.put("name", KEYWORD_MAP);
        map.put("age", INTEGER_MAP);
        map.put("isDelete", BOOLEAN_MAP);
        map.put("createTime", DATE_MAP);
        return map;
    }
}

/**
 * es索引创建
 * @author CHANG
 * @date 2019/7/21 15:01
 */
@Slf4j
public class ESInitManager {
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Autowired
    private ElasticSearchProperties elasticSearchProperties;

    /**
     * 判断index是否存在
     *
     * @param index index
     * @return indexExists 判断索引是否存在
     * @throws Exception ex
     */
    boolean indexExists(String index) throws Exception {
        GetIndexRequest request = new GetIndexRequest();
        request.indices(index);
        request.local(false);
        request.humanReadable(true);
        boolean exists = restHighLevelClient.indices().exists(request);
        return exists;
    }

    /**
     * 创建索引
     *
     * @param index      索引
     * @param indexType  类型
     * @param properties indexType 数据类型
     * @return boolean
     */
    public boolean init(String index, String indexType, Map<String, Object> properties) {
        try {
            log.info("init {}", index);
            if (indexExists(index)) {
                return true;
            }
            CreateIndexRequest request = new CreateIndexRequest(index);
            request.settings(Settings.builder()
                    .put("index.number_of_shards", elasticSearchProperties.getShades())
                    .put("index.number_of_replicas", elasticSearchProperties.getReplicas())); //副本数
            Map<String, Object> jsonMap = new HashMap<>();
            Map<String, Object> mapping = new HashMap<>();
            mapping.put("properties", properties);
            jsonMap.put(indexType, mapping);
            request.mapping(indexType, jsonMap);
            CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request);
            boolean acknowledged = createIndexResponse.isAcknowledged();
            log.info("CreateIndexResponse " + acknowledged);
            return acknowledged;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

}

/**
 * @author CHANG
 * @date 2019/7/21 15:14
 */
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@Slf4j
public class ESInitManagerTest {

    @Autowired
    private ESInitManager esInitManager;


    /**
     * 这里我采用索引与类型的名字一样可根据自己的需求改变名称
     */
    @Test
    public void init() {
        User user = new User();
        boolean init = esInitManager.init(user.USER_INDEX, user.USER_INDEX, user.genInitMap());
        log.info("init {}", init);
    }
}

5.es单节点创建索引副本为分配的问题

上面截图可以看出存在3个unassigned的分片,新建索引user_result的时候,分片数为3,副本数为2,新建之后集群状态成为yellow,其根本原因是因为集群存在没有启用的副本分片。


副本分片的主要目的就是为了故障转移,如果持有主分片的节点挂掉了,一个副本分片就会晋升为主分片的角色。
那么可以看出来副本分片和主分片是不能放到一个节点上面的,可是在只有一个节点的集群里,副本分片没有办法分配到其他的节点上,所以出现所有副本分片都unassigned得情况。

因为只有一个节点,如果存在主分片节点挂掉了,那么整个集群理应就挂掉了,不存在副本分片升为主分片的情况。
解决办法就是,在单节点的elasticsearch集群,删除存在副本分片的索引,新建索引的副本都设为0。然后再查看集群状态

//修改副本数
@ConfigurationProperties(prefix = "com.commons.es")
public class ElasticSearchProperties {
    private String host = "localhost";
    private int port = 9200;
    private String schema = "http";
    private int connectTimeOut = 1000;
    private int socketTimeOut = 30000;
    private int connectionRequestTimeOut = 500;
    private int maxConnectNum = 100;
    private int maxConnectPerRoute = 100;
    private boolean uniqueConnectTimeConfig = true;
    private boolean uniqueConnectNumConfig = true;
    private Integer shades = 3;//分片数
    private Integer replicas = 0;//副本数
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章