感谢IT牛人博客聚合上还能找到我之前博客的一些内容,因为之前主机没续费等各种原因,也懒得翻之前的备份文档了,就把那上面的文章直接拷过来整理一下好了,只搬迁一些还有意义的内容好了,其他的就让它随风而去吧。
最近在淘宝处在一个转折点,一方面有转化面试,一方面就快回学校报到了,再另一方面也是关于自己更应该做什么的思考。刚到淘宝实习时,第一天培训,神奇般的得到了华黎的赏识,希望我能去他那组。当时因为怕社区线这边可能会做前端表现层去做业务逻辑,同时自己也是对中间件很感兴趣,就想去他那里。不过国藩没同意,因为毕竟我还没有真正到社区线实习过,也并不知道我就真的不喜欢这边的工作,所以还是让我现在社区线这边实习,如果实在感觉不给力,再考虑transfer的问题。现在看来,国藩老大是对的,原因一会再说。
然后就是开始在社区线的架构组实习,很幸运,我被分去做社区线的搜索引擎。虽然说这里做搜索引擎并不是想象中那么“高端”——搞分词,搞索引,搞匹配等等,只是基于lucene和solr进行开发,因为这个搜索其实现在也是处于成长阶段,正如育森老大所说的,先要让自身的架子稳定下来,才能想去做一些更高级的事情。但是,实际上在做搜索引擎的开发时也接触到很多以前在学校经验几乎为0的东西——分布式系统。
其实真正去做了才发现自己其实欠缺很多东西,如果真的要是去了平台架构组,我可能不会得到在社区线这么多机会,同时因为根本不了解淘宝的应用,就去盲目做中间件,我真能做的好么?也许在老大们的思想下写好代码还是很简单的,但是这样的东西真的是我的么?显然不是,也不会是,因为我根本不了解这个中间件所应用的场景。
一晃将近两个月过去了,就在转化面试的前一天晚上,华黎问我实习的感受,还有在社区线这边呆的怎么样,如果不爽可以来他那里。之前在和育森交流时,育森也说过,如果我想专心只做技术,可以推荐我去平台架构那边,之前他也有机会去那边,但是他没去,因为他觉得脱离业务很难搞好技术,而且技术也是为了服务于业务,因此他选择回到社区线。这点我还是很认同的,所以在和华黎交流时,我也说我觉得我应该先在社区线这边多锻炼锻炼,毕竟如果不对淘宝的产品应用有了解,很难做好中间件。华黎也是很认同我的想法,也说在SNS的架构组锻炼还是很有好处的,而且毕竟中间件也是产生于生产系统,是将那些共性提取出来,做通用的服务。
今天转化面试时,其实也是和毕玄交流了一下这方面的感想,也说自己做搜索引擎也是用到了淘宝很多中间件,但是站在用户的角度看问题,会发现这个视角和程序员是不一样的。从用户的角度才能更加清楚的知道如何去做中间件,如何能把中间做的易用、稳定、健壮、可扩展性高、通用等等。毕玄也是比较同意的,而且还就我说的底层透明,给我讲了HSF的底层透明带来了什么不便,所以这个底层透明到底是好还是不好,还是值得商榷的。
其实说到底,由于终搜的目标是一个通用性搜索框架,因此实际上终搜本身就是中间件。而且从这次做server-dump的相关接口设计实现上来说,真的重构了无数次,为什么?就是为了做到更加通用、易用、易于扩展等等。
今天负责协助淘女郎那边升级,他们的Dump需求是:从表a取主要数据,然后在根据表a的某字段去另外一个库(实际上是另外一个应用的数据)的表里去取其他信息,然后整个拼合起来做索引。问题来了,我们现在的模型就是单条SQL去dump数据,基本都来自一个应用,即使分库分表,也仅需配置相应规则即可。显然,这个需求不能套在原本的框架里。老大建议还是重写一个DataProvider,然后去管理连接什么的,但是要便于扩展,虽然另外那个辅助表只是分表而已,但是保不准哪天就分库了,所以你尽量帮他们做的好更改些。
于是我开始思考他们的业务逻辑,因为涉及分表,以后还可能涉及分库,所以在利用原本分库分表规则解析器的情况下,我需要得到一个反向索引——原先是数据源对应一堆分表后缀,现在要分表后缀对应数据源。但是我得想好怎么把数据源交给用户,既不用让他们做太多事,同时我也在考虑万一以后还有这种需求,我不是还得写个DataProvider么。既然这样,我不如不把数据源给你了,我只给你结果,剩下的交给我管理,于是有了下面接口:
public interface SQLEngine {
public Map<String, String> execute(String param) throws Exception;
}
SQL语句是预先注入,然后根据传进来的参数进行相应替换。继而我又想,现在淘女郎是只要一个参数,如果需要多个参数的怎么办,于是接口变为:
public interface SQLEngine {
public Map<String, String> execute(Map<String, String> param) throws Exception;
}
这样就给力多了嘛,然后又想,现在淘女郎是一一对应的关系,如果现在情况变成一对多了,该怎么办,于是接口变为:
public interface SQLEngine {
public List<Map<String, String>> execute(Map<String, String> param) throws Exception;
}
经过一番改造,做后终于做出了一个比较通用的东西出来,只需要注入需替换的Sql语句以及分库分表规则(数据源本身就在配置文件里定义了),我就可以返回你要的东西。这样对于用户来说就简单多了。在请育森老大review代码时,他说你这个List实际上有内存溢出的风险,如果数据量比较大的话。不过这个可以在应用端控制,只是理论上的风险,不过iBatis也是这么做的。
iBatis也是这么做的,对啊,我这个东西基本上不就相当于是一个简化版只支持查询的iBatis么,尽管我完全不管O/R关系。但是,最关键的是,我可以支持分库分表啊。一直说想做个分布式数据访问层,对这个有点兴趣,但是现在竟然误打误撞做出这么一个Prototype来!这个,虽然是是在终搜体系中的,但实际上它也是一种中间件,可以应付80%的场景,除非你业务特别复杂。这就是所谓的中间件诞生于生产系统吧。
现在想想,为什么之前想做个DDAL玩玩但是始终没什么思路,但是现在却真的做出来了(虽然它不是一个完整意义上的DDAL)。首先,之前只接触了一些分库分表思想,但是没有实际去了解它的应用场景,一开始可能会无所适从。第二,我从一开始就是想的实现一个完整的DDAL,这样要考虑的点实在太多。又有多少中间件是从一开始就设计出一个伟大的架构然后去实现它,然后让用户去使用它呢?可能不会有,大多数中间件就是从一个小的点子慢慢扩展出来的。如果不是这次淘女郎的业务有需要,我可能不会去写这么一个东西,连这么一点小东西都实现不了,还空谈什么DDAL呢?
所以,我觉得我留在产品技术部门是一个正确的选择,一开始站在一个很高的起点上,虽然是高,但是脚下的铺垫不够厚实,摔下去也很容易。相反,如果每一步路都实实在在的踩下去,夯实基础,我一定会站的更高。