package com.alimama.mdrill.partion; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; import org.apache.log4j.Logger; import backtype.storm.utils.Utils; import com.alimama.mdrill.partion.GetPartions.TablePartion; import com.alipay.bluewhale.core.callback.RunnableCallback; import com.alipay.bluewhale.core.cluster.Cluster; import com.alipay.bluewhale.core.cluster.ClusterState; import com.alipay.bluewhale.core.cluster.ShardsState; import com.alipay.bluewhale.core.cluster.SolrInfo; import com.alipay.bluewhale.core.cluster.StormClusterState; import com.alipay.bluewhale.core.utils.StormUtils; /** * 用户获取某个表的所有shards以及mergers * @author yannian.mu * */ public class GetShards { private static Timer EXECUTE =new Timer(); private static Logger LOG = Logger.getLogger(GetShards.class); public static class SolrInfoList extends RunnableCallback{ private String tableName; TimerTask task=null; List<SolrInfo> infolist=new ArrayList<SolrInfo>(); public SolrInfoList(String tableName) { this.tableName = tableName; } Object lock=new Object(); @Override public <T> Object execute(T... args) { this.run(); return null; } public List<SolrInfo> getlist() { synchronized (lock) { List<SolrInfo> rtn=new ArrayList<SolrInfo>(); rtn.addAll(this.infolist); return rtn; } } public void run() { ArrayList<SolrInfo> newlist=new ArrayList<SolrInfo>(); try { long t1=System.currentTimeMillis(); LOG.info("sync from zookeeper "+tableName); StormClusterState zkCluster = getCluster(); List<Integer> list = zkCluster.higo_base(tableName,this); for (Integer id : list) { SolrInfo info = zkCluster.higo_info(tableName, id); if (info != null ) { newlist.add(info); } } long tl=System.currentTimeMillis()-t1; LOG.info("getShards timetaken:"+tl); } catch (Throwable e) { synchronized (lock) { if(this.task!=null) { this.task.cancel(); this.task=null; } } return ; } synchronized (lock) { infolist.clear(); infolist.addAll(newlist); if(this.task==null) { this.task=new TimerTask() { @Override public void run() { SolrInfoList.this.run(); } }; EXECUTE.schedule(task, 300000l, 300000l); } } } }; private static ConcurrentHashMap<String, SolrInfoList> infolistmap=new ConcurrentHashMap<String, GetShards.SolrInfoList>(); public static SolrInfoList getSolrInfoList(String tableName) { SolrInfoList infolist=infolistmap.get(tableName); if(infolist==null) { infolist=new SolrInfoList(tableName); infolist.run(); infolistmap.putIfAbsent(tableName, infolist); LOG.info("SolrInfoList init:"+tableName); } return infolist; } public static class ShardsList{ public ArrayList<String> list=new ArrayList<String>(); public int random=(int) (Math.random()*1000); public String randomGet() { int index=random%list.size(); random++; return list.get(index); } public boolean containsIp(String ip) { for(String s:list) { if(s.indexOf(ip)>=0) { return true; } } return false; } } public static void purge(String tableName) { SolrInfoList infolist=getSolrInfoList(tableName); infolist.run(); } public static ShardsList[] getCores(Map stormconf,TablePartion part) throws Exception { ShardsList[] cores = GetShards.get(part.name, false); for(int i=0;i<10;i++) { if(cores.length!=StormUtils.parseInt(stormconf.get("higo.shards.count"))) { if(i>5) { throw new Exception("core.size="+cores.length); } GetShards.purge(part.name); cores = GetShards.get(part.name, false); LOG.info("core.size="+cores.length); Thread.sleep(1000); }else{ break; } } LOG.info("request core.size="+cores.length); return cores; } public static ShardsList[] getCoresNonCheck(TablePartion part) throws Exception { ShardsList[] cores = GetShards.get(part.name, false); for(int i=0;i<10;i++) { if(cores==null||cores.length<=0) { if(i>5) { throw new Exception("core.size<=0"); } GetShards.purge(part.name); cores = GetShards.get(part.name, false); LOG.info("core.size="+cores.length); Thread.sleep(1000); }else{ break; } } return cores; } public static ShardsList[] getMergers(String tableName) throws Exception { return GetShards.get(tableName, true); } private static ShardsList[] get(String tableName,boolean isMs) throws Exception { SolrInfoList infolist=getSolrInfoList(tableName); long nowtime=System.currentTimeMillis(); HashMap<Integer,ShardsList> replication=new HashMap<Integer, ShardsList>(); for (SolrInfo info : infolist.getlist()) { if (info != null && info.isMergeServer == isMs)// &&info.stat==ShardsState.SERVICE { if (isMs && !info.stat.equals(ShardsState.SERVICE)) { continue; } if((info.times+1000l*3600)<nowtime) { continue; } ShardsList solrlist=replication.get(info.taskIndex); if(solrlist==null) { solrlist=new ShardsList(); replication.put(info.taskIndex, solrlist); } solrlist.list.add(new String(info.localip + ":" + info.port)); } } ShardsList[] rtn=new ShardsList[replication.size()]; int index=0; for(ShardsList s:replication.values()) { rtn[index++]=s; } return rtn; } private static StormClusterState higozkCluster; public static StormClusterState getCluster() throws Exception { if(higozkCluster==null) { Map stormconf = Utils.readStormConfig(); ClusterState zkClusterstate =Cluster.mk_distributed_cluster_state(stormconf); higozkCluster = Cluster.mk_storm_cluster_state(zkClusterstate); } return higozkCluster; } }