Your SlideShare is downloading. ×
手机之家新系统介绍及架构分享
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

手机之家新系统介绍及架构分享

19,943
views

Published on

手机之家 (Imobile.com.cn) 在 Beta 技术沙龙上的分享 PPT

手机之家 (Imobile.com.cn) 在 Beta 技术沙龙上的分享 PPT

Published in: Technology, Business

1 Comment
82 Likes
Statistics
Notes
No Downloads
Views
Total Views
19,943
On Slideshare
0
From Embeds
0
Number of Embeds
10
Actions
Shares
0
Downloads
1,138
Comments
1
Likes
82
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 手机之家新系统介绍及架构分享 IMOBILE TEAM 2009.03.29
  • 2. 手机之家首页
  • 3. 一)手机之家新系统介绍 1) 关于手机之家 2) 新系统概览 二)软件架构分享 1) 架构演变与发展 2) DAL 设计概览 3) 持续改进 三) Q & A 目录
  • 4. 手机之家新系统介绍
  • 5. 关于手机之家 手机之家是一个旨在提供全方位的手机相关服务的资讯类网站。在 7 年的 时间里,手机之家从无到有,已经发展成为极具人气、最受关注的手机产 品资讯网站。 目前已有的一些统计数据: a. 1000w+ 用户 b. 3000w+ 帖子 c. 1.1TB+ 附件 d. 780w+ Page View/ 每天 e. 5~10w 在线用户 /15 分钟
  • 6. 新系统概览 (1)‏ a. 从头设计、全部重写 b. 100% 采用开源软件 c. 自行开发: Web 层: MVC 框架 , 模板引擎 , JS 框架 ... 基础组件:简单的 glue, Monkey(Java NIO 框架 ), JMCL ... 中间件: DAL(Data Access Layer), JMCD, Session, Tools, 小文件存储系统 , 基于 Lucene 的搜索系统 ... d. 混合编程: PHP+JAVA e. 操作系统: centos5; 数据库: MySQL5; Web Server: Nginx
  • 7. 新系统概览 (3)‏ Logic MySQL Model MySQL MySQL DAL 中间件 Ctrl View Web
  • 8. 软件架构分享
  • 9. 架构演变与发展 - 老系统的问题
    • a) 由于系统分层比较模糊,导致问题极难排查,到底是哪个层面出现了错误
    • ?是页面相关的地方、访问数据的地方,还是处理逻辑的地方?
    • b) 由于 web server 可以直接访问 db server ,在高峰阶段,并发量比较
    • 大,导致 db server 经常 down 掉。
    • c) 数据表结构设计不当,导致无法很简单地 ( 甚至不可能 ) 进行竖直和水平
    • 方向的伸缩。
    没有设计!
  • 10. HTTP MySQL MC 数据访问层 表现层 逻辑层 FastCGI MySQL 架构演变与发展 - 纯 PHP 分层方案 (1)‏ R W
  • 11. 架构演变与发展 - 纯 PHP 分层方案 (2)‏ 方案 (1) 解决了之前所说的问题。但是: a) 开发一个功能,要写很多代码,而且有大部份代码是相当乏味的,重复性 极高,千篇一律,特别是数据访问层代码。 b) 程序员自己控制缓存。这使得: <1> 缓存代码渗透到业务逻辑的每一个角落,造成代码维护成本上升。 <2> 程序员根据自己的喜好来控制缓存的 KEY 和 VALUE ,造成缓存混乱。 <3> 程序员既要负责业务逻辑的编写,还要负责缓存管理,造成编程复 杂度提高、开发效率低下。 这些问题,迫使我们寻找其它的解决方案。。。
  • 12. 架构演变与发展 - 改进缓存 (1)‏ 我们对数据库记录的缓存的访问做了一定的抽象处理,开发出了 cache 处 理器。 所有的数据访问都经过 cache 处理器。这样,系统代替程序员接管了缓存 的存取访问。缓存的 KEY 和 VALUE 由系统处理,从而避免了冲突和 混乱。 cache 处理器的引入减少了 40% 的数据访问层代码! 最重要的是,我们采用了 Namespace 的方法使得缓存能自动清除了。
  • 13. HTTP MySQL MC 表现层 逻辑层 FastCGI 架构演变与发展 - 改进缓存 (2)‏ R W cache 处理器 数据访问层 cache 处理器 NS 处理器 php fcgi + SQLite 实现
  • 14. 架构演变与发展 - 改进缓存 (3)‏ 但是问题又来了,此时,系统响应速度变得很慢。原因在于,我们 Namespace 是借助 PHP fcgi 进程 +SQLite 来实现的。 这促使我们对采用纯 PHP 方案的可行性产生了质疑。。。
  • 15. 架构演变与发展 - PHP+JAVA, 提升性能 (1)‏ memcached 不支持 namespace ,也不支持遍历。 所以,我们基于之前开发的 monkey(java nio 框架 ) 实现了一个支 持 namespace 遍历功能的内存缓存程序 – jmcd 。我们采用了简单高效 的 STP 协议。
  • 16. 架构演变与发展 - PHP+JAVA, 提升性能 (2)‏ HTTP MySQL MC 表现层 逻辑层 FastCGI R W cache 处理器 数据访问层 cache 处理器 NS 处理器 基于 JMCL 实现
  • 17. 架构演变与发展 - PHP+JAVA, 提升性能 (3)‏ 我们改进了 Session 的实现方式:在 monkey 和 jmcl 的基础上开发出 session server 。 这次响应时间提升了 80 毫秒以上!这基本上达到了性能预期:平均每个页 面响应时间低于 20 毫秒。
  • 18. 架构演变与发展 - DA 引入 , DAL 产生 (1)‏ cache 处理器在缓存的存取方面有了很大的进步,但是由于接口众多,使 用起来不太方面。而且还是要编写大量的重复代码。 为此,我们重构了这部份代码,吸收了其它框架的优点,开发出 了 Data Accessor( 简称 DA) 。
  • 19. 架构演变与发展 - DA 引入 , DAL 产生 (2)‏ HTTP MySQL MC 表现层 逻辑层 R/W DA JMCD 存储 NS 、 Id List 、聚 合运算结果
  • 20. 架构演变与发展 - DA 引入 , DAL 产生 (3)‏ DA 标准化了调用接口,简化了编程,使程序员在业务逻辑层面不再关心缓 存与切库分表,极大地提高了生产力 ( 代码量继续减少,易用性提高 ) 。 但是它仍然有很多不足。 DA 直接和数据库打交道,在这一点上,可以说是 又回到了起点。 不过,从逻辑上来说, DA 已经是之后构想的 Data Access Layer 的雏形, 经过 4 个月的运行测试,现在,我们把[原 DA ]称为 DAL1.0 ,而把 [原 DA ]中包含的客户端程序仍然称为 DA 。
  • 21. 架构演变与发展 - DAL2.0(1)‏ DAL1.0 有很多不足,要弥补这些不足,必须从根本上进行重新设计。如果 说 DAL1.0 是为易用性而设计,那么 DAL2.0 就是为性能、可用性等等而设 计。。。
  • 22. 架构演变与发展 - DAL2.0(2)‏ HTTP MySQL DAL Server 表现层 逻辑层 SCGI DA CACHE JDBC Oracle ??? JDBC JDBC
  • 23. DAL 设计概览 - 关于分库切表 1) 垂直切分:按功能分。分到不同的数据库或服务器。 2) 水平切分:对数据进行水平分割。 a. 最好分到同一个数据库。 b. 一种已经证明是切实可行的方案:主表+辅表。 c. 有 3 种类型:主表不打散、主表打散无辅表、主表打散有辅表。 d. 但对程序员来说, TA 看到的只是一张表,不妨称之为虚表 ( 逻辑表 )‏ ,这张虚表实际上可能是由 N 张实表 ( 物理表 ) 组成的。
  • 24. DAL 设计概览 - 关于缓存 1) 缓存很重要。 2) 但不应该紧耦合于业务逻辑。 3) 慎用 XC/APC 缓存,一般情况下, mc/jmc 这种远程缓存已经够用了。 4) 缓存的最佳实践:缓存单个条目,根据 id list(unique key list) 找列表。 5) 缓存能自动清理就自动清理,不能自动清理的想办法自动清理。
  • 25. DAL 设计概览 - 目标 1) 程序员不再关心 ( 尽量少关心 ) 分库切表问题,经 DBA 配置,由 DAL 处理。 2) 程序员不再关心缓存的存取与清理问题,由 DAL 处理。
  • 26. DAL 设计概览 - DA 用法示例 (1)‏ 1) 增: DataAccessor::insert()‏ ->table('imobile.post.db_post')‏ ->data(array('post_id'=>1, ...))‏ ->dup()‏ ->execute(); 2) 删: DataAccessor::delete()‏ ->table('imobile.post.db_post')‏ ->where('post_id', 'IN', array(1, 2, 3))‏ ->limit(2)‏ ->execute();
  • 27. DAL 设计概览 - DA 用法示例 (2)‏ 3) 改: DataAccessor::update()‏ ->table('imobile.post.db_post')‏ ->data(array('level'=>0))‏ ->where('user_id', '<', 1000)‏ ->limit(100)‏ ->execute(); 4) 查: DataAccessor::select()‏ ->table('imobile.post.db_post')‏ ->columns('post_id')‏ ->where(array('thread_id'=>1, 'forum_id'=>2))‏ ->getPage();
  • 28. DAL 设计概览 - DAL Server2.0 设计目标 1) 提升性能 : a. 连接池 b. 并行查询、合并结果 c. 更好的缓存处理 ( 过期策略可配置、缓存提供者可配置等等 )‏ 2) 提高可用性 : a. 多个 DAL 实例 (1 available + n candidates)‏ b. 引入单数据库事务 3) 其它:更智能的 where 分析,表的状态监控, DAL 更具可扩展性。。。
  • 29. DAL 设计概览 - DAL Server2.0 的可扩展设计 DAL Server2.0 总体上设计成 (core + plugins) 的形式。 core 负责一些不可插件化 ( 或难以插件化 ) 的组件, plugins 则是那些可插 化的组件。 如配置处理、查询分析,选路策略,数据处理等等就是属于 core 的内容。 而 CacheProvider, ConnectionProvider... 就是一些可插件化的例子。
  • 30. DAL 设计概览 - DAL Server2.0 示意图 Monkey query executor routing strategy query parser cache provider result merger cache MySQL conn provider DAL Server2.0 config manager result encoder dal handler
  • 31. DAL 设计概览 - 扩展 DAL 概念 (1) 访问数据,可以是访问数据库中的数据,也可以是 MC/JMCD 当中的数据, 那为什么不可以是 lucene 索引中的数据?
  • 32. DAL 设计概览 - 扩展 DAL 概念 (2) 5) 搜: DataAccessor::search()‏ ->index('imobile.thread.db_thread')‏ ->fields('title')‏ ->key(' 三星 ') ->where(array('forum_id'=>2)) ->andWhere('date', 'BETWEEN', array(20090305, 20090310))‏ ->getPage();
  • 33. DAL 设计概览 - 扩展 DAL 概念 (3) HTTP 表现层 逻辑层 SCGI DA Search Server SCGI 原 DAL Server Data Access Layer MySQL Lucene 索引
  • 34. 持续改进 1) 很多轮子已成通用轮子。 2) 不断完善已有轮子。 3) 还会有新轮子出现:如,在表现层引入 Widget ,更好的存储系统 ...
  • 35. Q&A
  • 36. The End Thanks:)‏