数据访问层开发实践

11,682 views

Published on

1)前言

a) 关于数据访问层(Data Access Layer)

b) 关于Dal


2) Dal的产生


3) Dal的发展

a) Dal2.1.x

b) Dal2.2.x


4) Dal的未来


5)关于我们


6) Q&A

Published in: Technology
2 Comments
14 Likes
Statistics
Notes
  •    Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • good
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
11,682
On SlideShare
0
From Embeds
0
Number of Embeds
7,330
Actions
Shares
0
Downloads
379
Comments
2
Likes
14
Embeds 0
No embeds

No notes for slide

数据访问层开发实践

  1. 1. 数据访问层开发实践 许超前 @ 手机之家 2010 年 04 月 03 日
  2. 2. 1) 前言 a) 关于数据访问层 (Data Access Layer) b) 关于 Dal 2) Dal 的产生 3) Dal 的发展 a) Dal2.1.x b) Dal2.2.x 4) Dal 的未来 5) 关于我们 6) Q&A 目录
  3. 3. 前言
  4. 4. 关于数据访问层 引用维基百科 : A Data Access Layer (DAL) is a layer of a computer program which provides simplified access to data stored in persistent storage of some kind, such as an entity-relational database. This data access layer is used in turn by other program modules to access and manipulate the data within the data store without having to deal with the complexities inherent in this access.
  5. 5. 关于数据访问层 ( 续 ) 应用程序 Data Access Layer DB API 文件 DAL 在系统中的位置
  6. 6. 关于 Dal - 概览 Dal 是手机之家开发的数据访问层软件的产品名。 Dal1.0 、 Dal2.1.x 、 Dal2.2.x 及 Dal2.x 则是该软件的不同版本系列的一个引用。 Dal 是手机之家研发团队近几年在开发和运营上的经验的总结以及智慧的结晶。 开发 Dal 的目的是为了解决在构建大中型网站时遇到的和数据访问有关的诸多问题,如怎样使得分表透明化,怎样使得缓存存取清除自动化,怎样才能更好地防止服务单点故障等等。 Dal1.0 是一个具有里程碑意义的版本,但在很多方面仍然欠考虑。 Dal2.1.x 是一个经过精心设计、认真编写,具有较高可用性的分布式数据访问层,是综合数据代理 ( 如 MySQL Proxy) 、名值对缓存 ( 如 Memcached) 、集群等等思想而构建的一个软件系统。 Dal2.2.x 是目前的最新系列,引入了很多新特性:如分布式事务,支持数据库主从等等。
  7. 7. 关于 Dal - 软件定位 1) 不但具备了 memcached 和 mysql proxy 的优点,还避免了两者的缺点。 2) Dal 作为一个中间件,应保持语言中立、数据库中立。 3) 让系统在数据访问层上具备分布式计算能力。 4) 不造 ORM 轮子,只是发明访问数据的接口。
  8. 8. 关于 Dal - 核心概念 1) 透明 分片透明,缓存透明,主从透明。 2) 虚库 ( 逻辑库 ) 和实库 ( 物理库 ) 虚库:不是一个真正存在的库。也叫逻辑库。 实库:是真实存在的库。也叫物理库。 3) 虚表 ( 逻辑表 ) 和实表 ( 物理表 ) 虚表:不是一个真正存在的表。也叫逻辑表。 实表:是真实存在的表。也叫物理表。 4) 分片 ( 分表 ) 分片可以分布在同一个库中,也可以在多个库中。也叫分表。
  9. 9. 关于 Dal - 核心概念 ( 续 ) 5) 映射 虚库 -> 实库 ; 虚表 -> 实表 ; 应用列名 -> 数据库列名 ; 6) 条目缓存和查询缓存 7) 辅助索引 8) 分片情况:不分片、分片无辅助索引、分片有辅助索引 9) 面向库的开发方式 这是指, Dal 自动从数据库获得需要的信息,而不是由应用开发人员在配 置文件里显示配置。开发人员要配的只是分表的规则、连接池的使用、缓 存的使用等。只在应用层需要和数据库不一样的信息时 ( 如字段名 ) ,才 在配置文件里显式写出。
  10. 10. 关于 Dal - 核心概念 ( 续 ) 逻辑表 A 逻辑表 B 逻辑库 物理表 B_0 物理表 B_1 物理表 B_2 物理库 物理库 物理表 A 物理库 辅助索引 ID PID ... 列名 id pid ... 列名
  11. 11. 关于 Dal - 设计指导思想 Dal 总体上设计成 (Core + Plugins) 的形式。 Core 负责一些不可插件化 ( 或难以插件化 ) 的组件, Plugins 则是那些 可插化的组件。 我们定的是机制,提供的是策略;机制是软件目标和宗旨的体现,一般是不能轻易改变的,而策略则应当是能比较简单地进行切换的。 那么, Core 即机制, Plugins 即策略。
  12. 12. Dal 的产生
  13. 13. Dal 的产生 - 多数现有系统的经典问题 <ul><li>1) 由于 web server 可以直接访问 db server ,在高峰阶段,并发量比较大,导致 db </li></ul><ul><li>server 经常 down 掉。 </li></ul><ul><li>2) 添加缓存代码以降低数据库访问压力,但由于开发人员自己控制缓存使得: </li></ul><ul><li>a) 缓存访问逻辑混杂在系统的各个角落,造成代码维护成本上升。 </li></ul><ul><li>b) 开发人员根据自己的喜好来控制缓存的 KEY 和 VALUE ,造成缓存混乱。 </li></ul><ul><li>c) 开发人员既要负责业务逻辑的编写,还要负责缓存管理,造成编程复杂度提高、开发效率低下。 </li></ul>
  14. 14. Dal 的产生 - 多数现有系统的经典问题 ( 续 ) <ul><li>3) 在分表的情况下,程序员需要考虑和编写大量繁杂的和分表有关的代码: </li></ul><ul><li>a) 需要根据规则计算出数据的存取目标是在哪个分表当中。 </li></ul><ul><li>b) 如果取回的数据分布在不同的分表中,需要合并结果。 </li></ul><ul><li>c) 由于大表切分后变成了多个小的分表,对于有排序要求的查找, </li></ul><ul><li>需要通过建立并查找辅助索引来解决。 </li></ul><ul><li>d) 如果一套分表有多个辅助索引,需要寻找最优辅助索引。 </li></ul>
  15. 15. Dal 的产生 - Dal1.0 应需而生 HTTP MySQL Memcached 存条目 表现层 逻辑层 Dal1.0 MyCached 存 id list 及 聚合运算结果
  16. 16. Dal 的产生 - Dal1.0 的典型用法 接口采用 API Invocation+Call Chain 的方式,所有的方法名取自 SQL 关键字,方便记忆。 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(3)‏ ->execute();
  17. 17. Dal 的产生 - Dal1.0 的典型用法 ( 续 ) 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))‏ ->getAll();
  18. 18. Dal 的产生 - Dal1.0 的成效 Dal1.0 使得数据库的 QPS 从几千降到几百,缓存命中率稳定在 60%~80% 之间。 Dal1.0 还标准化了调用接口,简化了编程,使程序员在业务逻辑层面不再 关心缓存与分表问题,极大地提高了生产力。
  19. 19. Dal 的产生 - Dal1.0 的问题 但是, Dal1.0 仍然有很多不足: 1)Dal1.0 直接和数据库打交道。 2) 如果操作的数据分布在不同的分表中,为了提高性能,需要并行处理。但 是 PHP 不好做到。 3) 为了保证索引和分表数据的一致性,需要引入事务。但是 Dal1.0 没有。 4)Dal1.0 直接针对 MySQL 编码,万一将来需要采用其它的数据库,怎么办? 5)MyCached 和 Memcached 在不同的进程,很多情况下需要两次请求才能组合出完整的数据。 6) 如果需要支持其它的语言,怎么办? 要弥补这些不足,必须从根本上进行重新设计。如果说 Dal1.0 是为易用性 而设计,那么 Dal2.x 就是为性能、可用性等等而设计。
  20. 20. Dal 的发展
  21. 21. Dal 的发展 - Dal2.1.x 大图‏ MySQL Dal Server JDBC Oracle ??? JDBC JDBC Java Dal Client PHP Dal Client Python Dal Client ? Dal Client DALP DALP DALP DALP 缓存组件
  22. 22. Dal 的发展 – Dal Server2.1.x 大图‏ Monkey NIO Framework query executor routing strategy query parser cache provider Event listener MySQL conn provider config manager big queue dal handler Oracle DALP
  23. 23. Dal 的发展 – Dal2.1.x 在手机之家系统中的位置 应用 消息 队列 服务 M3 搜索 索引服务 搜索 更新 客户端 MySQL 计划任务 内置 消息 队列 事件 监听器 Dal2.1.x 调度器 回调应用程序 读取消息 发送更新任务 读写数据 写消息 读写数据 每分钟调一次
  24. 24. Dal 的发展 – Dal2.1.x/Dal1.0 简单性能对比 测试方法:每次涉及 1 个记录,循环 10000 次,每次涉及的记录都不相同。 Dal2.1.x insert: 8.2153069972992s, 8.2881560325623s, 8.2909779548645s delete: 8.928288936615s, 8.4321990013123s, 8.039489030838s update: 8.9594140052795s, 7.6687839031219s, 7.580326795578s select: 7.9645628929138s, 3.0665209293365s, 3.0304710865021s Dal1.0 insert: 42.473783969879s, 43.072340011597s, 42.900885105133s delete: 25.484493017197s, 25.382812976837s, 25.41899895668s update: 74.74593091011s, 74.557103872299s, 74.246424913406s select: 14.060505151749s, 9.7374119758606s, 6.5931770801544s
  25. 25. Dal 的发展 – Dal2.1.x/Dal1.0 对比结果分析 在增、删、改、查四类查询当中, Dal2.1.x 都比 Dal1.0 有了很大的提升。 原因在于:减少了一次 socket 请求、采用了异步消息处理机制、引入连接池及优化了算法等等。
  26. 26. Dal 的发展 – Dal2.1.x/Memcached 简单性能对比 测试方法 Dal2.1.x Memcached1.4.2 每次获取 1 个,循环 10000 次,每次获取的记录都不相同 10.839928150177s( 全部不命中的情况 ) 3.0760769844055s 3.1021270751953s 3.0667681694031s 1.9119760990143s 1.8506801128387s 1.8564429283142s 1.8201019763947s 每次获取 10000 个,执行 1 次,所有的记录都不相同。 0.64966702461243s 0.55020594596863s 0.52798008918762s 0.57868385314941s 0.28920984268188s 0.28875994682312s 0.28748893737793s 0.27671718597412s
  27. 27. Dal 的发展 – Dal2.1.x/Memcached 对比结果分析 从时间消耗的数量级来看, Dal2.1.x 和 Memcached1.4.2 属于同一个级别; 从时间消耗的绝对值来看, Dal2.1.x 还是有一定的差距。 那么这 1/3~1/2 的时间消耗都花在哪了?主要是在协议解析及查询分析上。
  28. 28. Dal 的发展 – Dal2.1.x 的成效 以下是手机之家某个时刻 4 组 Dal 服务的缓存命中率统计快照: 1) [entryCacheHits] => 1999443615(96.53%) [entryCacheMisses] => 71820652(3.47%) 2) [entryCacheHits] => 728834651(82.44%) [entryCacheMisses] => 155230407(17.56%) 3) [entryCacheHits] => 717269426(93.35%) [entryCacheMisses] => 51101159(6.65%) 4) [entryCacheHits] => 217927450(74.06%) [entryCacheMisses] => 76326220(25.94%) 其中, 2) 组服务命中率低的原因是:上面跑的是论坛,全动态的,更新频繁; 4) 组服务命中率低的原因是:应用层又做了缓存了,到 Dal 的冷请求变多了。
  29. 29. Dal 的发展 – Dal2.1.x 的问题 1) Dal2.1.x 采用的是内置缓存,而且存放的数据结构也不好 ( 大量的 Map 及字符串 ) ,在缓存数据量大的情况下, JVM 不堪重负,将进行频繁的 GC 。在高峰情况下,甚至会出现全 GC ,这时客户端 connection timeout 就频繁出现了。 2) 不支持分布式事务。这使得在分片分布在多个库的情况下,数据的完整性得不到保证。而跨查询事务问题更是得不到解决。 3) 不能简单的支持数据库主从。 4) 缓存不能简单地进行外置。 5) 不好在高峰时段进行配置 Reload 。 6) 不管分不分片,都得写一大堆配置。 7) 内置消息队列占用太多内存。 8) 不能把 dal 作为嵌入式包来使用。
  30. 30. Dal 的发展 – Dal2.2.x 大图 Dal 专用 客户端 Dal Server #a Cache #c Cache #a Dal Server #b Dal Server #c Dal Server #d Cache #b Cache #d Dal2.2.x 缓存集群 数据库集群 DB#a DB#d DB#d DB#b
  31. 31. Dal 的发展 – Dal2.2.x 重要变更 1) 自动生成条目 ( 实体 ) 类,用于缓存数据库记录。数据已经有了类型,同时有望缓解 JVM GC 问题。 2) 支持分布式事务。遵循 XA 规范。 3) 支持数据库主从。 4) 缓存内置、外置,任君选择。 5) 更好的元信息抽象,更聪明的发现及重载机制。 6) 更优的内置消息队列。内存中存储的是引用。 7) 已从 Dal Server 分离出 Dal Core ,可以简单地作为嵌入式包来引用。 8) 已支持 Php, Java, Python, Ruby 四个客户端。
  32. 32. Dal 的未来
  33. 33. Dal 的未来 - Dal2.3.x 数据库 特定 客户端 Dal 专用 客户端 Dal Server Dal Admin 浏览器 Dal Server Gtalk
  34. 34. Dal 的未来 - 更多 1) 继续完善功能、提升性能 ; 2) 支持 Spring 、 Guice 集成 ; 3) 支持更多的数据库,如 PostgreSQL, DB2 等 ; 4) 集成全文搜索功能 ; ...
  35. 35. Dal 的未来 - “ 终结者” ” 分布式数据库前端或中控系统”应该是 Dal 这个项目的最终定型。 分片、缓存、主从、事务、异质数据库、多语言、全文检索、监控等等是这个项目的基本词汇。
  36. 36. 关于我们
  37. 37. 手机之家 : http://www.imobile.com.cn/ DAL TEAM: 高春辉 ( 首席顾问 ), 刘增禄 , 张庆城、许超前 , ... 我的博客 : http://www.longker.org/ 我的 Gtalk : [email_address] 我的 MSN : [email_address] 关于我们
  38. 38. Q&A
  39. 39. The End Thanks:)‏

×