sphinx架构设计 -- 高并发rt实时索引

CleverCode最近在研究sphinx使用rt实时索引,总结了一下PHP调用的过程,并且总结了一下rt分布式架构设计。

1 安装Sphinx

   安装详解请查看:http://blog.csdn.NET/clevercode/article/details/52204124。


2 配置rt索引文件

vim /usr/local/sphinx2/etc/realtime.conf

  1. index username  
  2. {  
  3.     # 实时索引类型  
  4.     type = rt  
  5.       
  6.     # 索引保存路径,平时都是保存在内存内,数据量超过内存量的时候会保存在文件内,这里随便存了下没放到data目录下  
  7.     path =/usr/local/sphinx2/var/data/username  
  8.        
  9.     # utf-8' default value is  
  10.     charset_table = 0..9, A..Z->a..z, _, a..z,U+410..U+42F->U+430..U+44F, U+430..U+44F  
  11.       
  12.     #对于非字母型数据的长度切割(默认已字符和数字切割,设置1为按没个字母切割)  
  13.     ngram_len = 1  
  14.     ngram_chars = U+3000..U+2FA1F  
  15.       
  16.     # 全文检索字段声明,这里把实时索引的索引字段都声明出来  
  17.     rt_field = name  
  18.     rt_field = spell  
  19.     rt_field = shortspell  
  20.       
  21.     #他属性字段,可以用来查询  
  22.     rt_attr_uint = isvalid   
  23.     rt_attr_timestamp = ctime  
  24.     rt_attr_timestamp = utime      
  25.       
  26.     # 内存保存大小限制,超过这个就会保存到硬盘中  
  27.     rt_mem_limit = 64M  
  28. }  
  29.   
  30. indexer  
  31. {  
  32.     max_iops= 40  
  33.     max_iosize= 1048576  
  34. }  
  35.   
  36. searchd  
  37. {  
  38.     listen          = 9312  
  39.     listen          = 9306:mysql41  
  40.   
  41.     log         = /usr/local/sphinx2/var/log/searchd.log  
  42.     query_log       = /usr/local/sphinx2/var/log/query.log  
  43.     max_children        = 1024  
  44.     pid_file        = /usr/local/sphinx2/var/log/searchd.pid  
  45.     query_log_format = sphinxql  
  46.     read_timeout = 5  
  47.     rt_flush_period = 172800  
  48.     seamless_rotate     = 1  
  49.     # ondisk_dict_default   = 1  
  50.     workers = threads  
  51.     mva_updates_pool    = 1M  
  52.     max_packet_size     = 64M  
  53.     max_filters     = 256  
  54.     binlog_path        = /tmp  
  55.     binlog_max_log_size = 1024M  
  56.     read_buffer     = 32M  
  57.   # read_unhinted     = 32K  
  58.     max_batch_queries   = 32  
  59.     subtree_docs_cache  = 64M  
  60.     subtree_hits_cache  = 64M  
  61.     dist_threads        = 24  
  62.     thread_stack            = 128K  
  63.     client_timeout        = 300  
  64. }  


3 启动Sphinx(实时索引不需要启动indexer

  1. # pkill searchd    
  2. # /usr/local/sphinx2/bin/searchd --config /usr/local/sphinx2/etc/realtime.conf  

4 查看rt索引结构



5 更新rt数据源

5.1 SphinxRt类的封装。这个类是根据:http://www.sphinxsearch.org/sphinx-realtime-api。提供的简单改版。

  1. <?php  
  2.   
  3. class SphinxRt  
  4. {  
  5.     private $_link//sphinx 连接池  
  6.     protected $_field = array(); //当前索引的字段属性  
  7.     protected $_sql = array(); //sql表达式  
  8.     protected $queryStr = ''//查询的sql  
  9.   
  10.     public $rt = '' ; //當前索引  
  11.     public $error = ''//最后的错误信息  
  12.   
  13.     public $debug = false; //调试状态  
  14.   
  15.     //构造函数  
  16.     public function __construct($rt='',$host='127.0.0.1:9306')  
  17.     {  
  18.         try {  
  19.             $this->_link = mysql_connect($host);  
  20.             if(!$this->_link)  
  21.             {  
  22.                 throw  new Exception('sphinx 实时索引服务器连接失败!');  
  23.             }  
  24.             if($rt !='')  
  25.             {  
  26.                 $this->rt = $this->_sql['rt'] = $rt;  
  27.             }  
  28.         }  
  29.         catch (Exception $e)  
  30.         {  
  31.             $this->error = $e->getMessage();            
  32.         }  
  33.     }  
  34.   
  35.     /** 
  36.       +---------------------------------------------------------- 
  37.       * @todo 设置索引表 
  38.       * @access public  
  39.       * @param param 
  40.       * @return void 
  41.       +---------------------------------------------------------- 
  42.      */       
  43.     public  function rt($rt)  
  44.     {  
  45.         $this->_sql['rt'] = $this->rt = $rt;  
  46.         return $this;  
  47.     }  
  48.   
  49.     /** 
  50.       +---------------------------------------------------------- 
  51.       * @todo where 匹配条件.注意:这里一定要主动加上where 关键词 不能出现这样的情况 where 1 
  52.       * @access public  
  53.       * @param $where 
  54.       * @return void 
  55.       +---------------------------------------------------------- 
  56.      */       
  57.     public  function where($where)  
  58.     {  
  59.         $this->_sql['where'] = $where;  
  60.         return $this;  
  61.     }  
  62.   
  63.     /** 
  64.          +---------------------------------------------------------- 
  65.          * @todo limit 
  66.          * @access public  
  67.          * @param param 
  68.          * @return void 
  69.          +---------------------------------------------------------- 
  70.         */       
  71.     public  function limit($limit)  
  72.     {  
  73.         $this->_sql['limit'] = $limit;  
  74.         return $this;  
  75.     }  
  76.   
  77.     /** 
  78.             +---------------------------------------------------------- 
  79.             * @todo option 评分权值设定等 
  80.             * @access public  
  81.             * @param param 
  82.             * @return void 
  83.             +---------------------------------------------------------- 
  84.            */       
  85.     public  function option($option)  
  86.     {  
  87.         $this->_sql['option'] = $option;  
  88.         return $option;  
  89.     }  
  90.     /** 
  91.             +---------------------------------------------------------- 
  92.             * @todo field 
  93.             * @access public  
  94.             * @param param 
  95.             * @return void 
  96.             +---------------------------------------------------------- 
  97.            */       
  98.     public  function field($field)  
  99.     {  
  100.         $this->_sql['field'] = $field;  
  101.         return $this;  
  102.     }  
  103.   
  104.     /** 
  105.                +---------------------------------------------------------- 
  106.                * @todo order 
  107.                * @access public  
  108.                * @param param 
  109.                * @return void 
  110.                +---------------------------------------------------------- 
  111.               */       
  112.     public  function order($order)  
  113.     {  
  114.         $this->_sql['order'] = $order;  
  115.         return $this;  
  116.     }  
  117.     /** 
  118.   +---------------------------------------------------------- 
  119.   * @todo group 
  120.   * @access public  
  121.   * @param param 
  122.   * @return void 
  123.   +---------------------------------------------------------- 
  124.  */       
  125.     public  function group($group,$withGroup)  
  126.     {  
  127.         $this->_sql['group'] = $group;  
  128.         if($group)  
  129.         {  
  130.             $this->_sql['withGroup'] = $withGroup;  
  131.         }  
  132.         return $this;  
  133.     }  
  134.   
  135.     /** 
  136.       +---------------------------------------------------------- 
  137.       * @todo 检索数据,并对数据进行排序,过滤,评分设定等 
  138.       * @access public  
  139.       * @param param 
  140.       * @example select * from rt where match('keyword') group by gid WITHIN GROUP ORDER BY @weight DESC 
  141.       *          order by gid desc limit 0,1 option ranker=bm25,max_matches=3,field_weights=(title=10,content=3); 
  142.       * @return array 
  143.       +---------------------------------------------------------- 
  144.      */       
  145.     public  function search()  
  146.     {  
  147.         //排序  
  148.         if($this->_sql['order'] != '')  
  149.         {  
  150.             $orderSql = ' ORDER BY '.$this->_sql['order'];  
  151.         }  
  152.         //分组聚合  
  153.         if($this->_sql['group'] !='')  
  154.         {  
  155.             $groupSql = ' GROUP BY '.$this->_sql['group'];  
  156.             //组内排序  
  157.             if ($this->_sql['withGroup']!='') {  
  158.                 $groupSql .= ' WITHIN GROUP ORDER BY '.$this->_sql['withGroup'];  
  159.             }  
  160.         }  
  161.         //附加选项  
  162.         if($this->_sql['option'] !='')  
  163.         {  
  164.             $optionSql = ' OPTION '.$this->_sql['option'];  
  165.         }  
  166.         //数量限制  
  167.         if($this->_sql['limit']!='')  
  168.         {  
  169.             $limitSql = 'limit '.$this->_sql['limit'];  
  170.         }  
  171.         //字段  
  172.         if($this->_sql['field']=='')  
  173.         {  
  174.             $field = '*';  
  175.         }  
  176.         else  
  177.         {  
  178.             $field$this->_sql['field'];  
  179.         }  
  180.   
  181.         if($this->_sql['where']!='')  
  182.         {  
  183.             $where = $this->_sql['where'];  
  184.         }  
  185.         else  
  186.         {  
  187.             $where ='';  
  188.         }  
  189.   
  190.         $this->queryStr = sprintf("SELECT %s FROM %s %s %s %s %s %s",$field,$this->_sql['rt'],$where,$groupSql,$orderSql,$limitSql,$optionSql);  
  191.   
  192.         $rs = $this->query();  
  193.   
  194.         if($rs)  
  195.         {  
  196.             $resArr = array();  
  197.             while ($row = mysql_fetch_assoc($rs)) {  
  198.                 $resArr[] = $row;  
  199.             }  
  200.             $resArr['meta'] = $this->getMeta();  
  201.             return $resArr;  
  202.         }  
  203.         return false;  
  204.     }  
  205.   
  206.   
  207.     /** 
  208.       +---------------------------------------------------------- 
  209.       * @todo 添加索引,注意,这里的添加并未考虑并发操作,可能在sphinx端会出现id冲突 
  210.       * @access public  
  211.       * @param mixed $data  插入的数据 
  212.       * @return bool 
  213.       +---------------------------------------------------------- 
  214.      */       
  215.     public  function insert($data,$lastId=0)  
  216.     {  
  217.         if(!empty($data))  
  218.         {  
  219.             if($lastId===0)  
  220.             {  
  221.                 $lastId = $this->getLastId();  
  222.             }  
  223.         $fields = $values = '';  
  224.             foreach ($data as $k=>$v) {  
  225.                 $fields .= ','.$k;  
  226.                 $values .= ",'".$v."'";  
  227.             }  
  228.             $this->queryStr = "insert into ".$this->_sql['rt']."(id".$fields.") values ($lastId {$values})";  
  229.             return $this->query();  
  230.         }  
  231.         $this->error = '插入数据不能为空';  
  232.         return false;  
  233.     }  
  234.     /** 
  235.       +---------------------------------------------------------- 
  236.       * @todo 批量插入数据 
  237.       * @access public  
  238.       * @param mixed $datas 
  239.       * @param boolean $asStr 是否使用逗号分隔的方式一次性插入 
  240.       * @return void 
  241.       +---------------------------------------------------------- 
  242.      */       
  243.     public  function insertAll($datas,$asStr=true)  
  244.     {  
  245.         if(!empty($datas))  
  246.         {  
  247.             $fields = 'id'//字段  
  248.             $values ='';    //值  
  249.             $lastId = $this->getLastId();  
  250.             $i = 0;  
  251.             foreach ($datas as $k=>$v) {  
  252.                 //一次性插入数据,格式化  
  253.                 if($asStr)  
  254.                 {  
  255.                     $values .=',('.($i+$lastId);  
  256.                     foreach ($v as $kk=>$va) {  
  257.                         //属性字段  
  258.                         if($i==0)  
  259.                         {  
  260.                             $fields .= ','.$kk;  
  261.                         }  
  262.                         $values .= ",'".$va."'";  
  263.                     }  
  264.                     $i++;  
  265.                     $values .= ')';  
  266.                 }  
  267.                 else  
  268.                 {  
  269.                     $this->insert($v,$lastId);  
  270.                 }  
  271.             }  
  272.   
  273.             //批量数据sql格式化  
  274.             if($asStr)  
  275.             {  
  276.                 $values = ltrim($values,',');  
  277.                 $this->queryStr = sprintf("insert into {$this->_sql['rt']}(%s) values %s",$fields,$values);  
  278.                 return $this->query();  
  279.             }  
  280.   
  281.         }  
  282.         else  
  283.         {  
  284.             $this->error = '无效数据!';  
  285.             return false;  
  286.         }  
  287.   
  288.     }  
  289.   
  290.   
  291.     /** 
  292.      +---------------------------------------------------------- 
  293.      * @todo 更新索引数据 
  294.      * @access public  
  295.      * @param mixed $data 要更新的数据 
  296.      * @param int  $id  更新条件id 
  297.      * @return bool 
  298.      +---------------------------------------------------------- 
  299.      */       
  300.     public  function update($data,$id,$insert=true)  
  301.     {  
  302.         if(!empty($data) || $id>0)  
  303.         {  
  304.             //如果未找到记录且不需要不需要插入的话  
  305.             if($insert ===false && $this->getById($id) ===false) return true;  
  306.   
  307.             foreach ($data as $k=>$v) {  
  308.                 $fields .= ','.$k;  
  309.                 $values .= ",'".$v."'";  
  310.             }  
  311.             //若该条数据不存在,直接插入  
  312.             $this->queryStr = "replace into ".$this->_sql['rt']."(id".$fields.") values ($id{$values})";  
  313.             return $this->query();  
  314.         }  
  315.         $this->error = '无效更新数据!';  
  316.         return false;  
  317.   
  318.     }  
  319.   
  320.     /** 
  321.       +---------------------------------------------------------- 
  322.       * @todo 条件删除索引,如,根据外部id删除 
  323.       * @access public  
  324.       * @param $condition 
  325.       * @return void 
  326.       +---------------------------------------------------------- 
  327.      */       
  328.     public  function delBy($condition)  
  329.     {  
  330.         $rs = $this->where($condition)->search();  
  331.   
  332.         if($rs)  
  333.         {  
  334.             foreach ($rs as $v) {  
  335.                 if($v['id']) $idArr[] = $v['id'];  
  336.             }  
  337.             $this->delete($idArr);  
  338.             return true;  
  339.         }  
  340.         return false;  
  341.     }  
  342.   
  343.   
  344.     /** 
  345.     +---------------------------------------------------------- 
  346.     * @todo 删除索引数据,sphinx暂未提供批量删除的功能,如 in (123,34,565); 
  347.     * @access public  
  348.     * @param mixed $id  
  349.     * @return void 
  350.     +---------------------------------------------------------- 
  351.    */       
  352.     public  function delete($id)  
  353.     {  
  354.         if(is_array($id) && count($id)>=1)  
  355.         {  
  356.             $rs = true;  
  357.             foreach ($id as $v) {  
  358.                 $this->queryStr = sprintf("delete from %s where id=%d",$this->_sql['rt'],$v);  
  359.                 $rs &= $this->query();  
  360.             }  
  361.         }  
  362.         else  
  363.         {  
  364.             $this->queryStr = sprintf("delete from %s where id=%d",$this->_sql['rt'],$id);  
  365.             $rs =  $this->query();  
  366.         }  
  367.   
  368.         return $rs;  
  369.     }  
  370.     /** 
  371.       +---------------------------------------------------------- 
  372.       * @todo 清空表 
  373.       * @access public  
  374.       * @return bool 
  375.       +---------------------------------------------------------- 
  376.      */       
  377.     public  function truncate()  
  378.     {  
  379.         $lastId = $this->getLastId();  
  380.         for ($i=1;$i<=$lastId;$i++)  
  381.         {  
  382.             $this->delete($i);  
  383.         }  
  384.         return true;  
  385.     }  
  386.   
  387.   
  388.     /** 
  389.       +---------------------------------------------------------- 
  390.       * @todo 获取总记录 
  391.       * @access public  
  392.       * @param param 
  393.       * @return void 
  394.       +---------------------------------------------------------- 
  395.      */       
  396.     public  function countAll()  
  397.     {  
  398.         $this->queryStr = "SELECT * FROM $this->_sql['rt'] ";  
  399.         $this->query();  
  400.         $meta = $this->getMeta();  
  401.         if($meta)  
  402.         {  
  403.             return  $meta['total_found'];  
  404.         }  
  405.         return false;  
  406.     }  
  407.   
  408.     /** 
  409.       +---------------------------------------------------------- 
  410.       * @todo 获取当前最大值id,实现如mysql的auto_increment功能 
  411.       * @access public  
  412.       * @param param 
  413.       * @return void 
  414.       +---------------------------------------------------------- 
  415.      */       
  416.     public  function getLastId()  
  417.     {  
  418.         $this->queryStr = "select * from {$this->_sql['rt']} order by id desc limit 1";  
  419.         $rs = $this->query();  
  420.   
  421.         //若存在值,则取最大id的值,否则为1  
  422.         $row = mysql_fetch_assoc($rs);  
  423.     $lastId = 1;  
  424.         if($row)  
  425.         {  
  426.             $lastId = $row['id']+1;  
  427.         }  
  428.         return $lastId?$lastId:1;  
  429.   
  430.     }  
  431.   
  432.     /** 
  433.          +---------------------------------------------------------- 
  434.          * @todo 获取查询状态值 
  435.          * @access protected  
  436.          * @param param 
  437.          * @return array(); 
  438.          +---------------------------------------------------------- 
  439.         */       
  440.     protected  function getMeta()  
  441.     {  
  442.         $metaSql = "show meta";  
  443.         $meta = mysql_query($metaSql);  
  444.         while ($row = mysql_fetch_assoc($meta)) {  
  445.             $metaArr[$row['Variable_name']] = $row['Value'];  
  446.         }  
  447.         return $metaArr;  
  448.     }  
  449.   
  450.     /** 
  451.       +---------------------------------------------------------- 
  452.       * @todo 根据id获取记录 
  453.       * @access public  
  454.       * @param int $id 
  455.       * @return array 
  456.       +---------------------------------------------------------- 
  457.      */       
  458.     public  function getById($id)  
  459.     {  
  460.         if($id>0)  
  461.         {  
  462.             $sql = "'select * from $this->rt where id=".$id;  
  463.             $rs = mysql_query($sql);  
  464.             $row = mysql_fetch_assoc($rs);  
  465.             return $row;  
  466.         }  
  467.         return false;  
  468.     }  
  469.   
  470.     /** 
  471.       +---------------------------------------------------------- 
  472.       * @todo 获取索引的字段值,前提条件是索引服务器中必须至少一个值,暂时没有api显示可以直接像mysql 的语句 desc table 来获取索引的字段; 
  473.       * @access public 
  474.       * @param param 
  475.       * @return void 
  476.       +---------------------------------------------------------- 
  477.      */       
  478.     public  function _getField($rt)  
  479.     {  
  480.         $rt = $rt?$rt:$this->rt;  
  481.         $this->queryStr = "select * from {$rt} limit 1";  
  482.         $res = $this->query();  
  483.         if($res)  
  484.         {  
  485.             $row = mysql_fetch_assoc($res);  
  486.             $field = array_keys($row);  
  487.             unset($field[1]); //去掉weight,这个字段是sphinx的权重值  
  488.             return $field;  
  489.         }  
  490.         else  
  491.         {  
  492.             $this->error = '实时索引'.$rt.'没有任何记录,无法获取索引字段';  
  493.             return false;  
  494.         }  
  495.     }  
  496.   
  497.     /** 
  498.       +---------------------------------------------------------- 
  499.       * @todo mysql查询 
  500.       * @access public  
  501.       * @param param 
  502.       * @return void 
  503.       +---------------------------------------------------------- 
  504.      */       
  505.     public  function query($sql = '')  
  506.     {  
  507.         if($sql == '')  
  508.         {  
  509.             $sql = $this->queryStr;  
  510.         }  
  511.         if(!$this->_link) $this->triggerDebug($this->debug);  
  512.           
  513.         $rs = mysql_query($sql,$this->_link);  
  514.         if(!$rs$this->error = mysql_error();  
  515.         $this->triggerDebug($this->debug);  
  516.         return $rs;  
  517.     }  
  518.   
  519.     /** 
  520.       +---------------------------------------------------------- 
  521.       * @todo 获取错误信息 
  522.       * @access public        
  523.       * @return string 
  524.       +---------------------------------------------------------- 
  525.      */       
  526.     public  function getError()  
  527.     {  
  528.         return $this->error;  
  529.     }  
  530.   
  531.     /** 
  532.          +---------------------------------------------------------- 
  533.          * @todo 获取最后的sql语句 
  534.          * @access public  
  535.          * @param param 
  536.          * @return string 
  537.          +---------------------------------------------------------- 
  538.         */       
  539.     public  function getLastSql()  
  540.     {  
  541.         return $this->queryStr;  
  542.     }  
  543.   
  544.     /** 
  545.       +---------------------------------------------------------- 
  546.       * @todo 触发错误信息 
  547.       * @access public  
  548.       * @param param 
  549.       * @return void 
  550.       +---------------------------------------------------------- 
  551.      */       
  552.     public  function triggerDebug($debugMode=false)  
  553.     {  
  554.         if($debugMode)  
  555.         {  
  556.             $debugInfo = debug_backtrace();  
  557.   
  558.             $errorStr = 'file:'.$debugInfo[0]['file'];  
  559.             $errorStr .= '<br />line:'.$debugInfo[0]['line'];  
  560.             $errorStr .= '<br />sql:'.$debugInfo[0]['object']->queryStr;  
  561.             $errorStr .= '<br />error:<font color="red">'.$debugInfo[0]['object']->error.'</font>';  
  562.   
  563.             if($debugInfo[0]['object']->error!='')die($errorStr);  
  564.             echo ($errorStr);  
  565.         }  
  566.         return ;  
  567.     }  
  568.   
  569. }  

5.2 更新数据源

vim modifySource.php

  1. <?php  
  2. require_once "SphinxRt.php";  
  3.   
  4. function insert($data)  
  5. {  
  6.     $sphinx = new SphinxRt('username','127.0.0.1:9306');  
  7.     $sphinx->insert($data);  
  8. }  
  9.   
  10. function start()  
  11. {  
  12.     $data = array();  
  13.     $name = '张三';  
  14.     $utf8Name = iconv("GBK","UTF-8//IGNORE",$name);  
  15.     $data['name'] = $utf8Name;   
  16.     $data['spell'] = 'zhangsan';   
  17.     $data['shortspell'] = 'zs';   
  18.     $data['isvalid'] = 1;   
  19.     $data['ctime'] = '2016-08-17 12:00:00';   
  20.     $data['utime'] = '2016-08-17 12:00:00';   
  21.     $ret = insert($data);  
  22.     print_r($ret);  
  23. }  
  24.   
  25. start();  
  26.   
  27. ?>  


查看数据



5.2 查询数据

vim search.php

  1. <?php  
  2.   
  3. //分词  
  4. function parseWord($word)  
  5. {  
  6.     $so = scws_new();  
  7.     $so->set_charset('utf-8');  
  8.     //默认词库  
  9.     $so->add_dict(ini_get('scws.default.fpath') . '/dict.utf8.xdb');  
  10.     //自定义词库  
  11.     // $so->add_dict('./dd.txt',SCWS_XDICT_TXT);  
  12.     //默认规则  
  13.     $so->set_rule(ini_get('scws.default.fpath') . '/rules.utf8.ini');  
  14.   
  15.     //设定分词返回结果时是否去除一些特殊的标点符号  
  16.     $so->set_ignore(true);  
  17.   
  18.     //设定分词返回结果时是否复式分割,如“中国人”返回“中国+人+中国人”三个词。  
  19.     // 按位异或的 1 | 2 | 4 | 8 分别表示: 短词 | 二元 | 主要单字 | 所有单字  
  20.     //1,2,4,8 分别对应常量 SCWS_MULTI_SHORT SCWS_MULTI_DUALITY SCWS_MULTI_ZMAIN SCWS_MULTI_ZALL  
  21.     $so->set_multi(false);  
  22.   
  23.     //设定是否将闲散文字自动以二字分词法聚合  
  24.     $so->set_duality(false);  
  25.   
  26.     //设定搜索词  
  27.     $utf8Key = iconv("GBK","UTF-8//IGNORE",$word);  
  28.     $so->send_text($utf8Key);  
  29.     $words_array = $so->get_result();  
  30.     $so->close();  
  31.   
  32.     return $words_array;  
  33. }  
  34.   
  35. //查询结果  
  36. function search($words)  
  37. {  
  38.     $sc = new SphinxClient();  
  39.     $sc->SetServer('127.0.0.1',9312);  
  40.     $sc->SetMatchMode(SPH_MATCH_ALL);  
  41.     //$sc->SetMatchMode(SPH_MATCH_EXTENDED);  
  42.     $sc->SetArrayResult(TRUE);  
  43.     $res = $sc->Query($words);  
  44.     return $res;  
  45. }  
  46.   
  47. function start()  
  48. {  
  49.     $key = '张三';  
  50.       
  51.     //分词  
  52.     $words_array =  parseWord($key);   
  53.     if(false == is_array($words_array) || count($words_array) < 1)  
  54.     {  
  55.         echo "words_array is empty!";  
  56.         return;  
  57.     }  
  58.       
  59.         $words = '';  
  60.     foreach($words_array as $v)  
  61.     {  
  62.         $words = $words.'|('.$v['word'].')';  
  63.     }  
  64.   
  65.        $words = trim($words,'|');     
  66.   
  67.         //搜索      
  68.     $res = search($words);  
  69.     $str = print_r($res,true);  
  70.     //打印  
  71.    
  72.     echo '<p>输入:'.$key.'</p>'."\r\n";  
  73.     echo '<p>分词:'.iconv("UTF-8","GBK//IGNORE",$words).'</p>'."\r\n";  
  74.     echo iconv("UTF-8","GBK//IGNORE",$str);  
  75.       
  76. }  
  77.   
  78. start();  
  79.   
  80. ?>  

打印结果
  1. <p>输入:张三</p>  
  2. <p>分词:(张三)</p>  
  3. Array  
  4. (  
  5.     [error] =>   
  6.     [warning] =>   
  7.     [status] => 0  
  8.     [fields] => Array  
  9.         (  
  10.             [0] => name  
  11.             [1] => spell  
  12.             [2] => shortspell  
  13.         )  
  14.   
  15.     [attrs] => Array  
  16.         (  
  17.             [isvalid] => 1  
  18.             [ctime] => 2  
  19.             [utime] => 2  
  20.         )  
  21.   
  22.     [matches] => Array  
  23.         (  
  24.             [0] => Array  
  25.                 (  
  26.                     [id] => 1  
  27.                     [weight] => 2  
  28.                     [attrs] => Array  
  29.                         (  
  30.                             [isvalid] => 1  
  31.                             [ctime] => 2016  
  32.                             [utime] => 2016  
  33.                         )  
  34.   
  35.                 )  
  36.   
  37.         )  
  38.   
  39.     [total] => 1  
  40.     [total_found] => 1  
  41.     [time] => 0.001  
  42.     [words] => Array  
  43.         (  
  44.             [张] => Array  
  45.                 (  
  46.                     [docs] => 1  
  47.                     [hits] => 1  
  48.                 )  
  49.   
  50.             [三] => Array  
  51.                 (  
  52.                     [docs] => 1  
  53.                     [hits] => 1  
  54.                 )  
  55.   
  56.         )  
  57.   
  58. )  


6 rt分布式架构与负载均衡设计

当username的索引足够大的时候,以及并发量特别高的时候,可以考虑以下架构设计。

6.1 更新数据源

     当需要更新数据源的时候(modifySource)的时候,把需要更新的机器都更新一遍。即192.168.100,92.168.101,92.168.102。


6.2 查询

     当需要查询的时候(search),可以根据192.168.100,92.168.101,92.168.102处理能力的权重选择一台机器进行检索。


8 源码下载

http://download.csdn .Net/download/clevercode/9605832。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值