最近用到elasticsearch5.1.2,记录下使用方法。
1.elasticsearch.ym关键配置
默认配置:
index.number_of_shards: 5
index.number_of_replicas: 1
index.number_of_shards: 设置索引的主分片数,一旦索引建立,主分片数就确定了,不能再修改。
index.number_of_replicas: 设置分片的副本数,可以随时更改。
重要提示:5x版本后elasticsearch.ym不再提供index级别的修改。若需要修改index级别的配置,需要使用命令:
curl -XPUT http://ip:9200/myindex/_settings -d'{"index.number_of_replicas": 2}'
表示myindex索引的分片备份数改为2。
index.number_of_shards:只能设置一次且只能在建立索引时设置:
curl -XPUT ip:9200/index_name -d '{
"settings":{
"index": {
"number_of_shards": "10",
"number_of_replicas": "1",
"max_result_window": 999999
}
}
}'
表示创建一个名为index_name的索引,设置主分片数为10片,副分片1份,查询最多返回结果999999。
#让ES节点不进行Swapping,可提高性能
#2x版本修改如下
bootstrap.mlockall: true
#5x版本修改如下
bootstrap.memory_lock: true
#关闭master功能,使之仅成为数据节点
node.master: false
node.data: true
#数据节点关闭http功能
http.enabled: false
#为了请求更高效,在数据节点上设置
indices.cluster.send_refresh_mapping: false
#设置所有节点间的传输数据是经过压缩的。默认不压缩。
transport.tcp.compress
#防止自动创建索引
action.auto_create_index: false
#该值默认为2,意思是任何时间点,只能有2个分片被移动。该值设置低一些,能降低分片再平衡,从而避免影响索引。
cluster.routing.allocation.cluster_concurrent_rebalance:2
#给节点分配分片时将考虑磁盘空间
cluster.routing.allocation.disk.threshold_enabled: true
#低位值对应的磁盘使用率, 达到后ES不再分配新分片(97%)
cluster.routing.allocation.disk.watermark.low: .97
#高位值对应的磁盘使用率,达到后分片开始移出节点(下面示例中为99%)
cluster.routing.allocation.disk.watermark.high: .99
#设置各部分所占用的缓存比例,默认是没有限制的,很可能会撑爆 JVM 堆空间(设置 fielddata 会影响搜索性能)
indices.fielddata.cache.size: 40%
indices.cache.filter.size: 30%
indices.cache.filter.terms.size: 1024mb
有时会报最大打开文件数异常(好像是这个名字?记不太清了)
解决办法
vim /etc/security/limits.conf
username soft nofile 65536
username hard nofile 65536
username soft memlock unlimited
username hard memlock unlimited
vim /etc/profile
ulimit -n 65536
source /etc/profile
其他的设置
vim /etc/sysctl.conf
vm.max_map_count=262144
fs.file-max=518144
vm.swappiness=1 # 免费赠送一个关闭 swapping
执行 sysctl -p
2.mapping配置
curl -XPUT ip:9200/my_infex -d '{
"settings":{
"index": {
"refresh_interval" : "-1" //减少shard刷新间隔,用于大规模bulk插入,且对实时查询不要求时使用,完成bulk插入后再修改为1s
"number_of_shards": "20", //初始化20个主分片
"translog.flush_threshold_size": "1024mb" //默认是200mb,增大这个参数可以允许translog在flush前存放更大的段(segment);更大的段的创建会减少flush的频率,并且更大的段合并越少,会减少磁盘IO,索引性能更高。
"number_of_replicas": "1", //设置1个备份,bulk导入大量的数据,可以考虑不要副本,设置为0
"max_result_window": 999999
}
},
"mappings" :{
"my_type" : {
"include_in_all": false, //禁用_all,可以在具体字段打开
"dynamic": "false",
"_source": {
"enabled": "true"
},
"_all": { "analyzer": "ik_max_word" },
"properties": {
"myid" : {
"type": "keyword",//5x后废弃了string,改为keyword和text
"index": "not_analyzed",
"include_in_all": true,
"store": true
}
}
}
}
}'
3.集群设置
如果你只是用bulk导入数据而不关注查询性能,可以关闭合并的阈值
curl -XPUT ip:9200/_cluster/settings -d'
{
"transient" : {
"indices.store.throttle.type" : "none"
}
}'
然后在导入完数据之后恢复成“merge”来恢复这个阈值设置
4.模板设置
curl -XPUT ip:9200/_template/my_template -d'
{
"template": "my_index*", //匹配所有my_index开头的索引
"order":0,
"settings": {...},
"mappings" :{...}
}
更改模板方法,将PUT请求改为POST请求
5.使用BulkRequestBuilder批量写数据java代码:
Settings settings = Settings.builder().put("client.transport.ignore_cluster_name", true).build();
//5x版本的使用的PreBuiltTransport
Client Client client = new PreBuiltTransportClient(settings).addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName("ip", port));
BulkRequestBuilder bulkRequest = client.prepareBulk();
System.out.println("count ="+count);
for(int i=1;i<=count;i++){
bulkRequest.add(client.prepareIndex("my_index", "my_type")
.setSource("json") //json就是你要导入的数据啦,一个json代表一条数据
//bulkRequest.add(client.prepareIndex("my_index", "my_type","指定id").setSource("json")
);}long beginTime = System.currentTimeMillis();BulkResponse bulkResponse = bulkRequest.execute().actionGet();if (bulkResponse.hasFailures()) {System.out.println("erros");}long endTime = System.currentTimeMillis();System.out.println("time = "+(endTime-beginTime));
每个请求大小建议在5-15MB,逐步增大测试,当接收到EsRejectedExecutionException,就说明已经到达节点的瓶颈了,就需要减少并发或者升级硬件增加节点
当写入数据时,确保bulk请求时轮询访问所有节点,不要发送所有请求到一个结点导致这一个节点要在内存存储所有请求的数据去处理
目前我从txt中读取twitter数据,然后导入到es,使用如上设置,java开启10个线程,单个线程每次提交5000条twitter数据。
每秒能提交2万条左右。