出家如初,成佛有余

服务器部署Session Draining支持方案

Posted in 技术相关 by chuanliang on 2016/02/24

 

支付系统对账算法优化方案

Posted in 电子商务, 技术相关 by chuanliang on 2015/06/09

一、目前对账的算法:

1、从上游渠道(银行、银联等金融机构)获取对账文件,程序逐行解析入库

2、在存储过程中,以上游对账文件的表为基准,程序逐行读取并与我们系统的交易记录/账务记录(有账务系统情况下,合理方案应该是于账务记录)对比,查找出差异记录。

3、以我们系统的交易记录/账务记录为基准,程序逐行读取与上游对账文件对比,查找出差异记录

 

二、目前对账算法问题:

1、使用存储过程,对账过程都在数据库端完成,对数据库性能影响较大,而且对账逻辑扩展极为麻烦

2、逐行比对算法效率较低,但算法上并无好的优化余地。如果采用数据库INTERSECT、MINUS对数据库压力也高。

3、在业务量大的情况下(例如有上百家上游渠道需要对,每一家都有几十万条交易记录),对账服务器及数据库服务器负荷较高。即便采用读写分离,对账时候使用读库,压力一样很大。

4、导入批量文件,逐行入库效率较为低下(每一次都需要建立网络连接、关闭连接)

 

三、对账算法优化思路:

1、涉及网络传输的,尽量采用批量方式操作,减少网络消耗及时间消耗

2、使用Redis等NOSQL数据库,降低数据库服务器的压力。同时在扩展上也容易,一台Redis服务器不够,可以无限制增加用于对账用的服务器。

3、使用Redis的set集合的sdiff功能,利用Redis sdiff算法的高性能,比对上游记录和我方记录的差异

 

四、对账算法说明:

1、利用Oracle/Mysql的load data infile将对账文件批量导入到数据库

2、程序读取上游账务记录表,对上游账户记录执行select  concat(channel_id, “:” , order_id , “:” , HASH_MD5(channel_id , order_id , amount , status , timestamp1 , timestamp2 ,…) )  as hashid from table ,得到对应的SET集合。

这里思路是将需要对账的记录拼成格式为:channel_id:order_id:hashid形式的串,以便作为Redis SET集合的item。

其中channel_id和order_id用于标识对应的渠道及订单,只是例子,根据实际需要补充。之所以要在hashid前面带上channel_id和order_id,主要目的是在sdiff后,能够作为主键,根据set结合的item查找出对应的数据库记录。

3、对我方的交易记录表/账户历史表采用上一步的类似算法,得到对应的SET结合

4、采用Redis的pipeline功能(Redis的各种客户端,包括java客户端jedis 都提供此功能),将上游账务记录SET集合和我方的交易记录/账务历史记录SET集分别批量执行sadd插入Redis,得到两个SET集合。

由于单条记录sadd 插入Redis效率较差(每一次都涉及网络open、close、传输消耗),因此使用Redis的pipeline功能,已实现批量入库功能。

可以参考:http://redis.io/topics/mass-insert

5、利用redis的sdiff功能查找出上游账务集合与我方记录集合的差值

6、从sdiff 集合中channel_id:order_id:hash,定位对应的数据库记录,更新对账状态。

具体性能及实现可以在实现后测试对比一下,应该会有大幅的性能提升。

高并发交易驱动系统方案

Posted in 电子商务, 技术相关 by chuanliang on 2015/01/25

我在知乎就《现在有这样一个需求,在一秒中有3万的支付订单请求,有什么比较好的解决方案吗?》做的回答。

从交易角度来看,各种高并发系统可以粗略分为两大类:交易驱动的系统,内容驱动的系统。其中:
交易驱动的系统:包括支付系统、电信计费系统、银行核心交易系统等,此类系统强调数据库事务的ACID原则。
内容驱动的系统:包括SNS、微博、门户、视频、搜索引擎等系统,此类系统对数据库事务ACID的关注不是第一位的,更强调CAP原则:Consistency(一致性), Availability(可用性),Partition tolerance(分区容错性)。
与此对应,交易驱动的系统与内容驱动的系统在系统优化方法最大的差异在于:
交易驱动的系统:强 调事务的ACID,按照CAP原则做选择,更强调CA(Consistency(一致性)和Availability(可用性);因此交易驱动的系统一般 在核心交易上选择关系型数据库(包括采用内存数据库、缓存等涉及事务问题),当然这就导致交易系统最大的瓶颈一般都在关系数据库上。
内容驱动的系统:可以在CAP之间根据业务需要做选择三选二,因此一般选择NOSQL为主、RDBMS为辅的方案。
在优化策略上,内容驱动的系统采用的诸多优化手段交易驱动的系统也可以采用,上面各位回答都有所提及,这里重点说一下因事务导致的业务复杂性的处理。
3万笔/每秒这个级别的交易订单这个量级说实话挺大,但即便如此,也有诸多可优化的空间。由于题主未对具体场景说明,只能假定是典型的交易驱动系统,一些思考点:
1、3万笔/每秒是峰值最大交易量还是持续交易量?
2、3万笔/每秒是同一类型的订单还是诸多种类型的订单?
3、业务能否做拆分,例如从功能、从区域、从优先级等角度?
4、支付订单是实时交易还是非实时交易,能否延时入库?
5、支付订单能否延时批量处理?
6、支付订单是否涉及热点账户问题,也即对同一账户会有多个并发请求对其属性(例如账户余额)进行操作?
由此可以展开诸多优化策略,不在此处细述。
以前写过一篇 交易系统“热点账户”处理 ,供参考

知乎回答原文链接:http://www.zhihu.com/question/27590048/answer/38025567

交易系统和风控系统的架构怎么设计?

Posted in 电子商务, 技术相关, 产品管理 by chuanliang on 2015/01/19

我在知乎就《交易系统和风控系统的架构怎么设计?》做的回答。

交易系统和风控系统从架构角度设计,是应该设计成两个单独的系统,题主提到的问题,本质在于交易系统和风控系统之间数据共享及服务调用的问题。
一般通过如下几个层面来降低交易系统、风控系统的耦合度,提升系统性能和扩展性:读写分离、缓存/内存数据库、SOA架构、复合事件处理
数据库读写分离机制:在初期,风控系统一般都极为简单,此时侯一般通过数据库主从复制/读写分离/Sharding等机制来保证交易系统的数据库和风控系统数据的同步及读写分离。风控系统对所需要的客户/账户数据、交易数据一般都只进行读操作。
缓存/内存数据库机制:不 管是交易系统还是风控系统,高效的缓存系统是提升性能的大杀器,一般会把频繁使用的数据存放到Redis等缓存系统中。例如对风控系统,包括诸如风控规 则、风控案例库、中间结果集、黑白名单、预处理结果等数据;对交易系统而言,包括诸如交易参数、计费模板、清结算规则、分润规则、银行路由策略等。对一些 高频交易中,基于性能考虑,会采用内存数据库(一般会结合SSD硬盘)。
RPC/SOA架构:要降低交易系统和风控系统的 耦合度,在初期系统服务较少的情况下,一般直接采用RabbitMQ/ActiveMQ之类的消息中间件或RPC方式来实现系统间服务的调用。如果系统服 务较多,存在服务治理问题,会采用Dubbo之类的SOA中间件来实现系统服务调用。
复合事件处理(CEP):对实时/准实时交易风险控制,相对于纯基于规则的处理模式,采用复合事件处理(CEP)模式,性能及扩展性更好,开源的方案包括Esper、Storm、Spark等。
从风控系统构建角度,对应所谓的事前、事中、事后风险控制,作为风控系统最核心的风控引擎分为实时风控引擎、准实时风控引擎、定时风控引擎三种:
1、实时风控引擎&准实时风控引擎
实时风控主要在交易过程对交易过程进行实时监控,一个典型应用场景是甄别钓鱼、盗卡风险。
准实时风控典型应用场景是在T+1结算时候,对商户洗钱、跑路进行甄别。
实时/准实时风控引擎一般采用规则引擎+复杂事件处理(CEP)。
2、定时风控引擎
主要定时对支付/交易/账务等数据进行定时ETL、深度挖掘等处理,建立对应的风控模型,一个典型应用场景是商户的信用等级模型。此时侯一般采用Hadoop、ML等技术进行大数据建模
以前写过两篇关于第三方支付风控系统建设的文章,供参考
支付系统风控系统建设思考
复杂事件处理(Complex Event Processing)入门1

 

知乎回答原文链接:http://www.zhihu.com/question/20860347/answer/36328342

开发一个业务逻辑复杂的系统,应该怎么样设计才能使项目的扩展性更好?

Posted in 技术相关, 产品管理 by chuanliang on 2014/11/24

我在知乎关于《开发一个业务逻辑复杂的系统,应该怎么样设计才能使项目的扩展性更好?》做的回答。

既然业务逻辑复杂,那意味着项目前期的业务建模、需求分析、分析设计极为重要,直接抛开这几个阶段进入技术实施开发阶段,不管套用什么设计模式、架构模式,系统的扩展性肯定难以保证。
项目的扩展性虽然最终体现为系统架构、技术实现的扩展性,但系统扩展性的根源在于系统业务架构及业务模型的扩展性。大家经常骂xx系统烂、扩展性差,大都将原因归结为技术实现烂,但总结那些成功的大型项目或产品的最佳实践,原因都会有:某某是业务专家,对xx业务很熟悉,能够衔接业务与技术。因此一个好的项目角色中,应该有行业专家/领域专家、业务过程分析师、系统分析师、软件架构师等角色,从业务架构、信息架构、技术架构保证系统的扩展性。

具体怎样进行业务建模,搭建良好的业务架构和业务模型,从而为技术架构、信息架构、技术实现奠定良好基础,有一些较为成熟的软件开发过程可供参考。例如 RUP(Rational Unified Process,统一软件开发过程)。一个标准的RUP工作流程包括:业务建模,需求分析,分析设计,实施开发,测试,部署,配置和变更管理,项目管理,环境。当然RUP只是一个方法论,且过于庞大,大部分项目很难完整执行其过程,需要根据实际情况进行裁剪,但其方法论对于复杂业务逻辑系统的建设具有指导意义。像互联网产品设计中常用的用例分析技术就源于RUP。

因此对于题主描述的一个复杂系统,标准的过程应当在业务建模,需求分析,分析设计,实施开发,测试,部署完整过程的分析设计(与开发语言无关)或实施开发(分析设计的成果映射为具体语言,例如Java、.NET等)阶段才考虑设计模式、架构模式的引入。设计模式的使用会经历僵化->固化->优化的阶段,类似禅修中“看山是山、看水是水”的三个阶段,才能体会模式的运用之妙。

值得强调的是:如果是偏交易(例如支付、金融)的系统,在考虑扩展性时候,一定要将信息架构、信息模型的扩展性纳入到考虑范围,此类系统数据模型至关重要,也不可能频繁变动。

上面描述方法的特别适用与传统软件、系统集成等需求偏稳定的项目,对于互联网偏创新性的项目就不一定完全适用了,此类项目的现实情况如下:业务模式不确定,会不停试错,验证模式;需求不停变化,要求能够快速响应;全新的行业,没有行业专家,没有行业标杆可借鉴(至多有跨界标杆可参考);此时候,类似精益创业、Scrum之类的敏捷开发模式更适合,但对于复杂的业务而言,业务建模->需求分析->分析设计的理念仍然值得参考借鉴。

最后,最最重要的是:完美系统的架构和扩展性是管理出来的、持续重构出来的。正如各大城市马路不停翻了再修、修了再翻的命运一样,中国大部分公司后任会不停否定掉前任的架构、系统,推倒再来一遍,然后等新系统刚开发出来不久,尚未上线或上线运营一段时间后,再换一帮人继续折腾,然后。。。

总结这么多年的经历,深刻体会到:再烂的系统和架构,如果能够强化管理、持续积累、持续重构、持续完善,都能够有机会成为完美的系统,完美的系统不在于其架构的牛逼和完美,而在于:符合公司的业务模式,能够完美支撑公司业务的高速发展和市场需求的快速响应。

 

http://www.zhihu.com/question/26731781/answer/33906943

手机密号的原理是什么?

Posted in 移动互联网, 技术相关 by chuanliang on 2014/11/24

在知乎就《手机密号的原理是什么? 之前有安卓和微信版本,现在又有苹果版本了,它的实现原理是什么呢?》做的回答。

手机密号的功能并无太多新颖的东西,像58同城、赶集等也推过类似服务。这里大致说一下自己理解的主要技术,做过呼叫中心、VOIP的比较擅长。
类似服务一般涉及用户、互联网服务提供商、云呼叫中心服务提供商、电信运营商几个角色。
1、 互联网服务提供商:例如58同城之类,由于专业分工原因,互联网服务提供商一般是采用第三方云呼叫中心服务提供商提供的VOIP服务。像手机密号的功能, 诸如注册、微信绑定等功能属于互联网服务提供商的业务功能,而临时性虚拟号码的分配、外呼是由云呼叫中心服务提供商提供的,当然。
2、 云呼叫中心服务提供商:一般采用类似asterisk之类的VOIP及软交换开源项目进行改造,对外提供云呼叫中心服务。与传统呼叫中心基于语音+PBX 不同,一般采用IP+软交换方案。可以参考一下合力金桥、讯鸟的方案。当然云呼叫中心服务提供商也可以扮演互联网服务提供商角色。
3、运营商:为云呼叫中心提供号码池、外呼中继等相关服务。在运营商那端有一堆主叫号码池和外呼中继,这样使用手机密号用户注册绑定后会从不同的主叫池中选择分配(或者动态分配)一个不同的主叫号码并外呼出去。没错,与VOIP透传之类的套路一样。

 

http://www.zhihu.com/question/24816198/answer/29088983

PHP, Python, Node.js 哪个比较适合写爬虫?

Posted in 技术相关 by chuanliang on 2014/06/03

我在知乎关于《PHP, Python, Node.js 哪个比较适合写爬虫? 》做的回答

主要看你定义的“爬虫”干什么用。
1、如果是定向爬取几个页面,做一些简单的页面解析,爬取效率不是核心要求,那么用什么语言差异不大。
当然要是页面结构复杂,正则表达式写得巨复杂,尤其是用过那些支持xpath的类库/爬虫库后,就会发现此种方式虽然入门门槛低,但扩展性、可维护性等都奇差。因此此种情况下还是推荐采用一些现成的爬虫库,诸如xpath、多线程支持还是必须考虑的因素。
2、如果是定向爬取,且主要目标是解析js动态生成的内容
此时候,页面内容是有js/ajax动态生成的,用普通的请求页面->解析的方法就不管用了,需要借助一个类似firefox、chrome浏览器的js引擎来对页面的js代码做动态解析。
此种情况下,推荐考虑casperJS+phantomjs或slimerJS+phantomjs ,当然诸如selenium之类的也可以考虑。
3、如果爬虫是涉及大规模网站爬取,效率、扩展性、可维护性等是必须考虑的因素时候
大规模爬虫爬取涉及诸多问题:多线程并发、I/O机制、分布式爬取、消息通讯、判重机制、任务调度等等,此时候语言和所用框架的选取就具有极大意义了。
PHP对多线程、异步支持较差,不建议采用。
NodeJS:对一些垂直网站爬取倒可以,但由于分布式爬取、消息通讯等支持较弱,根据自己情况判断。
Python:强烈建议,对以上问题都有较好支持。尤其是Scrapy框架值得作为第一选择。优点诸多:支持xpath;基于twisted,性能不错;有较好的调试工具;
此种情况下,如果还需要做js动态内容的解析,casperjs就不适合了,只有基于诸如chrome V8引擎之类自己做js引擎。
至于C、C++虽然性能不错,但不推荐,尤其是考虑到成本等诸多因素;对于大部分公司还是建议基于一些开源的框架来做,不要自己发明轮子,做一个简单的爬虫容易,但要做一个完备的爬虫挺难的。
像我搭建的微信公众号内容聚合的网站
http://lewuxian.com就是基于Scrapy做的,当然还涉及消息队列等。可以参考下图:


23b58ecfcd42d2f0b26931b660ede44f_m


具体内容可以参考
一个任务调度分发服务的架构

 

地址:http://www.zhihu.com/question/23643061/answer/26322652

Tagged with: , , ,

微软小冰智能聊天是如何实现的?

Posted in 技术相关 by chuanliang on 2014/06/03

我在知乎关于《微软小冰智能聊天是如何实现的?》做的回答

 

刚好做过一个类似的产品,虽然没有那么高大上,但一些核心技术原理应该也参考意义,说一下做的思路。
类似小冰这样的产品说简单也简单,说复杂也复杂。单纯从外面看你会觉得小冰与去年人人网上流行的小黄鸡类似,但在技术实现上有本质的差异。
此类应用的大致流程都是:用户输入一段话(不一定只是单词)->后端语义引擎对用户输入的语句进行语义解析->推断用户最可能的意图->调用对应的知识库、应用、计算引擎->返回结果给用户。
1、最初级的实现方法:关键词匹配
建一个关键词词库,对用户输入的语句进行关键词匹配,然后调用对应的知识库。
此种方式入门门槛很低,基本上是个程序员都能实现,例如现在微信公众平台的智能回复、诸多网站的敏感词过滤就是此类。
但此种方式存在诸多问题,例如:
a、由于是关键词匹配,如果用户输入的语句中出现多个关键词,此时由于涉及关键词权重(与知识库的关键词对比)等等问题,此时关键词匹配的方法就不擅长了
b、不存在对用户输入语句语义的理解,导致会出现答非所问的现象。当然在产品上对回答不上的问题就采用卖萌的方式来规避掉。
c、基本上无自学习能力,规则只能完全由人工维护,且规则基本是固定死的。
d、性能、扩展性较差。还是上面的一句话中包含多个关键词的例子,采用普通程序语言来做关键词匹配,性能奇差。即便采用一些文本处理的算法来做(例如Double-array trie tree),也很难满足大规模场景需求。
2、稍微高级点的实现方法:基于搜索引擎、文本挖掘、自然语言处理(NLP)等技术来实现
相对于1的关键词匹配,此种实现方法要解决的核心的问题可以大致理解为:根据一段短文本(例如用户问的一句话)的语义,推测出用户最可能的意图,然后从海量知识库内容中找出相似度最高的结果。
具体技术实现就不细说了。举一个很粗糙的例子来简单说一下此种实现方法处理的思路(不严谨,只是为了说明思路)。
假如用户问:北京后天的温度是多少度?
如果采用纯搜索引擎的思路(基于文本挖掘、NLP的思路不尽相同,但可参考此思路),此时实际流程上分成几步处理:
1、对输入语句分词,得到北京、后天、温度3个关键词。分词时候利用了预先建好的行业词库,“北京”符合预先建好的城市库、“后天”符合日期库、“温度”符合气象库
2、将上述分词结果与规则库按照一定算法做匹配,得出匹配度最高的规则。假定在规则库中有一条天气的规则:城市库+日期库+气象库,从而大致可以推测用户可能想问某个地方某天的天气。
3、对语义做具体解析,知道城市是北京,日期是后天,要获取的知识是天气预报
4、调用第三方的天气接口,例如中国天气网-专业天气预报、气象服务门户 的数据
5、将结果返回给用户
以上例子其实很粗糙,实际上还有诸多问题没提到:语义上下文、语义规则的优先级等等。
例如用户上一句问:北京后天的温度是多少度?下一句问:后天的空气质量呢?这里实际上还涉及语义上下文、用户历史喜好数据等等诸多问题。
此种处理方法存在的最大问题:规则库还主要依赖于人工的建立,虽然有一定的学习能力,但自我学习能力还是较弱。可以借助一些训练算法来完善规则,但效果并不是很好。而这也是目前流行的深度挖掘技术所擅长的。
3、当下时髦且高级的玩法:基于深度挖掘、大数据技术来实现
这是cornata、google now等后端的支撑技术,至于小冰,感觉应该是以2为主+部分领域知识的深度挖掘。
下图是自己做的产品的架构图,供参考:

 

a4d821b41a189f03227721a8794d5947_m

 

地址:http://www.zhihu.com/question/23952075/answer/26243159

微信公众平台微信消息推送实现方案

Posted in 移动互联网, 技术相关 by chuanliang on 2014/04/29

微信公众平台作为客户关系管理平台、服务平台,必须能够对用户的投诉申告、咨询、购买订单等消息及时响应和反馈,以便在第一时间服务好客户。因此在微信公众平台管理系统中有诸多场景需要及时获取用户互动消息,例如有新的订单产生、新的用户申诉等等。
但目前微信公众平台对消息推送有诸多的限制:
1、公众平台并没有提供主动推送消息到指定微信号的接口,无法推送消息到微信号
2、微信公众平台管理后台能够点对点向在24小时内与公众号互动过的微信号推送消息。注意:如果超过24小时,公众平台再也无法主动推送消息给粉丝。
早期并没有24小时限制,于是有诸多人通过对所有粉丝点对点推送消息的方式来模拟消息群发的效果,从而规避订阅号每天只能群发一次的限制,后来被腾讯封杀掉了。

1、微信公众平台的消息通知方式
因此目前要实现及时获取用户互动消息,除了在后台派专人刷屏外,只能通过邮件通知、短信通知两种方式。
与短信通知先比,邮件通知及时性并不高,且由于国人的使用习惯,较少使用push mail之类的服务,因此邮件通知适合非紧急消息的延迟处理。
短信通知倒是比较及时,但考虑到短信发送成本、短信通道的稳定性等因素后,还是存在较大局限性。
处于移动互联网时代,最合理的消息通知方式莫过于主动推送微信消息给指定的公众号,但正如上面描述,目前并没有直接推送消息给微信号的接口和服务可用。
  有么有靠谱可用的微信消息推送的解决方案啊?

 

2、实现微信消息推送的思路
既然在微信公众平台后台可以主动推送消息给24小时内互动过的粉丝,那么,我们可以利用此规则,让微信公众平台的管理员(或运营人员)每天至少主动上行一 条消息给自己的公众平台,那么我们就可以借助程序来自动化往此微信号主动推送消息。剩下的问题就是:
1、怎样让消息推送过程自动化。也即:有符合业务规则的消息产生时,由程序主动自动化推送对应格式的消息给管理人员或运营人员的微信号
2、怎样保证数据安全,只将消息推送给有权限的微信号
当然在具体的技术实现上还有诸多问题需要考虑的,例如:
用户在微信上行消息的标识是openid:fromusername,而在公众平台的标识是fakeid,这两者的对应关系怎样匹配建立;

在技术实现上,强烈建议由兴趣的同学看看casperjs+phantomjs,简直是自动化模拟的神器,尤其是结合xpath之类,比正则表达式解析页面等方式方便多了。

3、游迹天下解决方案
基于以上思路,游迹天下微信公众平台管理系统提供了对诸如新订单、新预约等重要消息多种渠道推送支持,包括短信、邮件、微信号。
这里主要说一下微信号消息推送的功能使用。
   使用用法:

   1、公众号的运营人员在微信中关注公众号,上行:bangding 到公众号,即可完成绑定操作,由于数据安全原因,缺省状态为:绑定但未生效,此时候运营人员还不能接受消息通知
2、公众号的管理员在游迹天下管理后台的“会员账户管理->微信号绑定管理”中审核对应的微信号,将状态设置为1,将对应微信号纳入到通知列表中。
3、运营人员每天至少在微信中主动上行一条消息给公众号。
   4、系统在有订单、预约等需要通知的地方,会主动推送消息给所有已经成功绑定的微信号。

 

194725h9zirrhrxrxzyshq

用Sphinx驱动WordPress搜索

Posted in 技术相关 by chuanliang on 2014/04/14

乐无线lewuxian.com最初的搜索是基于wordpress自身的数据库搜索功能,在数据量剧增的情况下,搜索速度奇慢无比,因此改用Sphinx来完成对Wordpress的搜索请求。

大的框架:采用sphinx-for-chinese + WordPress Sphinx Search Plugin + Redis 搭配来实现搜索性能的优化。其中:

sphinx-for-chinese 在sphinx基础上增加了CJK字符的搜索支持。WordPress Sphinx Search Plugin 是Wordpress插件,用于集成Wordpress和Sphinx;Redis用于搜索操作和结果的缓存。

1、sphinx-for-chinese安装配置

最初直接使用了sphinx 最新版本来实现搜索,为解决中文(CJK)搜索问题,按照 Using Sphinx search engine with Chinese, Japanese, and Korean language documents 提供的方案,大致注意事项如下(对sphinx.conf中每一项source段):

1)、charset_type :Wordpress数据库编码采用utf-8编码,Sphinx 的 charset_type 设置为 utf-8。

2)、charset_table :设置 CJK 专用的 charset_table ,简单起见直接拷贝cjk_index_example.zip 例子提供的charset_table 。

需要注意的是:由于charset_table 的内容太多,无法放在一行,需要分成多行,sphinx.conf的续行标识为“\”,在续行符“\”后一定不能有空格等其他符号,只能为回车换行符号 (\r\n)。在配置过程中,习惯性在”\”后面加了空格,结果在执行indexer时候,报莫名其妙的错误。

3)、ngram_chars:设置CJK分词符(CJK Ngram Characters ),仍直接拷贝cjk_index_example.zip 例子提供的是ngram_chars。

4)、把 ngram_len 设置为 1,目前版本只支持设置为1 。

按照以上步骤设置为,Sphinx倒是能够对Wordpress的中文文档建索引、搜索了,但由于建立索引和搜索时候都是按照1分法索引查询的,导致搜索效果并不好。一般中文搜索按照二分法效果好得多。

因此寻找sphinx中文搜索的更优解决方案。目前可选的似乎就是:sphinx-for-chinese  和coreseek 。简单对比,感觉coreseek对sphinx调整较大,不像sphinx-for-chinese那样简洁,因此选择了sphinx-for-chinese。

在CentOS 5服务器上安装最新版本的sphinx-for-chinese-2.2.1-dev-r4311.tar.gz ,在make时候报错,换成sphinx-for-chinese-2.1.0-dev-r3361.tar.bz2 倒是比较顺利。

编译安装倒是比较简单,sphinx-for-chinese官方文档说得比较清楚。

值得注意的是官方说明文档提到的xdict_1.1.txt 需要从google code下载http://code.google.com/p/sphinx-for-chinese/downloads/list ,并没有包含在发布包中,也没有在官网http://www.sphinx-search.com/ 提供下载。

 

  2、WordPress Sphinx Search Plugin安装配置

参照 WordPress Sphinx Search Tutorial 这篇文章,完成WordPress Sphinx Search Plugin的安装配置。

sphinx与wordpress集成,所使用的配置文件 :sphinx.confhttp://www.yeeach.com/sphinx.conf

注意事项:

1)、由于lewuxian.com对每一个公众号在wp_users中都有一个对应的作者,要支持对author的搜索需要对对应主题theme增加支 持页面。简单起见,采用如下的变通方式:将作者的user_login和user_nicename拼接到wp_main_posts和 wp_delta_posts的source中,这样在建索引和搜索时候可以支持对author的索引和搜索,不需要做其他复杂处理。

sql_query    = select \
p.ID*2+1 as ID, \
0 as comment_ID,\
p.ID as post_ID,\
p.post_title as title, \
concat(p.post_content ,’ ‘,u.user_nicename,’ ‘,u.user_login) as body, \
        t.name as category, \
IF(p.post_type = ‘post’, 1, 0) as isPost, \
0 as isComment, \
IF(p.post_type = ‘page’, 1, 0) as isPage, \
IF(p.post_type = ‘post’, 0, IF(p.post_type = ‘page’, 1, 2)) as post_type, \
UNIX_TIMESTAMP(post_date) AS date_added, \
GROUP_CONCAT(DISTINCT tag_t.name) as tags \
from \
wp_posts as p \
left join \
wp_users  u on (p.post_author=u.ID) \

 

  3、搜索操作及结果的缓存

由于在搜索后展示搜索结果详情时候需要查询数据库,目前服务器资源有限,为减缓数据库压力,采用Redis对搜索操作及结果进行缓存,可参考 使用Redis突破WordPress性能瓶颈

 

   4、其他配置

1)、crontab配置

1 1 * * * /usr/local/sphinx-for-chinese/bin/indexer –rotate –config /data/www/wwwroot/www.lewuxian.com/wp-content/uploads/sphinx/sphinx.conf  –all
*/5 * * * * /usr/local/sphinx-for-chinese/bin/indexer –config /data/www/wwwroot/www.lewuxian.com/wp-content/uploads/sphinx/sphinx.conf wp_delta –rotate
*/5 * * * * /usr/local/sphinx-for-chinese/bin/indexer –config /data/www/wwwroot/www.lewuxian.com/wp-content/uploads/sphinx/sphinx.conf wp_stats –rotate

2)、searchd

searchd启动脚本

放到/etc/init.d/searchd ,然后执行:

chkconfig  –add  searchd

chkconfig  –level searchd 345

3)新搭建的wordpress,执行indexer –rotate  –config –all 报max_id=’(null)’ 和min_id=’(null)’错误

using config file ‘/data/www/wwwroot/www.lewuxian.com/wp-content/uploads/sphinx/sphinx.conf’…
indexing index ‘wp_main’…
ERROR: index ‘wp_main’: sql_query_range: max_id=’(null)’: must be positive 32/64-bit unsigned integer.
total 33471 docs, 294394782 bytes
total 80.890 sec, 3639444 bytes/sec, 413.78 docs/sec
indexing index ‘wp_delta’…
ERROR: index ‘wp_delta’: sql_query_range: min_id=’(null)’: must be positive 32/64-bit unsigned integer.

解决办法:

select min(id) from wp_posts;

select min(comment_id) from wp_comments;

如果min(comment_id)为NULL,则随便找一篇帖子回复一下即可。

 

5、参考资料:

Using Sphinx search engine with Chinese, Japanese, and Korean language documents

sphinx-for-chinese官方文档

Sphinx速成指南

 

原文链接:http://www.yeeach.com/post/1247