阿里O2O战略—在中信证券内部讲话

O2O这个大词,国内能够干这事的公司,目前首推阿里、腾讯。范言直谏 (微信公众号fanyanzhijian)推荐大家读读这篇文章,阿里虽然最近风头大减,但依然是国内电商领域首屈一指的玩家,不得不察。

本文来自阿里集团O2O品牌负责人于2014年2月19日在中信证券“互联网O2O”专题研讨会上的演讲。此文流传甚广,我把要点作了点标注。

非常感谢大家!刚才在会议上听到毛老师(毛长青)演讲有非常多同感,另外我发现最近每个行业关于O2O的话题,都是整个行业里面最热门的话题。这是我第二次在中信证券的讲台上跟大家做分享,2013年是在中信证券厦门品牌服饰论坛中跟大家分享天猫战略。这一次O2O有一点雷军所讲的台风口的感觉,因为整个行业非常兴奋,另外这次是一场真正革命的到来。

从战略四步走看O2O

刚才毛老师讲到阿里集团著名的曾鸣教授,曾鸣教授在我们内部高管里面培训的时候,包括做O2O培训的时候,给我们讲什么叫做战略。战略,对我们所有规划和思考、以及未来做事情的时候,有非常多的借鉴。曾鸣教授给我们讲战略的时候,分为四个步骤:

第一步是终局。终局错了所有都会错,因为方向会错掉。之所以今天阿里巴巴发展成这样一个大的公司,因为13、14年前马云便提出未来电子商务会改变世界的方方面面。虽然那个时候这句话是比尔·盖茨说的,但正是因为14年前对终局的思考,才有今天阿里巴巴的转身。

第二步是布局。为了终局我们到底要做哪几件事情?讲到布局讲一个案例:我们最近又把高德地图全线收购了,是因为地图是整个O2O产业中最基础、最核心的一个板块。高德地图以往有吃喝玩乐的很多信息,但是对于O2O最核心的品牌商领域,比如说大家看到的GXG、ZARA等很多线下品牌,以往地图上没有呈现。随着我们O2O战略的进展,2014年所有上百万级的品牌商店铺都会到线上来,而后包括营销在内的所有策略都会基于地图,高德地图整个价值会翻好几倍,所以说我们全线收购了高德地图。未来O2O战略中,每一个跟O2O核心价值相关的产业,都会成为一个非常重要的投资热点。收购高德地图讲的是布局。

第三步我们称之为定位。到底消费者如何认知我们的平台和我们的战略。在阿里,我们认为很核心的地方是:所有消费者和商家把阿里视为以商务和电子商务为核心的平台,这是我们的定位。未来我们会帮助所有企业解决商务的问题。后面我会讲我们策略已经从电子商务变成商务电子化,之间区别我后面会讲到。

第四步我们称之为策略。实现所有事情我们要走的路线,分别是什么样子、方法和步骤,这是我们公司在内部制作所有产品时候的思考方式。

在我们整个思考中,O2O是未来3-5年内行业非常关键的策略。但是讲到这里跟大家说一个不幸的消息,O2O并不是整个产业的终局,O2O乃至整个电子商务产业的未来来自商业的终局。如果想透彻后,未来终局是C2B。从最早的C2C到B2C、O2O、再到C2B,其中O2O是其中非常重要的环节。不知道大家记不记得,我们不久以前私有了我们的上市公司1688,很多人不理解为什么私有化,不是赚钱挺好的吗?原因我们发现整个淘宝目前有1.2万亿的市场,但是在我们B2B产业背后,有一个3万亿的供应链市场。前面毛老师讲,整个电子商务对行业的发展不仅仅是对渠道,背后最核心的是对于整个商业链条的颠覆,是第三次工业革命价值的诞生。我举一个例子来说明,所有产业怎么来发展的。为什么会私有化、为什么C2B会是核心?我们2013年“双十一”的时候,有一家公司叫茵曼,他们做了一件事情:“双十一”选择了500款衣服没有生产,只是做了样衣和价格,然后把衣服扔给所有消费者让他们做选择。于是消费者根据自己的习惯和喜好从500款中选择了150款,而且每一款消费者根据数量付了订金。之后这家公司再把数量和产品给到自己的制造工厂,工厂再把制造订单给到原料厂商给到布料商、拉链商等等。大家会发现,整个产业从消费者订单到品牌商、从品牌商到原料商、从原料商到所有环节,用数据打通了所有产业链,这样的效率彻底改变了以往生产状态。

从电子商务到商务的电子化

现在讲一个重要的观点,我们5%市场在电子商务端,而95%市场是没有被电子商务化的。在2013年“双十一”之前阿里集团形成了一个非常重要的概念,这个概念在未来将逐渐形成产业端的认识,我们称之为从电子商务到商务的电子化。如同前面所讲,既然有95%的商业依然在线下、依然没有电子化、没有电子商务化,一定是因为某些场景和某些环节无法形成一个商业的闭环。而今天我们反过来去思考,为什么一定要形成闭环?现在目前在我们的互联网上有很多文章在传,比如说如何用互联网思维去改造某某。我们一样在思考,如何用互联网思维、用数据化的方式,去改变以往传统产业。所以2014年我们会把它称之为整个中国的O2O的元年,因为2013年“双十一”启动了这样一个项目后,阿里巴巴把自己战略重点从电子商务变成商务电子化。

后面我会讲到店铺智能化,大家所看到每一家线下店铺,在今天看起来依然是一个没有上网的PC。在今年O2O实现后,未来每一个线下店面以及导购员会成为一个互联网端的PC,这其中的差距会非常大。所有互联网思维以及O2O运行过程中,1%看似很小的差别起着至关重要的作用,因为未来的消费者已经发生非常重要的转变。讲到转变,易经中变化之前先考虑不变、再考虑变、最后考虑变异。

什么在变与不变

首先不变的是所有东西都在变化,但其实有些东西根本就没变。大家要非常清楚,如果不知道什么不变,所有的变化都是乱变化,所有的变化都是没有章法的变化。不变的东西是什么?以及在未来越来越重要的东西是什么?在我们这里已经看到了,前面讲的C2B模式也是一模一样,所有环节都指向一个中心——产品为核心。在互联网端,随着我们O2O进展的越来越顺利,随着未来C2B时代到来,从消费者订单一直到整个产业链转变,这个背后提升的效率,以及对于库存压力的解放,都是基于未来的产品是适应未来的消费者的,这是所有不变的地方。在大家所看到的地方,目前渠道的价值变得越来越小,而整个以产品为核心变得越来越重要,这就是为什么雷军在做小米手机的时候,几乎所有的消费和所有的营销端都在电子商务端做,而把所有80%精力放在产品端,让商业回归其本质的地方,使产品和服务成为所有竞争最核心的要素,这是永远不会变的。所以大家看到未来电子商务中,尤其在淘品牌中发展很快,是因为他们适应了未来消费者的发展。

第二个地方的变化就来了,有一个东西一定会变,而且变化的速度超出我们的想象,就是移动商务的到来。还好有一家竞争对手跑进来名字叫腾讯,最近腾讯支付和支付宝支付打的这么凶,哪家赢哪家输?我开了个玩笑,百事可乐和可口可乐打架哪家赢哪家输?其实都不会输,因为有另外一个竞争对手进来,整个行业会被加速发展,我们两家打架的时候我起了个名字叫做竞争伙伴。我们在竞争,但我们是伙伴,原因是我们两家会快速普及移动支付,而移动支付会去取代或者是很大程度的去取代我们线下银行的POS系统,这才是真正要命的地方。就像马总曾经说过:不会完全取代,但是基本会取代所有线下银行支付系统。后面我讲支付的时候也会讲到,移动端今年基本上所有的流量和销量就会超过PC端,而且发展速度会越来越快。大家所看到移动端我们布局会非常非常多,今年整个阿里巴巴战略布局有三个:第一移动商务、第二O2O发展,因为O2O是整个移动电商中最核心环节、第三个国际化发展。

第三个变异。当这个地方发生变化,有的变有的不变,背后变化的掌握是什么东西?就在这张图上,这就是可能的变异,所有变化核心的场景的地方所在。讲到这里的时候,要特别跟大家强调一个重要概念,在以往我跟很多朋友交流O2O的时候,大家对于O2O的理解会从概念的角度被束缚掉,很多人讲O2O非常局限于线下到线下或者线上到线下,其实O2O概念根本不是两个简单线下、线上的概念,更合适的概念是O&O。大家现在所看到这张图左边场景是一个O2O,我们称之为逻辑图或者策略图,或者是一个重要的方程式。O2O的场景中, Online和Offline只是两条平行线。而打通的核心:第一个地方是SNS,社交化媒体传播。为什么大家看到“来往”发展那么快、“微信”发展那么快;第二个是LBS,这个不细讲;第三个地方是手机端,大家未来会看到阿里云手机。因为在全中国信息安全会成为越来越重要的话题,信息安全核心场景在手机端。手机端有自己信息安全系统或者原创系统的,除了苹果iOS系统、安卓系统之外,中国只有一家。其实大家会发现,我们在这个背后有很多布局。“SO”方面我们收购了微博和陌陌等频道、“LO”我们收购了高德、“MO”我们进行了手机端的整个布局及背后的云数据。上面提到的这三个场景,是所有O2O企业非常关注的、非常重要的地方。

与此相对我们称之为人、货、场三者的结合,以及所有为三者提供的解决方案,因为这三者会被重构和重新组织掉。

人、货、场,三者的重构

“人”的地方指的是我们将向以消费者为核心的体系转变。一方面会员体系将全渠道打通;另外未来的营销将向精准营销和社会化营销转变。特别讲到这个地方,未来的营销在O2O的场景里面,跟现在的电子商务是完全不一样的。在线上做过生意的人都知道,诸如淘宝、京东等频道的行销模式有三种,第一种直通车、第二种站长、第三种是我们内部活动或者双11大促活动分配。这样的营销模式在整个产业布局和业态中相当于什么呢?相当于长江水源的支流,河流的方式灌溉到哪里哪里就繁荣,没有被灌溉的地方基本上不可能成长很大,所以这样的模式会促进原始社会部落的经济。而未来无线端由于是去中心化,他像下雨一样恩泽天下,所有地方无论是否有水源都可能会得到新的流量,所以说所有流量会重新分配。在O2O的场景里面,所有的营销是以地理位置为核心的。

举个例子:Zara店铺营销的客户群,是在这个店周边十公里地方的人群。所以未来营销是基于社区化、区域化的营销服务。因此说未来会有很多新公司和新产业是做区域化营销为基础的,会成为行业里面越来越重要的公司。再就是个性化服务和精准服务。因为有了大数据,线下所有门店会有新会员服务系统,C2B模式会越来越清晰,预售在为消费者选择提供更多可能性。所以未来商业里面会出现极端两极分化,第一种满足大部分消费者需求,这样品牌会越来越多,但是利润会很薄,就像现在看到的一些常规的衣服,T恤衫的东西。另外非常个性化的产品越来越多,因为它满足了个性化的需求。

第二个是货,货最核心第一个地方称之为货品电子化,二维码是一个十分关键的环节;第二个地方是基于商业闭环;第三个链条是在产品打通之后商家的收藏,断色断码会有新的解决方案。

最后是场,场指的是流。第一种资金流;第二种是数据流,讲的更加精准叫做工作流。整个线下管理和店面的管理工作流会因为O2O的存在被彻底的革命掉和颠覆掉,具体怎么做我后面有一个案例给大家;第三种是物流,整个物流体系由于“菜鸟体系”嵌入以及整个O2O和物流分仓发展,都会发生很多革命性变化。

O2O成长中最麻烦与最关键的地方在于利益重新分配

大家看到人、货、场的变化,是整个O2O中变异系数非常大,而且谁在这个地方做好,谁就拥有O2O核心基因。我们讲到这个问题,既然O2O这么美好,O2O的话题在行业里面已经热了接近三年,今年真正非常热,但是为什么好像行业里面没有几家公司可以拿出来说我真的做的很好?除了行业的移动电商还没有发展成熟之外,另外一个非常重要的原因是整个行业里面的利润体系重分配,这才是整个O2O成长中最麻烦和最关键的事情。前面毛老师讲到一点我非常认可:O2O的后边代表的是商业界、乃至整个中国组织结构的变化。重新划分整个品牌的利润体系是O2O发展的前提和核心。我举个例子:鄂尔多斯公司是做羊绒的。这家公司做了一件事情,他电子商务频道非常有趣和好玩。他的电商部门跟所有电商不一样:第一他没有货,第二他也不管发货。这个公司的电商做什么呢?有一天在聚划算包了个品牌团、给了他三十个坑位,他把每个坑位给到不同地方,把流量分配给线下一级品牌商帮助线下渠道卖货。当他们反过来不卖货只帮线下卖货的时候,所有线下的公司开始对电商有了新的认识,而且都对这个公司老总非常客气,原因是他帮谁卖货谁的业绩就会达成。这样的方式一下子解决了所有的利益冲突。另外他也不发货,原因是谁卖出货谁自己发,我把消费者数据给你就完了。这个代表什么呢?

一、以往传统的电子商务由于解决不了线上线下冲突,所以在未来O2O发展中会受限。O2O商业模型中电子商务部门的职能在发生革命性变化。很多公司最早的电商部门是一个新渠道的销售部门,而在O2O的场景中电子商务部门会成为整个公司的一个战略性的部门,将统领全国数据、产品、服务乃至于统领所有以后的整个供应链。这背后所代表的是整个电商在整个中国的经济体中的地位发生革命性的变化。回到刚才讲到的鄂尔多斯,看似简单的配货完成了几个重要的事情。第一个地方电子商务,这个公司O2O的部门拥有一个虚拟的仓、虚拟的产品库,实际没有货但是把全国分销商的库存数据集成在O2O这个部门,所以说他才能做全国货品调配。第二个地方全国库存及时的增减都在这个部门做。第三全国的渠道利益分配机制也通过它来做。第四所有线下货卖出去以后的服务体系也由这个部门来做。所以这个部门的未来,它的协调功能和战略价值会越来越重要。所以说O2O要解决的核心问题是利益冲突和整个组织的问题。这个解决不了所有的O2O只是皮毛,这个能解决掉背后的体系才能够真正运转起来,这是我们讲的第一个事情。

第二个非常重要的事情是宝岛眼镜里面大家看到的变化。O2O场景里面不简单只是线上线下产品打通,而是体现在O2O行业发展中三个重要方面:第一个支付环节走的很快;第二个社区化服务,比如看电影、KTV团购走的非常快;第三个是品牌商,品牌商有一部分商家本身就在做O2O做的事情。比如说宝岛眼镜,以往线上买了产品,线下需要去验光、取镜、做专业咨询。所以我们把服务环节-线上购买环节做完之后,再到线下去服务。同样的地方他也做了一件事情,所有线下购买的货的人的咨询是不需要到店面去完成的。因为他的电商部门每天请了两个专业的眼科医生在线上坐诊,线下所有营销产品的服务在线上去解决掉。所以不仅是商品端,服务端也有很多事情在做。

阿里O2O在2014年会实现的几个重要指标

大家看到前面说我们今天主题叫做千军万码,指得是什么意思呢?阿里O2O的计划中,我们今年2014年会实现几个重要指标,或者实现几个重要的事情。

第一个事情:我们今年将有近五千家品牌商进入到整个阿里O2O战略范围中,而且基本已经都在达成协议。做的是什么?所有线下有10亿以上销售额、100家以上门店的公司,都在我们考虑范围之内,因为这些公司所有线下店面改造都是我们核心所在。千军背后有一个非常重要的东西,百万级线下店铺会到高德地图来。大家以后到线下购物会养成一个习惯,到线上查一查地图,看看能不能领到优惠券,未来消费者会先到线上再到线下。

第二个事情是万码,指的是二维码计划。二维码多重要?二维码是手机打通虚拟世界和实际世界关键时刻和节点的工具。所以说二维码背后会成为一个非常大的产业,请大家特别关注它的价值。未来所有场景里面都会有二维码的实现,它的背后会有非常多功能,品牌、店铺、导购员、会员、支付都有二维码身影。这里特别强调一下分账二维码,就好像淘宝客一样,未来大家发现所有人都可以做成自己的淘宝客。举个例子:今天会上资料如果印上二维码,我们关注任何会员,印刷这个产品的人会得到分成。未来这个市场会非常大,而且二维码会成为未来所有商业非常重要的环节和基础。未来百万级的店铺,乃至所有传统媒体都会因为有分账二维码的呈现,出现完全不一样的商业模式。如果大家投资了媒体的,我们跟谁合作的二维码,这家媒体未来盈利就会被重新焕发起来,就好像我们曾经把传统的“快的”行业彻底改变掉,我们会改变所有传统媒体行业。

第三个事情是在支付环节。支付环节会非常重要,大家看到马总到银泰刷支付宝系统。为什么支付系统在未来商业格局很重要:一、费率非常低,银行费率基本在1%—2%,我们非常低接近千分之五。二、支付宝手机钱包支付,背后有数据交换,数据价值越来越强。三、我现在在台上,我手上一定带着手机,去任何地方手机一定会带在身上,但是钱包和现金不一定会带。未来随着余额宝规模越来越大,大家以后的钱基本在手机端。另外一个地方说现在微信发展非常快,确实这样子,我们两家一起来快速把移动支付整体推动起来,而各个产业会在移动支付解决的基础上发生重要的变化。前面毛老师讲了很多产业,其实半年前甚至一年前我们已经启动了,这些行业很多,比如说医院、大学、公路网、地铁、超市,未来一两年都会发生革命性的变化。阿里系在未来O2O产业场景中,会跟越来越多传统产业发生深入的交流和改变。

另外一个地方是一个产品,这个产品叫做“导购宝”。在整个产业闭环中最关键三个环节:第一个地方是流量和营销。我们会做营销活动,不久大家会看到大型营销活动,但如前面说过,营销方法已经变了;第二个地方是优惠券,所有人去线下都会取优惠券,这个平台已经产生已经做好;第三个地方通过我们二维码的方式以及相应产品做支付。我们再看这个产品,内部是导购员的导购系统,这个导购系统非常重要。O2O中重要单元是线下店铺,线下店铺里最核心人物,导购员以往做不了什么事情,只能在客户到来和离开这个简单时间发生作用。未来导购宝会非常强大,把线下导购员变成一个真正智能的人,因为有数据的交换。把线下店铺变成一个智能店铺,这个背后导购员导购系统可以做几件事情:支付环节可以解决掉、消费者互动可以解决掉、商品打通可以解决掉、营销可以解决掉,还有流量,还有所有的社交都可以在这个地方解决掉。我给大家看一个样本:当消费者自己选择完商品后,会生成订单放到购物车,生成订单之后会生成一个动态的二维码,这个动态二维码都是导购员操作的,完成到这一步消费者只要拿出手机,扫导购员手机上的或者pad上的二维码,就可以把产品整体放入自己的购物车,直接把钱付掉。所以用这样一个智能终端可以解决未来非常非常多的问题,它的作用也会非常强。

当我们一旦打通商品体系有很多新事情发生。我们可以解决现在线下几个非常核心问题。第一,线下到哪里开店。线下公司不一定那么准确,但是我们知道,哪个地方人群、销售率是最高的,我们有所有的地图和所有会员的数据,我们会指导所有品牌商把店铺开到什么地方最好。第二、店铺备货。这个店铺是鞋店,到底备多少双、备什么颜色、每一个颜色码数备多少双,这样数据线下没有但是线上有。我知道深圳所有人脚多大,没有人知道我知道。所以这样的方式我们会指导线下备货,备货之后线下断数、断码我们会知道。这个地方还有一个利益分配机制,这个非常难但是非常关键,任何一个场景都会有至少六方利益分配需要考虑。我们有导购系统解决,六方包括商家、平台、店面、导购员、商场和第三方,都是我们要解决利益关系的人。O2O非常的困难,电商向来发展最快,而传统商场和品牌又是最传统、水最深的,这样子两者结合起来本身就是整个中国到目前为止产业经济中最复杂的一次交集,一定会产生中国软件行业的一次革命。也对中国所有的管理咨询,乃至于资金投资企业,有一次新的增长起点。关于O2O闭环,时间关系不细讲,我强调一个非常重要的环节。未来我们购物的时候,大家可以直接跟你的店铺联系,而不是到了店面才可以。什么意思?比如说今天我们深圳降温了,大家想买一件衣服。在以往的时间点你没法知道周边哪个地方有zara的店,而今天过两个月之后大家从手机端可以查到,原来两公里地方有一家zara的店,大家现在就可以跟他的导购员进行沟通,两公里之外你把你的身高、买什么东西告诉她。这样的服务和沟通会越来越好,我强调这个原因地方是很多产业方式会产生变化。

最后,在阿里巴巴O2O的规划,实现的效果我们称之为四通八达,四通指所有O2O场景中,必须打通以上四个重要环节。第一个环节是流量打通。流量打通背后体现地图的价值,区域化营销非常大。第二个环节是会员体系打通。我相信大家跟我一样,钱包里面有十张二十张各种各样的会员卡,这是很不方便的事情。未来所有会员卡都会装到手机淘宝端,电子会员卡会成为一个真正的潮流。第三个环节是支付体系打通。支付体系打通我们前面讲过,线上支付宝会铺设到所有大家可以看到的线下店面里面去。方式有非常多,声波支付、二维码支付、前面讲到的导购员手机上系统支付、乃至未来战略合作支付都会做。第四个环节商品打通。一旦打通形成一个完整的产业闭环,包括物流体系、分仓体系、二维码。八达指的是:八个重要业务场景里面我们去思考所有背后的解决方案。在最近,我们已经跟中国比较大的企业做了非常多战略合作,比如说海尔、日日顺等等,我们有非常多大型企业已经推进O2O试点,不久大家会看到八个场景里面代表的地方是有接近95种不同行业的,或者是不同组织结构解决方案。我们跟所有战略合作伙伴做沟通和合作的时候,每一家都会出一个针对性解决方案。在上个月我做了三家解决方案,一家海尔、一家格力、一家TCL,做起来发现三家看起来是家电,但是完全不一样,因为组织、产品、分销、利润体系不一样。所以这个非常重而且非常重要,给产业带来巨大机会,是因为背后具有个性化的产业解决方案。

一点感受

最后谈谈自己的感受。第一点感受,基因。我以前觉得我跟电商一点关系没有,后来发现我的关系越来越大。大家都在讲互联网基因是什么?互联网思维和互联网基因。我上硕士的时候做的就是基因学,做的克隆就是基因,我觉得越来越有关系,整个互联网基因会越来越强大。第二点,生态系统。阿里巴巴是一个生态系统,生态系统背后代表着我们做O2O的时候为大家会创造一个新的生态环境。这个生态环境里边有三个重要的要素,第一个是经济环境,像空气一样;第二个作为我们,就像土地一样。我们自己没有太多生命力,但是在我们土地上提供第三方非常有可能性,所以跟O2O产业相关的第三方包括地图、wifi、营销体系、社交体系、手机体系,每一个合作产业未来都有非常大发展。第三点,就是我们品牌商、消费者和商场,在未来会发生非常多的质的变化,不仅仅是数量变化。这个生态体系里面,相信我们阿里巴巴集团还有我们中信证券,还有我们今天在座所有品牌商以及相应的伙伴们,在未来都会看到在O2O的潮流来了之后整个经济体的变化。而且我们看到一个非常重要的趋势,今年开启的整个O2O大门之后,在2015年,仅仅是一年之后的今天,大家会看到O2O的场景基本全部实现。这样的方式比以往所有行业速度来的非常快,这个背后代表着这个时代赋予的非常好的机遇

Evernote helps you remember everything and get organized effortlessly. Download Evernote.

白宫宣布激励太阳能光伏产业发展新举措

【大美太阳能快讯】白宫宣布激励太阳能光伏产业发展新举措

2014-04-18 大美太阳能快讯

  美国白宫17日宣布一系列新举措鼓励联邦政府机构、家庭、企业、社区安装太阳能电池板,以促进美国太阳能产业发展。

  白宫当天发表声明说,太阳能是奥巴马政府全面能源战略的重要组成部分。自奥巴马政府上台以来,随着对太阳能研发的大量投入,美国太阳能电池板价格已大幅下降,太阳能市场增长迅速。美国整个太阳能行业的发电能力已从2008年的约1200兆瓦增至目前的约1.3万兆瓦,可以满足220多万户美国家庭的用电需求。

  为进一步促进太阳能产业发展,白宫当天宣布一项计划鼓励联邦政府机构、军事基地和联邦政府资助的公共建筑物在屋顶或开阔地带安装太阳能电池板。同时,美国能源部将出资1500万美元帮助家庭、企业和社区发展太阳能项目。美国环保局也宣布其绿色能源合作计划承诺,十年内使包括太阳能在内的可再生能源使用增加一倍。

  白宫表示,未来几个月,美国能源部还将为企业安装使用太阳能和获取清洁能源融资出台技术指导手册。本周早些时候,美国能源部已宣布计划为太阳能创新应用项目提供至少25亿美元贷款担保,以完善太阳能分布式发电系统。

Evernote helps you remember everything and get organized effortlessly. Download Evernote.

3.5中TermInfosReader的改进学习

From Evernote:

3.5中TermInfosReader的改进

Clipped from: alires:///MsgHistory/recent_tribe.htm?cssname=default

Ref:

1. https://issues.apache.org/jira/browse/LUCENE-2205

2. http://www.nearinfinity.com/blogs/aaron_mccurry/my_first_lucene_patch.html

原来思路:

-  private final Term[] indexTerms;
-  private final TermInfo[] indexInfos;
-  private final long[] indexPointers  

1) 利用这三个字段来保存Term相关信息。

2) 每隔128保存一个Term信息,因此保存的实际上是总共term的  1/128 。

3) 因为term是有顺序的,在查找一个term的位置时,使用的是binary search, 在比较时使用的是String 的compare 

3.5中修改点:

1.  将 term, termInfo indexPointer信息保存到 TermInfosReaderIndex 类中。

2. Term中包含的信息: 

   String field;  (1) 哪个字段

   String text;    (2)  什么内容

   

   TermInfo 中包含的信息: 

    /** The number of documents which contain the term. */

  int docFreq = 0;   (3)   

  long freqPointer = 0;  (4)

  long proxPointer = 0;   (5)

  int skipOffset;         (6)

3. TermInfosReaderIndex 中的处理:

 for (int i = 0; indexEnum.next(); i++) {

      Term term = indexEnum.term();

      if (currentField != term.field) {

        currentField = term.field;

        fieldStrs.add(currentField);

        fieldCounter++;

      }

      TermInfo termInfo = indexEnum.termInfo();

      indexToTerms.set(i, dataOutput.getPosition());

      dataOutput.writeVInt(fieldCounter);    //(1)来代替term中的field 

      dataOutput.writeString(term.text());   // (2) 来代替 term中的text

      dataOutput.writeVInt(termInfo.docFreq);  //(3) termInfo中的docFreq

      if (termInfo.docFreq >= skipInterval) {

        dataOutput.writeVInt(termInfo.skipOffset);   //(6) termInfo中的 skipOffset,在某种情况下被省略掉

      }

      dataOutput.writeVLong(termInfo.freqPointer);    //(4) termInfo中的freqPointer

      dataOutput.writeVLong(termInfo.proxPointer);    //(5) ternInof中的proxPointer

      dataOutput.writeVLong(indexEnum.indexPointer);

      for (int j = 1; j < indexDivisor; j++) {

        if (!indexEnum.next()) {

          break;

        }

      }

    }

   从这里可以看出除了field内存使用fieldCount来代替之外,其它都是没有变化。

   term中field使得int来代替有一个好处是尽量使用number来代替string,同时对number和string保持一个映射关系。

诱饵:

前段时间在 jvm 群有提到在系统启动里Forest,Catserver会占用大量内存,导致full gc。

后来有同学 提到 :

我们在做ip查找的时候,把所有的string放一起了。。。。 

用的时候来new string 

用数组压缩掉 

对象少多了 

而且可以减少重复string。 

这样做, 就会成为 3个数组对象+一个string对象 

gc毫无压力 

数组对象主要是 ip地址对应的属性,各种距离。 

哈哈,面对这类场景,我很自然地又想到了 lucene-2205 这个issue,因为我本身对这个issue中某些点印象比较深刻:

这是3.5中的一个重大的 optimization, 当时官方release说明中是:  Very substantial (3-5X) RAM reduction required to hold the terms index on opening an IndexReader

这个issue 从created 到resolved在历时一年多,当然在lucene中历时这么久的也还有其它issue

从这个issue也说明了只要去思考,提出方案,然后在别人指导下,还是可以取得不错成绩的。这issue的提出及解决者就是第一次向lucene社区提交patch,

针对这个issue, Doug Cutting   也出来冒泡了,提了好几点意见:

It’d probably be better not to make TermInfosReaderIndex and its subclasses public, to reduce the APIs that must be supported long-term.
针对这点,我们大部分同学是否有所感想? 因为我目前看到的是:很多人只习惯public,private ,至于是否真的需要public有考虑过这么多吗?针对这个public,这次法洛斯项目中,也是被坑了一次,完全可以写点总结。

Term :   简单来说就是用来表示某个field对应的一个word,(因为分词,一个field可以有多个word,因此也会有多个term)

因为有权重,高亮,span query等功能,需要表示这个term的相关信息,会有TermInfo对象:

lucene 3.5 及之前版本中,对term相关信息在内存中的保存方式:

实现类: TermInfosReader 

 用来保存term信息的是:

 private final Term[] indexTerms ;

  private final TermInfo[] indexInfos;

  private final long [] indexPointers;

  这也是我们平常一般思维习惯上组织信息的方式,分别用3个数组来表示整个索引对应的term信息。

   

      在对象初始化时,从文件中读取相应信息填充这三个数组:

让我们从基本知识点来考虑内存占用情况:

Terms[]

TermInfos[]

long[] 
如果从对象上来说,Term, TermInfos中都没有一丁点多的属性,也没有属性可以合并之类的优化方案了。同时对象中也都已经使用了primitive类型(String 除外啊,:))。

       java占用内存,很容易被忽略的一点是reference。

       任何单一的引用会占用 4个字节(32位机器)or 8字节(64位机器)。从引用角度来看,我们可以算一下保存term信息的这几个数组会占用多少内存

Terms[] 占用内存是 length * 3,  其中一个引用是Term对象,另外两个是Term中的String 属性

TermInfos[] length*1,  只是TermInfos占用一个引用,因为其内部都是primitive

long[]   只占用 1 reference, 可以忽略了吧

因此假设索引中有10亿个term(不要觉得很夸张,一个document中可能包含几十个term,如果以一个doc中包含50个term来算,只需要2KW document), 在 32位机器上,保存这部分内存中的term(对,是内存中的term,并不是全部term)需要  125M = 1,000,000,000/128 *(3+1 reference)*4bytes,在目前都是64位天下的情况下,就会占用 250M。 如果把128变成 64,那在64位机器下就是500M占用,这可是只是reference占用的内存啊。

如何把这些reference占用的内存省下来呢?  砍掉对象,在内存中不再以对象方式组织信息,以bytesArray来保存原始信息,同时为了能反向找出对象信息,偏移量信息的int数组是必须的

我们再看一下这样的思考来保存term相关信息的话,实际代码是如何实现的:

有了偏移量,在get时,查找相关term信息就不会是问题啦,主要是也不想再写了,哈哈。

为6月的电商大战贡献真金白银

这个6月电商界还真挺热闹的,其中之一就是几大书市都在大搞促销。

今天在amazon上下单买了5本书:

<<选择的悖论:用心理学解读人的经济行为>>

<<大数据时代:生活、工作与思维的大变革>>

<<程序员的数学>>

<<黑客与画家:硅谷创业之父Paul Graham文集>>

<<思考的乐趣:Matrix67数学笔记>>

发现这书目还是和工作,自己长期以来的兴趣最为有关。

 

4.2中solr对docvalues支持学习

From Evernote:

4.2中solr对docvalues支持学习

1. 入口:

          对solr来说,schema是任何新增数据类型支持的一个入口。

          对docvalues的支持也不例外,如果某个field是支持docvalues,应该是在schema中体现。

      实现的体现是:

   

 

   相比之前的field定义,这里多了 docValues=”true”这一property.

2. domain级别的支持

   描述这些property的类是:

    FieldProperties.java 

          protected  final  static int STORE_OFFSETS      = 0×00004000;

          添加了: protected final static int DOC_VALUES          = 0×00008000;

          这里采用了bit values for boolean field properties

          这比一般设计时采用的为每个boolean variable 采用一个field要好多了,节省了内存.同时在操作上也会更有灵活性。

   FieldType, SchemaField 这两个子类, schemaField这是一个为field各方面具体提供接口的类,因此肯定会有判断是否支持docvalues这类的方法。 schemaField 对应于schema文件中的field element.

              FieldType 及其子类 是具体的各个field描述。对应于schema文件中field type element。

              FieldType 一个重要功能是它会根据 schemaField生成,对应的value 生成 indexableField

              这一个方法 就把 solr中的schemaField, FieldType, lucene中的IndexableField这三者紧密地联系在了一起。

    

    DocumentBuilder 因为solr是在lucene之上做的,其本身有对filed的定义,document的定义,因此对schema中定义的改动,很容易触及到这个中间者的变化。

3. Add时的支持 

    

    提交的xml文件,包含一个document的信息,

==>对于每个field解释成SolrInputField(name , value, + boost)==> 组合成 SolrInputDocument ==> Docement (AddUpdateCommand-> DocumentBuilder(SolrInputDocument,IndexSchema))       这里一个关键信息是IndexSchema, 因为可以根据field name从index schema中取到 SchemaField
    进而可以得到这个field的type。 这部分业务对象的组织是和配置文件紧密结合在一志的。
    整个schema.xml文件对应于  <=====> IndexSchema
                 <=======> SchemaField
  <=======> FieldType 

      

    这个流程其实也和上述分析的domain修改有一定的内在联系。

    因此关键修改点就在 几个支持docvalues的 具体FieldType 的createField 方法 上。

    在这里一个关键动作就是把 solr FieldType上的配置信息 映射到 lucene级的 FieldType上。 

  note:

        在具体的fieldType的createFields方法中,如果当前field 支持docvalues,会生成两个IndexableField

        一个是无docvalues项的indexableField

        另一个是NumericDocValuesField , 为什么会这样处理呢?

4. query时的支持

    solr 通过父类拿到的都是 doc id

    几个关键点:

    如上述例子中,配置了 intdv为 int 并且支持docvalues,

    在一整个内部,如何来区分这些不同呢?

    也就是说如果在 一个query中,如果使用 intdv 进行sort, 这时对intdv是否支持docvalues放在哪一层?

    

    针对sort这场景, 关心的是对应docid 的doc 中intdv的值是多少, 如果不是docvalues,以之前的经验,这个 value是来自fieldcache,

   如果是docvalues呢?毫无疑问 这个值应该来自docvalues。

   可以考虑使用fieldcache的统一接口,但在返回值时,屏蔽掉是来自feildcach,还是单独的docvalues。

   在fieldCacheImpl的getLongs(…) , getFloats(…), getInts(….) 这些接口中,就是体现了这类设计。

   因此在fieldComparator中,引用就很方便,可以屏蔽底层细节了

   

    @Override

    public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
      // NOTE: must do this before calling super otherwise
      // we compute the docsWithField Bits twice!
      currentReaderValues = FieldCache.DEFAULT.getFloats(context.reader(), field, parser, missingValue != null);
      returnsuper.setNextReader(context);

    } 

facet场景:

  

lucene4.0特性

From Evernote:

lucene4.0特性

Clipped from: http://blog.mikemccandless.com/2012/07/lucene-400-alpha-at-long-last.html

内容总体上来自 Mike McCandless 的  

Lucene 4.0.0 alpha, at long last!

当作一个温故而知新的过程,记录在此。

4.0 alpha有许多重要的改进,基本的是:

3.6.0中所有deprecated的APIS已经被删除了

3.0之前的索引已经不在支持

MIGRATE.TXT 描述了怎样去更改你的应用代码

4.0 alpha和4.0 GA版本之间的索引格式不会再改变(除非为了fix严重的bug而需要更改),但在4.0 beta前,APIS还是会有调整。

插件式的 Codec

 4.0最大的变化是新引入的插件式的Codec框架,这一架构能完全控制索引的所有元素(terms, posings, stored fields, term vectors, deleted documents,segments infos, field infos)是如何写入的。你可以创建你自己或使用现成的codecs,同时你也可以为每一个基本的字段自定义postings format。

有一些有意思的核心codecs:

lucene40 是4.0.0中默认的codec.

lucene3x(只读)能读取lucene 3.x 格式的任何索引

SimpleText 以纯文本方式保存任何信息(这对学习,debug很有帮助,如何应用到生产系统将是一声灾难).

MemoryPostingsFormat   以快速及压缩的FST保存所有postings(terms, documents, positions, offsets) 在RAM中,这对于有限的postings是很有效果的(如primary key (id) field, date field, etc.)

PulsingPostingsFormat 针对那些低频的terms直接内联进terms dictionary,这样就可以减少一次硬盘查找时间。

AppendingCodec 避免了在写的时候进行询盘,这对于如 Hadoop DFS这类文件系统是非常有必要的。

如果你创建自己的codec,这也是很容易来确定是否所有的Lucene/Solr 测试用例是否能通过。如果有测试用例失败了,很有可能就是你的Codec有bug!

一个新的 4-dimensional postings API(to read fields, terms, documents,postings)代替了之前的postings API.

灵活的打分(Flexble scoring)

Lucene的打分机制现在是完全插件式的,其中默认的是 TF/IDF 向量空间模型. 你也可以创建自己的scoring model,或者使用核心scoring models中的一个(BM25,Divergence from Randomness, Language Models, 和 Infomations-based models). 每个文档(document)的normalization 值 也不再被限制到一个字节。各种新的集合统计数据也能被提供出来.

这些改进是 2011 Google Summer of Code Project的一部分(thank you David!).

这两个改进是相当重要,因为他们扫除了后续继续创新的障碍。现在已经很方便尝试文件格式 或者 lucene scoring models的改变。 一个最近出来的类似创新就是这个 灵巧的codec(由Flax的开发完成),通过将postings通过key/value保存在Redis中做到field更新。

Document Values

新版的 docuement values API  为每个文档保存强类型单值field, 这意味着这是一个可能替换Lucene field cache的方案。 这些值是在index阶段事先计算好,以 column-stride(所有文档某字段所有的值被保存在一起,可以理解成类似于列存储?)格式保存于索引中,这使得它比起field cache,在搜索时的初始化时间大大得到提升。这些值可以是固定的8,16,32,64位 ints, 也可以是可变长的(packed)ints; 浮点值,双精度值;6种类型的 byte数组(固定大小 or 可变大小;反向引用【dereferenced】?; straight or sorted).

New Field APIs

创建document fields 的API也已经改变了: Fieldable 和AbstractField 已经被删除, 从Field 类中重构出来的新的 FieldType,这包含field的值应该怎样被indexed。具体的经常使用到的新类已经事先创建好了:

StringField 索引string为一个单一的token, 没有norms 。例如可以把 primary key (id) field, 或者想进行排序的字段设置为StringField。

TextField 索引了完全tokenized String, 带上norms,同时也包括docs,term frequencies 和 positions.

StroredField 表示这个field的值只是保存使用。

XXXDocValuedsField 创建强类型的文档级别值的fields.

IntField,FloatField,LongField,DoubleField 为有效的范围查询和过滤器创造数字类型的字段。

如果这些feild 类没有一个可以应用的,你也可以创建你自己的FieldType, 然后构造一个Field通过传递一个名字,FieldType和值 。

 

note:原来那些老的APIs(使用index,store,termvector enums) 还是存在的(只不过已经是deprecated),为了方便迁移。

这些改变 是 2011 Google Summer of Code Project的一部分(thank you Nilola!).

其它主要改进(Other big changes)

lucene的terms 现在已经是二进制(byte[]); 默认情况下无边无际 UTF-8 编码的Strings, 以Unicode 排序顺序排列。但是Analyzer 是可以自由产生任意byte[]的token.(如CollationKeyAnalyzer就是这样做的).

新的DirectSpellChecker查找提示可以直接从任何一个lucene 索引,这样这避免了维护一个额外的spellchecker 索引。它使用了和FuzzyQuery一样的 fast Levenshtein automata(6+1 2013-2-17)。

Term offsets(term开始结束字符所在的位置)现在可以保存于postings,通过在索引字段时使用FieldInfo.IndexOption.Docs_AND_OFFSETS来实现。期望这对于不需要term vector而能快速highlighting有帮助。

新的AutomatonQuery匹配所有包含了提供的自动机中任一term的文档。WildQuery和RegexpQuery都是简单地构造出相关的自动机,然后再转到AutomatonQuery. 经典的QueryParse会r产生一个RegexpQuery如果你输入的是 filedName:/expression/ 或者 /expression against default field/.

优化(optimizations)

降了这些有趣的新特性以外,也还有一个惊人的性能提升。

如果你使用FuzzyQuery, 针对适度大小的索引你会看到 100-200倍的速度提升。

如果你搜索时使用Filter, 你也可以获取 X3的速度(这取决于filter的密度和query的复杂度),这得感谢于一个改变:filter的使用和删除文档保持一致。(6+1 2013-2-17)

如果在indexing时使用多线程,你将会看到吞吐率的提升,这是因为采用了 concurrent flushing. 现在你也可以使用大于2048M的 IndexWriter RAM buffer.

新的默认Terms dictionary BlockTree只需更少的RAM来保存terms index, 并且有时在terms不存在的情况下可以避免向disk进行查询。另外,field cache 也使用更少的RAM,这主要是不再为每个document保存一个单独的object,而是把character data 打包成共享的byte[] 块。 这直接减少了搜索时73%的内存使用量。

IndexWriter现在buffer term 数据使用byte[]而不是 char[], 这针对ASCII terms 将会少使用一半内存。

MultiTermQuery 现在重写了per-segment,并且cache 每个term的metadata 信息,这样可以在scoring时减少再次的查询。

如果一个BooleanQuery只包含Must TermQuery 条件,这时一个特定的ConjunctionTermScorer会被使用,可以得到25%的速度提升。

减少merge IO影响(reducing merge IO impact)

Merging是一个对IO,cpu相当敏感的操作,这很容易影响到正在进行的搜索。在4.0.0中我们通过两种方式来减少这方面的影响:

Rate-limit merge时的IO,这可以调用FSDirectory.setMaxMergeWriteMBPerSec

使用新的NativeUnixDirectory,针对所有merge 引发的IO,它会跳过操作系统的 IO cache层,而使用direct IO. 这会保证merge不会evict搜索使用的热门pages.

记得在linux上要设置swappiness为0,如果你想最大提升搜索的响应时间。

打开一个input 或者output文件的APIs(Directory.openInput and Directory.createOutput)现在要带上一个IOContext,用来描述需要怎样做(flush 还是merge),因此你可以创建自己的Directory,根据IOContext来改变相应接口的行为。

lucene codec是如何集成的

From Evernote:

lucene codec是如何集成的

lucene 4.0 后整体结构上一个最大的变化就是用户可以写各个codec,为扩展提供了极大的便利。

1. 那整体设置上是如何的呢?切入点是在哪里

codec

2. codec中使用哪些实现,通过

SPI(service provider interface) 来实现。

http://en.wikipedia.org/wiki/Service_provider_interface

3. codec 又是怎样初始化的呢? 也就是说如何配置使用哪个codec

    理解下spring的bean配置,可能会想到是否也利用同样的机制来配置决定使用哪个codec呢?

    同时再思考下,我们有时是不是经常对某一变量先new 一个default value,但同时又提供一个set方法,

     好让外界有机会根据自己的需要来modify这个value。

    没错,其实我们平时在用的这一套方法论也同样适用lucene中如何引用codec。

   对于Codec的总入口类 Codec,提供了一个获取default codec的方法:

  ……

 private static Codec defaultCodec = Codec.forName(“lucene41″);

  …….

  public static Codec getDefault(){

     return defaultCodec;

    }

spi实现的简单解释:

在resources目录下,创建 

完整classname的文件,

文件中内容是文件名对应接口的实现类,

在这个例子中就是各个不同版本的codec实现类。

目前的实现如果想升级某类field的format,必须升级整个codec,不能单独为一个field进行配置