Package com.alimama.mdrill.ui.service

Source Code of com.alimama.mdrill.ui.service.MdrillService

package com.alimama.mdrill.ui.service;


import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.zip.CRC32;

import javax.servlet.jsp.JspWriter;

import org.apache.solr.client.solrj.*;
import org.apache.solr.client.solrj.impl.*;
import org.apache.solr.client.solrj.request.UpdateRequest;
import org.apache.solr.client.solrj.response.*;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.request.compare.GroupbyRow;

import backtype.storm.utils.Utils;

import com.alipay.bluewhale.core.cluster.SolrInfo.ShardCount;
import com.alimama.mdrill.json.JSONArray;
import com.alimama.mdrill.json.JSONException;
import com.alimama.mdrill.json.JSONObject;
import com.alimama.mdrill.partion.GetPartions;
import com.alimama.mdrill.partion.GetShards;
import com.alimama.mdrill.partion.GetShards.ShardsList;
import com.alimama.mdrill.partion.MdrillPartions;
import com.alimama.mdrill.partion.GetPartions.TablePartion;
import com.alimama.mdrill.partion.GetShards.SolrInfoList;
import com.alimama.mdrill.partion.MdrillPartionsInterface;
import com.alimama.mdrill.ui.service.MdrillRequest.StartLimit;
import com.alimama.mdrill.ui.service.utils.WebServiceParams;
import com.alimama.mdrill.ui.service.utils.WebServiceParams.HigoJoinParams;
import com.alimama.mdrill.utils.UniqConfig;
import com.alipay.bluewhale.core.cluster.ShardsState;
import com.alipay.bluewhale.core.cluster.SolrInfo;

import org.apache.log4j.Logger;


public class MdrillService {
  private static Logger LOG = Logger.getLogger(MdrillService.class);

  private static AtomicLong InsertIndex=new AtomicLong(0);
 
 
  public static enum FlushType{
    buffer,sync,syncHdfs
  }
  public synchronized static String insert(String projectName,Collection<SolrInputDocument> docs,FlushType tp)
  throws Exception {
    return insert(projectName, docs,false,null, tp);
  }
 
  public synchronized static String insertLocal(String projectName,Collection<SolrInputDocument> docs,FlushType tp)
  throws Exception {
    return insert(projectName, docs,true,null, tp);
  }
 
  private static String localip=null;
  public synchronized static String insert(String projectName,Collection<SolrInputDocument> docs,boolean islocal,ShardsList[] coresfortest,FlushType tp)
      throws Exception {
    if(localip==null)
    {
      localip = java.net.InetAddress.getLocalHost().getHostAddress();
    }
   
    TablePartion part = GetPartions.partion(projectName);
    MdrillPartionsInterface drillpart=MdrillPartions.INSTANCE(part.parttype);
   
    ShardsList[] cores = coresfortest;

    if (cores == null) {
      cores = GetShards.getCoresNonCheck(part);
    }

    for(SolrInputDocument doc:docs)
    {
     
      doc.setField("mdrill_uuid", MdrillFunction.uuid());
      if(!doc.containsKey("mdrillPartion"))
      {
        String partion=drillpart.InsertPartion(doc);
        doc.setField("mdrillPartion", partion);
      }
       
      if(tp!=null)
      {
        if(tp.equals(FlushType.sync))
        {
          doc.setField("mdrillCmd", "sync");
        }else if(tp.equals(FlushType.syncHdfs))
        {
          doc.setField("mdrillCmd", "syncHdfs");
        }else{
          doc.setField("mdrillCmd", "add");
        }
      }
    }
   
    long index = InsertIndex.getAndIncrement();
    if (index > 100000000) {
      index = 0l;
      InsertIndex.set(index);
    }

    JSONObject rtn = new JSONObject();
 
    if(tp==null||tp.equals(FlushType.buffer))
    {
      ShardsList write =null;
      if(islocal)
      {
        ArrayList<ShardsList> list=new ArrayList<GetShards.ShardsList>(cores.length);
        for(ShardsList shard:cores)
        {
          if(shard.containsIp(localip))
          {
            list.add(shard);
          }
        }
        if(list.size()>0)
        {
          write =list.get((int) (index %list.size()));
        }
      }
      if(write==null)
      {
        write = cores[(int) (index % cores.length)];
      }
 
      for (String s : write.list) {
        String url = "http://" + s + "/solr/" + projectName;
        try{
        CommonsHttpSolrServer server = new CommonsHttpSolrServer(url);
        server.setConnectionManagerTimeout(60000l);
        server.setSoTimeout(60000);
        server.setConnectionTimeout(10000);
        server.setDefaultMaxConnectionsPerHost(100);
        server.setMaxTotalConnections(100);
        server.setFollowRedirects(false);
        server.setAllowCompression(false);
        server.setMaxRetries(4);
        server.setRequestWriter(new BinaryRequestWriter());
        UpdateRequest req = new UpdateRequest();
        req.add(docs);
        UpdateResponse rsp = req.process(server);
        rtn.put(s, rsp.toString());
        }catch(Throwable e)
        {
          LOG.error("insert error "+url,e);
          throw new Exception(e);
        }
      }

    }else if(tp.equals(FlushType.sync)||tp.equals(FlushType.syncHdfs))
    {
      for(ShardsList write:cores)
      {
        for (String s : write.list) {
          String url = "http://" + s + "/solr/" + projectName;
          try{
          CommonsHttpSolrServer server = new CommonsHttpSolrServer(url);
          server.setConnectionManagerTimeout(60000l);
          server.setSoTimeout(60000);
          server.setConnectionTimeout(10000);
          server.setDefaultMaxConnectionsPerHost(100);
          server.setMaxTotalConnections(100);
          server.setFollowRedirects(false);
          server.setAllowCompression(false);
          server.setMaxRetries(4);
          server.setRequestWriter(new BinaryRequestWriter());
          UpdateRequest req = new UpdateRequest();
          req.add(docs);
          UpdateResponse rsp = req.process(server);
          rtn.put(s, rsp.toString());
          }catch(Throwable e)
          {
            LOG.error("insert error "+url,e);
            throw new Exception(e);          }
        }
      }
    }
    rtn.put("code","1");
    rtn.put("message","success");
    return rtn.toString();


  }
  public static String insert(String projectName,String list,ShardsList[] coresfortest)
      throws Exception {
    JSONArray jsonStr=new JSONArray(list.trim());
      Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();

    for(int i=0;i<jsonStr.length();i++)
    {
      SolrInputDocument doc=new SolrInputDocument();
      JSONObject obj=jsonStr.getJSONObject(i);
      Iterator keys = obj.keys();
      while (keys.hasNext()) {
        String key = (String) keys.next();
        doc.addField(key, obj.get(key));
      }
      docs.add(doc);
    }
   
    return insert(projectName, docs,false, coresfortest,FlushType.buffer);

  }
 
  public static String getBasePath()
  {
    Map stormconf = Utils.readStormConfig();
    return MdrillFieldInfo.getBasePath(stormconf);
  }
 
  public static LinkedHashMap<String, String> readFieldsFromSchemaXml(String tablename) throws Exception
  {
    Map stormconf = Utils.readStormConfig();
    return  MdrillFieldInfo.readFieldsFromSchemaXml(stormconf, tablename);

  }

  public static String result(String projectName, String callback,
      String startStr, String rowsStr, String queryStr, String dist,
      String fl, String groupby, String sort, String order,String leftjoin,JspWriter out)
      throws Exception {
    long t1=System.currentTimeMillis();
    String logParams = MdrillRequestLog.logRequest(projectName, callback, startStr, rowsStr,queryStr, dist, fl, groupby, sort, order,leftjoin);
    HeartBeat hb=new HeartBeat(out);
    new Thread(hb).start();
       
    TablePartion part = GetPartions.partion(projectName);

    try {
      Map stormconf = Utils.readStormConfig();
     
      MdrillTableConfig tblconfig=new MdrillTableConfig(part, stormconf);
      MdrillTableCoreInfo coreinfo=new MdrillTableCoreInfo(part, stormconf);
      MdrillRequest req=new MdrillRequest(tblconfig,part, stormconf, projectName, startStr, rowsStr, queryStr, dist, fl, groupby, sort, order, leftjoin);
     
      GetPartions.Shards shard = GetPartions.getshard(part, req.partionsAll,coreinfo.cores, coreinfo.ms);
      HigoJoinParams[] joins=req.parseJoins(coreinfo,shard);
      ArrayList<String> fqList =req.parseFq(tblconfig, shard);
   
     
      JSONObject jsonObj = new JSONObject();

      long t2=System.currentTimeMillis();
     
      String rtn= request(part,tblconfig,coreinfo,req,callback, fqList, shard,joins,jsonObj);
      long t3=System.currentTimeMillis();
      long timetaken=t3-t1;
      jsonObj.put("___timetaken", timetaken+"="+(t2-t1)+"+"+(t3-t2));
      logParams=MdrillRequestLog.logRequest(projectName, callback, startStr, rowsStr,req.queryStr, dist, fl, groupby, sort, order,leftjoin);
      LOG.info("timetaken:"+(timetaken)+",logParams2:"+MdrillRequestLog.cutString(logParams));
      if(timetaken>1000l*100)
      {
        LOG.info("longrequest:"+(timetaken)+",logParams2:"+MdrillRequestLog.cutString(logParams)+"@"+MdrillRequestLog.cutString(rtn));
      }
       hb.setIsstop(true);
          while(!hb.isstop())
          {
            try {
            Thread.sleep(100);
          } catch (InterruptedException e) {
          }
          }
         
          synchronized (hb.lock) {
            if(out!=null)
            {
              out.write(rtn);
            }
        }
         
          return rtn;

    } catch (Throwable e) {
      GetShards.purge(part.name);
      long t2=System.currentTimeMillis();
      LOG.error("timetaken:"+(t2-t1)+",logParams:"+MdrillRequestLog.cutString(logParams));
      LOG.error(MdrillRequestLog.cutString(logParams), e);
      throw new Exception(e);
    }
    finally{
       hb.setIsstop(true);
    }

  }
 
 


  private static String request(TablePartion part,MdrillTableConfig tblconfig,  MdrillTableCoreInfo coreinfo,
  MdrillRequest req,String callback, ArrayList<String> fqList,
      GetPartions.Shards shard,HigoJoinParams[] joins,JSONObject jsonObj) throws Exception {
    CommonsHttpSolrServer server = WebServiceParams.makeServer(shard);
   

    if(req.groupbyFields.size()==0&&joins.length>0)
    {
      if(req.commonStatMap.size() > 0 || req.distStatFieldMap.size() > 0)
      {
        req.groupbyFields.add("higoempty_groupby_forjoin_l");
      }
      req.showFields.add("higoempty_groupby_forjoin_l");
    }
   
    if(req.commonStatMap.size() > || req.distStatFieldMap.size() > 0)
    {
      if(req.groupbyFields.size()==0)
      {
        req.groupbyFields.add("higoempty_groupby_l");
        req.showFields.add("higoempty_groupby_l");
      }
    }
   
   
    try {
      if (req.groupbyFields.size() > 0) {
        resultGroupBy(fqList, shard, req, joins, jsonObj, server);
      else {
        SolrQuery query = WebServiceParams.makeSolrQuery(shard);
        WebServiceParams.setDetailByQuery(query, fqList,req,joins);
        LOG.info("queryinfo:"+shard.urlMain + "/select/?" + MdrillRequestLog.cutString(query.toString()));
        QueryResponse qr = WebServiceParams.fetchDetailCrcQr(query, server,jsonObj,"__timedebug");
        WebServiceParams.setDetailResult(jsonObj, qr, req.showFields,joins);
      }

    } catch (Throwable e) {
      GetShards.purge(part.name);
      LOG.error("higocall,exceptin", e);
      jsonObj.put("code", "0");
      jsonObj.put("message", WebServiceParams.errorToString(e));
    }

    if (callback != null && callback.length() > 0) {
      return callback + "(" + jsonObj.toString() + ")";
    } else {
      return jsonObj.toString();
    }
  }
 

   
  private static void resultGroupBy(ArrayList<String> fqList,
      GetPartions.Shards shard, final MdrillRequest req ,HigoJoinParams[] joins,JSONObject jsonObj,CommonsHttpSolrServer server) throws SolrServerException, JSONException
  {
 
    StartLimit slimit=req.getReqStartEnd();
    SolrQuery query = WebServiceParams.makeSolrQuery(shard);
    WebServiceParams.setGroupByQuery(query, fqList, slimit.start, slimit.rows,req,joins,null);
    query.set("mdrill.isRestat", false);
    LOG.info("queryinfo:"+shard.urlMain + "/select/?" + MdrillRequestLog.cutString(query.toString()));

    QueryResponse qr = WebServiceParams.fetchGroupCrcQr(query, server,jsonObj,"__timedebug");
   
    LinkedHashMap<String,GroupbyRow> groupValueCache=WebServiceParams.setGroupByResult(query,jsonObj, qr, req.groupbyFields, req.showFields,joins,null);
   
    boolean isUseRefetch=jsonObj.getLong("total")>(UniqConfig.defaultCrossMaxLimit()-10)&&groupValueCache.size()<=UniqConfig.defaultCrossMaxLimit()&&jsonObj.getString("code").equals("1");
    if((req.distStatFieldMap.size()>0)||isUseRefetch)
    {
      try{
        query = WebServiceParams.makeSolrQuery(shard);
        int rows= Math.min(groupValueCache.size()*10,UniqConfig.defaultCrossMaxLimit());
        WebServiceParams.setGroupByQuery(query, fqList, 0,rows, req,joins,groupValueCache);
        LOG.info("queryinfo_pre:"+shard.urlMain + "/select/?" + MdrillRequestLog.cutString(query.toString()));
       
        query.set("mdrill.isRestat", true);
        QueryResponse qr2 = server.query(query, SolrRequest.METHOD.POST);
        jsonObj.put("__timedebug_qr2", qr2.getTimetaken(4).toString());
        WebServiceParams.setGroupByResult(query,jsonObj, qr2, req.groupbyFields, req.showFields,joins,groupValueCache);
      }catch(Exception e2)
      {
        LOG.error("queryinfo_pre_exception",e2);
      }
    }
   
   
    if(jsonObj.getString("code").equals("1")&&req.sortType.isStatNum)
    {
      JSONArray jsonArray=jsonObj.getJSONObject("data").getJSONArray("docs");
      ArrayList<JSONObject> results=new ArrayList<JSONObject>();
      boolean iscontains=true;
      for(int i=0;i<jsonArray.length();i++)
      {
        JSONObject obj=jsonArray.getJSONObject(i);
        if(!obj.has(req.sortType.sortRow))
        {
          iscontains=false;
        }
        results.add(obj);
      }
      final boolean isdesc=req.sortType.order.toLowerCase().equals("true");
      boolean needsort=jsonObj.getLong("total")>(UniqConfig.defaultCrossMaxLimit()-10);
      if(iscontains&&needsort)
      {
        Collections.sort(results, new Comparator<JSONObject>() {
          @Override
          public int compare(JSONObject o1, JSONObject o2) {
            int rtn=0;
            try {
              rtn = Double.compare(ParseDouble(o1.get(req.sortType.sortRow)), ParseDouble(o2.get(req.sortType.sortRow)));
            } catch (JSONException e) {
            }
            if(isdesc)
            {
              rtn*=-1;
            }
            return rtn;
          }
        }
        );
      }
     
      JSONArray rtnarr=new JSONArray();
      int actualstart=req.start-slimit.start;
      int actualend=req.rows+actualstart;
      for(int i=actualstart;i<results.size()&&i<actualend;i++)
      {
        rtnarr.put(results.get(i));
      }
     
      jsonObj.getJSONObject("data").put("docs", rtnarr);
    }
  }


 
  public static Double ParseDouble(Object s)
  {
    try{
    return Double.parseDouble(String.valueOf(s));
    }catch(Throwable e)
    {
      return (double) s.hashCode();
    }
  }
  public static String notice(String projectName, String callback,String startStr,String rowsStr) throws JSONException {
 
    try {
        HashMap<String,Long> dayAmt = new HashMap<String, Long>();
      SolrInfoList infolist=GetShards.getSolrInfoList(projectName);
      for (SolrInfo info : infolist.getlist()) {
        if(info!=null)
          {
            if(info.stat==ShardsState.SERVICE&&!info.isMergeServer)
            {
              for(Entry<String, ShardCount> e:info.daycount.entrySet())
              {
                Long amt=dayAmt.get(e.getKey());
                if(amt==null)
                {
                  amt=0l;
                }
                long cnt=e.getValue().cnt;

                if(cnt>0)
                {
                  amt+=1;
                }
                dayAmt.put(e.getKey(), amt);
              }
            }
          }
      }
     
      long maxamt=0;
      for(Entry<String,Long> e:dayAmt.entrySet())
      {
        maxamt=Math.max(e.getValue(),maxamt);
      }
     
      ArrayList<String> matchlist=new ArrayList<String>();
      for(Entry<String,Long> e:dayAmt.entrySet())
      {
        //if(e.getValue()>=maxamt)
        {
          matchlist.add(e.getKey());
        }
      }
     
      int maxValue = 0;
      int minValue = Integer.MAX_VALUE;
      int fcsize = 0;
      for (String s:matchlist) {
        fcsize++;
        int value = Integer.parseInt(String.valueOf(s));
        if (value > maxValue) {
          maxValue = value;
        }
        if (value < minValue) {
          minValue = value;
        }
      }


      JSONArray jsonArray=new JSONArray();

      int total=0;
      if(fcsize>0)
      {
        int start = WebServiceParams.parseStart(startStr);
        int rows = WebServiceParams.parseRows(rowsStr);
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
        Date d1=fmt.parse(String.valueOf(maxValue));
        Date d2=fmt.parse(String.valueOf(minValue));
       
        total = ((int) (d1.getTime() / 1000) - (int) (d2.getTime() / 1000)) / 3600 / 24+1
       
        for(int i=start;i<(start+rows)&&i<total;i++)
        {
          jsonArray.put(fmt.format(new Date(d1.getTime()-i*1000l*3600*24)));
        }
      }
   
     
      JSONObject jsonObj = new JSONObject();
      JSONObject jo = new JSONObject();
      jo.put("min", minValue);
      jo.put("max", maxValue);
      jo.put("total", total);
      jo.put("list", jsonArray);
      jsonObj.put("data", jo);
      jsonObj.put("code", "1");
      jsonObj.put("message", "success");
      jsonObj.put("fcsize", fcsize);
      return callback + "(" + jsonObj.toString() + ")";
    } catch (Exception e) {
      throw new JSONException(e);
    }

  }
 
 
  public static final int daysBetween(Date early, Date late) {
     
        java.util.Calendar calst = java.util.Calendar.getInstance()
        java.util.Calendar caled = java.util.Calendar.getInstance()
        calst.setTime(early)
         caled.setTime(late)
         //设置时间为0时 
         calst.set(java.util.Calendar.HOUR_OF_DAY, 0)
         calst.set(java.util.Calendar.MINUTE, 0)
         calst.set(java.util.Calendar.SECOND, 0)
         caled.set(java.util.Calendar.HOUR_OF_DAY, 0)
         caled.set(java.util.Calendar.MINUTE, 0)
         caled.set(java.util.Calendar.SECOND, 0)
        //得到两个日期相差的天数 
         int days = ((int) (caled.getTime().getTime() / 1000) - (int) (calst 
                .getTime().getTime() / 1000)) / 3600 / 24
       
        return days; 
   }
 
 
  public static String fieldValueList(String projectName, String callback,
      String field, String startStr, String rowsStr, String queryStr)
      throws Throwable {
    return result(projectName, callback, "0", "1000", queryStr, "", null,
        field, null, null,null,null);
  }


}
TOP

Related Classes of com.alimama.mdrill.ui.service.MdrillService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.