根据Elasticsearch中文社区《ES冷热分离(读写分离) hot, stale 场景》一篇整理并测试修改后实现
本项目按照该原理实现读写分离
写的数据如果需要实时被读取,实际上不可能实现完全的读写分离的。
分区读写分离方法:
假设 集群有8个节点,node1,node2,node3,node4 为热区,设置为hot,node5,node6,node7,node8 为冷区,设置为stable.
1. 集群节点分区:
设置elasticsearch每个节点分区,分为hot,stable2个区,设置一下参数:
node.zone: hot
cluster.routing.allocation.awareness.force.zone.values: hot,stable
cluster.routing.allocation.awareness.attributes: zone
index.number_of_shards: 24
index.number_of_replicas: 0
分片分区分布实现方法:
1.1)、启动节点方法:
该设置并不会让hot全部是主primary 分片,stable全部是副本分片,需要先后循序启动节点或者使用设置的方法先后建立索引库来实现,先启动hot节点,后启动stable接点,该方法适合索引库数据量较大时候使用;
1.2)、接口调用实现方法:
一. 0副本方式,建立索引库,仅限于hot热区,将分片全部分布到hot区;
curl -XPUT 'http://localhost:9200/twitter/' -d '{
"settings" : {
"index.routing.allocation.include.zone": "hot",
"number_of_shards" : 12,
"number_of_replicas" : 0
}
}'
二. 修改索引设置,建立1副本,这时因为索引库仅限于热区,副本不能装配,集群黄色;
curl -XPUT 'http://localhost:9200/twitter/_settings' -d '{
"index" : {
"number_of_replicas" : 1
}
}'
三. 修改索引分区设置,包括hot,stable,集群装配分片,冷热分区分片完成:
curl -XPUT 'http://localhost:9200/twitter/_settings' -d '{
"index" : {
"routing.allocation.include.zone": "hot,stable"
}
}'
2. 接口说明:
2.1)、建立分区的读写分离索引:
/es-wrapper/hssplitIndex/create?clusterName=vdata-test&indexName=testsplit2
参数:
clusterName: 集群名,必填
indexName:索引库名,必填
shardNum:分片数,默认12
replicas: 副本数,默认1
delayUnAssign: 索引延时装配时间,默认10 s
hotZoneName: 热区名,默认hot,需要es索引实现配置号冷热分区;
stableZoneName:冷区名,默认stable
2.2)、初始化索引库的建立索引库,无副本,适合全量导入时初始化时调用:
/es-wrapper/hssplitIndex/init?clusterName=vdata-test&indexName=testsplit2
参数:
clusterName: 集群名,必填
indexName:索引库名,必填
shardNum:分片数,默认12
replicas: 副本数,默认1
delayUnAssign: 索引延时装配时间,默认10 s
hotZoneName: 热区名,默认hot,需要es索引实现配置号冷热分区;
2.3)、完成全量导入后建立副本stable区接口,适合全量导入完成后调用:
/es-wrapper/hssplitIndex/finish?clusterName=vdata-test&indexName=testsplit2
clusterName: 集群名,必填
indexName:索引库名,必填
hotZoneName: 热区名,默认hot,需要es索引实现配置号冷热分区;
stableZoneName:冷区名,默认stable
3、读写分离:
3.1)、全量数据写入:
读写分离的操作,全量数据大量高并发写入的时候,可以先建立0副本的热区索引库,2.2步骤,初始化索引库建立,将写操作仅仅限于hot区的接点,并0副本提高写入性能,待数据全部写入完成,设置副本数目为1,2.3 步骤 完成写入。
3.2)、读取search操作,带上参数
preference= _replica_first
java代码:
SearchRequestBuilder sqb = (SearchRequestBuilder) requestBuilder;
sqb.setPreference(Constants.ES_HOTSTABLE_SPLIT_READVALUE);
3.3).写入因为es写入需要副本,主master分片都写入才算,完成,如果不是全量数据写入,依然是全区接点写入。
二、es-wrapper的读写分离:
es-wrapper的读写使用不同的线程池操作,读写和sql查询中分别已经做了以上原理的读写分离参数,直接使用就已经实现读写分离。