需要的jar包,我这里使用maven的pom.xml导入,可以自己下载jar包并导入到项目中
com.alibaba
fastjson
1.2.24
org.apache.logging.log4j
log4j-core
2.10.0
junit
junit
4.2
test
org.apache.httpcomponents
httpclient
4.5.2
org.elasticsearch.client
transport
5.4.2
org.elasticsearch
elasticsearch
5.4.2
连接集群ClientConnect.java
package util;
import java.net.InetSocketAddress;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
/**
*
* @createDate 2018年3月8日
* @class_name ClientConnect 连接ES集群
* @description : 建立es的client,通过getClient()调用,只能连接es5.4.2
*/
public class ClientConnect {
private TransportClient client;
public TransportClient getClient() {
return client;
}
/**
*
* @param clusterName 集群名称
* @param clusterAddress 集群ip地址
* @param port 端口号
*/
@SuppressWarnings({ "unchecked", "resource" })
public ClientConnect(String clusterName, String clusterAddress, int port) {
Settings settings = Settings.builder().put("cluster.name", clusterName)
.build();
client = new PreBuiltTransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(
new InetSocketAddress(clusterAddress, port)));
System.out.println("success connect");
}
}
mapping结构获取与构建Mapping.java
package util;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSONObject;
/**
*
* @createDate 2018年3月22日
* @className Mapping
* @description : 获取和创建es服务器上的mapping
* @lastUpdate_time 2018年3月22日
*/
public class Mapping {
private static final Mapping mapping=new Mapping();
private Mapping(){}
public static Mapping getInstance(){
return mapping;
}
/**
*
* @description : 建立索引及其mapping
* @param index 索引名称
* @param json json格式的参数
* @return String es的json格式回复
* @throws Exception
*/
public String setMapping(String url,String index, String json) throws Exception {
// 构建网址实例
String reindexUri = url +"/"+ index;
URI uri = new URI(reindexUri);
// 建立连接客户端
HttpClient client = HttpClients.createDefault();
// 设置PUT请求的网址
HttpPut httpput = new HttpPut(uri);
// 设置允许添加json格式参数
httpput.addHeader(HTTP.CONTENT_TYPE, "application/json");
// 转化成请求格式
StringEntity se = new StringEntity(json);
// 添加参数
httpput.setEntity(se);
// 客户端发送请求,并获取回复
HttpResponse response = client.execute(httpput);
// 将回复转成JSON字符串
String responseJSON = EntityUtils.toString(response.getEntity());
return responseJSON;
}
/**
*
* @throws Exception
* @description : 获取指定索引的mapping
* @param url 服务器ip
* @param index 索引
* @param type 类型
* @return String es的json格式回复
* @throws Exception
*/
public String getMapping(String url,String index,String type) throws Exception {
// 构建网址实例
String reindexUri = url +"/"+ index
+ "/_mapping/" + type;
URI uri = new URI(reindexUri);
// 建立连接客户端
HttpClient client = HttpClients.createDefault();
// 设置GET请求的网址
HttpGet httpget = new HttpGet(uri);
// 客户端发送请求,并获取回复
HttpResponse response = client.execute(httpget);
// 将回复转成JSON字符串
String responseJSON = EntityUtils.toString(response.getEntity());
return responseJSON;
}
/**
*
* @description : 构建mapping,需根据自己需求填写
* @return json的mapping参数
*/
public JSONObject mapJsonBulid() {
// TODO Auto-generated method stub
JSONObject json = new JSONObject();
json.put("type", "keyword");
JSONObject json2 = new JSONObject();
json2.put("name", json);
JSONObject json3 = new JSONObject();
json3.put("type", "keyword");
json2.put("uuid", json3);
JSONObject json5 = new JSONObject();
json5.put("properties", json2);
JSONObject json6 = new JSONObject();
json6.put("current_user", json5);
JSONObject json7 = new JSONObject();
json7.put("mappings", json6);
System.out.println("createJson3" + json7.toJSONString());
return json7;
// {"mappings": {
// "current_user": {
// "properties": {
// "name": {"type": "keyword"},
// "unid": {"type": "keyword"}
// }}}}
}
}
package util;
import java.net.URI;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
/**
*
* @createDate 2018年3月22日
* @className HttpRequest
* @description : 向es服务器发送请求
* @lastUpdateTime 2018年3月22日
*/
public class HttpRequest {
private static final HttpRequest httpRequest = new HttpRequest();
private HttpRequest() {
}
public static HttpRequest getInstance() {
return httpRequest;
}
/**
*
* @description : 发送reindex请求,
* @param url 服务器ip地址
* @param json 发送的json格式参数
* @return String 服务器返回的json格式回复
* @throws Exception
*/
public String reindex(String url, String json) throws Exception {
HttpClient client = HttpClients.createDefault();
URI uri = new URI(url + "/_reindex");
HttpPost httppost = new HttpPost(uri);
httppost.addHeader(HTTP.CONTENT_TYPE, "application/json");
StringEntity se = new StringEntity(json);
httppost.setEntity(se);
HttpResponse response = client.execute(httppost);
return EntityUtils.toString(response.getEntity());
}
}
构建reindex的参数ReindexJSONBuild.java
package util;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import com.alibaba.fastjson.JSONObject;
/**
*
* @createDate 2018年3月22日
* @className ReindexJSONBuild
* @description : 构建reindex的json格式参数
* @lastUpdateTime 2018年3月22日
*/
public class ReindexJSONBuild {
private static final ReindexJSONBuild reindexJSONBuild=new ReindexJSONBuild();
private ReindexJSONBuild(){}
public static ReindexJSONBuild getInstance(){
return reindexJSONBuild;
}
/**
*
* @description : 构建reindex的json格式请求
* @param urlRemote 远程服务器地址
* @param sourceIndex 迁移前index
* @param sourceType 迁移前type
* @param destIndex 迁移后index
* @return String json格式的reindex请求
*/
public String reindexJson1(String urlRemote,String sourceIndex,String sourceType,String destIndex) {
// 创建json对象, 其中一个创建json的方式
JSONObject json = new JSONObject();
json.put("host", urlRemote);
JSONObject json2 = new JSONObject();
json2.put("remote", json);
json2.put("index", sourceIndex);
json2.put("type", sourceType);
JSONObject json3 = new JSONObject();
json3.put("index", destIndex);
JSONObject json4 = new JSONObject();
json4.put("source", json2);
json4.put("dest", json3);
// System.out.println("reindexJson1:" + json4.toJSONString());
return json4.toJSONString();
}
/**
*
* @description : 构建reindex的json格式请求
* @param urlRemote 远程服务器地址
* @param sourceIndex 迁移前index
* @param sourceType 迁移前type
* @param destIndex 迁移后index
* @return String json格式的reindex请求
*/
public String reindexJson2(String urlRemote,String sourceIndex,String sourceType,String destIndex) throws Exception {
// 创建json对象, 其中一个创建json的方式
XContentBuilder source = XContentFactory.jsonBuilder()
.startObject()
.startObject("source")
.startObject("remote")
.field("host", urlRemote)
.endObject()
.field("index", sourceIndex)
.field("type",sourceType)
.endObject()
.startObject("dest")
.field("index", destIndex)
.endObject()
.endObject();
//System.out.println("createJson4");
return source.string();
}
}
ElasticSearch集群中的index获取IndexAndTypeBuild.java
package util;
import java.util.ArrayList;
import java.util.List
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.collect.ImmutableOpenMap;
/**
*
* @createDate 2018年3月22日
* @className IndexAndTypeBuild
* @description : 从es服务器上获取所有的索引和类型
* @lastUpdateTime 2018年3月22日
*/
public class IndexAndTypeBuild {
private static final IndexAndTypeBuild indexAndTypeBuild = new IndexAndTypeBuild();
private IndexAndTypeBuild() {
}
public static IndexAndTypeBuild getInstance() {
return indexAndTypeBuild;
}
/**
*
* @description : 建立index-type信息
* @param client 客户端
* @return index-type的所有信息
* @throws Exception
*/
public List getIndexAndType(TransportClient client)
throws Exception {
// 某一个index下的type数
int typeCount;
// 某一个index下的所有type
String[] types;
// 一对index-type,用于生成一条记录
String[] indexType = new String[] {};
// 所有的index-type数据
List indexTypeList = new ArrayList();
// 用户端从服务器上获取所有index
ImmutableOpenMap indexMap = client.admin()
.cluster().prepareState().execute().actionGet().getState()
.getMetaData().getIndices();
// 将获取的index转化成数组
Object[] indexs = indexMap.keys().toArray();
// 对每一个index进行处理
int size = indexMap.size();
for (int i = 0; i < size; i++) {
// 获取当前index下有多少个type
typeCount = indexMap.get(indexs[i].toString()).getMappings().size();
if (typeCount == 1) {
// 获取type,先用split切割掉后面的无用部分,然后去掉最前面的“[”
types = indexMap.get(indexs[i].toString()).getMappings()
.toString().split("=");
types[0] = types[0].substring(1);
// 生成一条index-type记录,添加进去
indexType = new String[] { indexs[i].toString(), types[0] };
indexTypeList.add(indexType);
} else if (typeCount > 1) {
// 获取type,先用split将type分割开,继续用split切割掉每个type后面的无用部分,然后去掉最前面的“[”
types = indexMap.get(indexs[i].toString()).getMappings()
.toString().split(",");
for (String type : types) {
type = type.split("=")[0].substring(1);
// 第三个参数作为判定是否index有多个type,生成一条index-type记录,添加进去
indexType = new String[] { indexs[i].toString(), type,
"multiType" };
indexTypeList.add(indexType);
}
} else {
System.out.println(indexs[i].toString() + "下没有type");
}
}
// for (int i = 0; i < indexTypeList.size(); i++) {
// System.out.print("index:"+indexTypeList.get(i)[0] + ", type:");
// System.out.println(indexTypeList.get(i)[1]);
// }
return indexTypeList;
}
}
运用上面的类迁移数据ReindexTest.java
package instancetest;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import java.util.Properties;
import org.elasticsearch.client.transport.TransportClient;
import util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
/**
*
* @createDate 2018年3月21日
* @className ReindexTest
* @description : reindex测试
* @lastUpdateTime 2018年3月23日
*/
public class ReindexTest {
public static void main(String[] args) throws Exception {
// 建立工具类实例
Mapping mapping = Mapping.getInstance();
HttpRequest httpRequest = HttpRequest.getInstance();
ReindexJSONBuild reindexJSONBuild = ReindexJSONBuild.getInstance();
IndexAndTypeBuild indexAndTypeBuild = IndexAndTypeBuild.getInstance();
TransportClient client = new ClientConnect("elasticsearch","192.168.203.201", 9320).getClient();
// 获取已创建过的index和type
URL in = mapping.getClass().getResource("/indexType.properties");
InputStream inin = in.openStream();
Properties prop = new Properties();
prop.load(inin);
String index;
String destIndex;
String type;
boolean isNotMulit;
String response;
String remoteurl = "http://192.168.203.201:9220";
String buildurl = "http://192.168.203.201:9200";
// 获取服务器上所有的index和type
List indexTypeList = indexAndTypeBuild.getIndexAndType(client);
for (String[] indexType : indexTypeList) {
index = indexType[0];
type = indexType[1];
isNotMulit = indexType.length == 2;
// 获取mapping
JSONObject tempjson = JSON.parseObject(mapping.getMapping(remoteurl, index, type));
// 判断该index是否有多个type
if (isNotMulit) {
// 判断是否创建过该index
if (null == prop.get(index)) {
// 先建立mapping
response = mapping.setMapping(
buildurl,
index,
tempjson
.getJSONObject(index)
.toJSONString());
// 判断是否建立成功
if (response.substring(2, 7).equals("ackno")) {
// 将index和type输入到配置文件中
prop.setProperty(index, type);
FileOutputStream fos = new FileOutputStream(
mapping
.getClass()
.getResource("/indexType.properties")
.getPath());
prop.store(fos, null);
fos.flush();
fos.close();
}
// 构建reindex请求的json格式
String json = reindexJSONBuild.reindexJson1(remoteurl, index, type, index);
// 发送请求,并打印回复
System.out.println(httpRequest.reindex(buildurl, json));
} else {
System.out.println("已创建过" + index);
}
} else {
destIndex = index + "_" + type;
// 判断是否创建过该index
if (null == prop.get(destIndex)) {
// 先建立mapping
response = mapping.setMapping(
buildurl,
destIndex,
tempjson
.getJSONObject(index)
.toJSONString());
// 判断是否建立成功
if (response.substring(2, 7).equals("ackno")) {
// 将index和type输入到配置文件中
prop.setProperty(destIndex, type);
FileOutputStream fos = new FileOutputStream(
mapping
.getClass()
.getResource("/indexType.properties")
.getPath());
prop.store(fos, null);
fos.flush();
fos.close();
}
// 构建reindex请求的json格式
String json = reindexJSONBuild.reindexJson1(remoteurl, index, type, destIndex);
// 发送请求,并打印回复
System.out.println(httpRequest.reindex(buildurl, json));
} else {
System.out.println("已创建过" + destIndex);
}
}
}
}
}
注意:迁移前需在elasticsearch.yaml文件中添加下面配置
reindex.remote.whitelist: host:port
此程序为当初将ElasticSearch版本为5.4.2的集群迁移到ElasticSearch版本为6.0.0的集群上编写的。
因为使用了ambari安装的ElasticSearch,所以ElasticSearch的结构不同,且版本不同,有一些地方出现变化,无法直接用新版本覆盖升级。
故用以上程序保证数据完整地迁移到新集群。