杨武兵个人博客

记录我工作和生活的点点滴滴.

Cobar架构设计

| Comments

前言

最近打算学习一下cobar的源代码,方便以后扩展或者改造cobar以符合我们的需求,增加一些目前cobar不支持的特性,比如读写分离等特性。

以前不知道该如何下手看一个大型开源项目的源代码,经过一段时间的摸索之后,我认为要学习一个开源项目的代码,直接下手看代码会很盲目,不容易看懂。按照以下方法也许更好。

1.先学习开源项目的原理或者协议。了解开源项目的大概实现原理,以及它遵循的协议,比如我原来阅读过的CAS,先了解CAS的协议及原理,再去看源代码就容易看懂了;再比如我之前阅读过的openfire源码,在看之前我们先学习XMPP协议的原理,再去看源代码的时候,就更容易看懂代码。

2.学习开源项目的架构设计。先通过官方或者别人分享的开源项目的架构设计,有助于从宏观上了解整个项目源代码的结构,这样在看源代码的时候就不容易迷失方向,也更容易读懂代码。很幸运的是cobar这个项目的文档还是相对比较完善的。本文也是在学习了cobar的架构设计之后整理出来的,大部分内容和图都是来源于cobar的文档,加上自己的一些理解。

3.带有目的性的阅读源代码。因为一个大型开源项目的源代码都比较多,很难短时间内全部阅读完,带有目的性的去阅读更容易获得成就感,比如你的目的是解决一个技术问题,扩展一个不支持的特性等等。

cobar架构

系统模块架构图

Front-end Communication: Cobar与前端应用的通信模块

SQL Parser : SQL解析,提取SQL中的重要信息

SQL Router : 决定SQL语句被分发到哪些库执行

SQL Excutor : 执行SQL语句

Result-Merger : 合并多个库的执行结果

DataNode,HA Pool,JDBC : 后端数据访问

其实让我们自己来设计一个这样的数据库代理服务器的话估计也会类似于这样设计,因为它确实需要这些功能模块组成。

前端通信

负责从客户端读入SQL语句,并将执行结果集发送给客户端,遵循MySQL协议

解析、路由

解析SQL即提取SQL信息

路由并重组SQL,减少不必要的查询

后端数据访问

后端连接池,连接复用,提升效率

在datanode内部做HA,细粒度的FailOver机制,一旦主库有异常,立即切换到备库

用户可自由将不同datanode的主、备库放在同一数据库实例,分散MySQL实例上的压力

系统实现

各个模块数据流图

网络通讯模块

路由与数据分布模块

结果合并与返回模块

写给即将出世宝贝的话

| Comments

虽然已经毕业五年多了,但是总感觉自己似乎又刚毕业不久,在浏览朋友的QQ空间的时候,发现最近这几年的结婚照和亲子照片比较多,这才意识到已经不在年轻,到了成家立业,结婚生子的而立之年,可能是心态上还没有成熟。

至从得知老婆怀孕后,刚开始是惊喜,来得太意外了,还没有做好心理准备,经过一段时间后突然变得淡定了,非常期待我的孩子早点来到这个世界,这可能也是很多像我一样初为人父心理状态的转变过程吧!

老婆一直叫我先给孩子取一个名字,我在想名字应该蕴含了父母对孩子的殷切希望!所以在起名字之前,我们要先想好对未来孩子有什么期望呢?对于这个问题我思索了很多,特此记录下来,也许当我的孩子某一天能看懂我写的这篇博客的时候,是数十年之后。

对于未来的孩子,不管你是男孩还是女孩,都永远是我们的心头肉,我们永远爱着你!我不期望你要成为商界精英,富可敌国;

我只希望你能拥有以下几点:

健康的身体

高尚的品格

自由的思考

快乐的生活

那么我给你取的名字中应该包含以上几点意思,希望你能够努力做到这几点,如果真能做到这些,我会感到非常欣慰,因为这些是你的父亲一生追求的。

消息中心技术设计总结

| Comments

前言

又有好一段时间没有写博客了,现在终于更加深刻的领悟到坚持是世界上最难的事情,人最大的敌人是自己。反省自己,克服人天生的惰性。

消息中心的功能在很多网站是最常见的功能之一,主要在以下这几类网站上比较常见,第一类:社交类网站,比如微博、QQ空间、人人网等;第二类:开放平台型网站。比如天猫、京东等电子商务平台等。目的是通过消息的形式更加及时地提醒用户,有的是应用系统触发的事件类消息,有的是用户之间的交互类型的消息。

对于不同特点的消息需要采取不同的技术实现方式,以达到业务需求和技术性能的最佳组合。

消息的获取方式

消息实现方式总结

提醒或者消息的获取方式确定如下规则。 a. 对于业务类的提醒通知,采用推拉结合的方式实现。进入 web 页面或者 ios 界面之后采用拉取信息的方式实现,要获取消息提醒内容、消息是否阅读等信息。该信息通过连接 http 服务器获得;若停留在页面上,对于获取及时消息提醒,通过与 XMPP 服务器建立长连接(在 web 客户端通过 http 短连接模拟长连接实现)以推送的方式获取及时消息提醒。

  1.  对于用户会话 IM 消息,直接采用推的方式实现。进入 web 页面或者 ios 界面,建立与 XMPP 服务器的长连接,由服务器直接推送及时通讯消息,用户在线状态等。 用户会话有两种情况,单人会话和多人会话。对于单人会话,消息推送的范围固定,性能问题不严重;对于多人会话,考虑到性能,应当限制多人会话的人数,因为涉及到消息的广播,人数过多会消耗较多的服务器资源,包括内存、 CPU 和网络带宽等。
    
  2.   对于全站通知消息,如无具体的接收人。由于人数不确定,不能采用推的方式实现,若用户量巨大则会出现资源消耗过多的问题,因此只能采用拉的方式实现。
    
  3.  对于公开的微博消息。情况一、用户会通过拉取消息的方式直接阅读消息内容;情况二、用户通过订阅用户或者订阅内容的方式订阅消息,对于这种订阅的消息,订阅人数不确定,也是推拉结合的方式获取消息,用户进入个人主页后,根据订阅规则,主动拉取消息内容,但是对于新的消息 提醒 , 用户通过定期拉取新消息的方式实现。
    

分布式数据访问层技术方案选型

| Comments

解决的问题

目前已经面临或者未来可能面临的问题有以下这些:

1.数据量越来越大,超出了单表或者单库的最大限制。

2.数据访问压力越来越大,超出了数据库系统能力。

3.数据访问层运维问题。

4.数据访问层高可用方案。

5.数据访问层访问控制和管理。

暂时不解决的问题包括:

对非关系型数据存储的统一访问。

自主开发还是扩展?

为了解决上述问题,有很多可选的方案。自主开发和使用现有开源方案扩展的讨论是经常会面临的,详细讨论过程就不再赘述,直接列出讨论的结果。

结论:基于目前开源方案进行扩展和定制实现。具体原因有以下这些:

a.我们的使用场景很简单,大多数开源解决方案都可以很好地实现,而且目前有很多可选的开源方案,直接使用开源方案可行。

b.完全自主开发的周期更长、技术风险都非常大,这都是咱们无法承担的。

c.选择一个源代码开放、需求最符合、代码能够扩展和定制的开源产品可行。基于该开源产品,通过

不断深入学习使用方法,学习实现原理和源代码实现,达到可以自由扩展和定制,以改造成完全符合

自身需求的产品。

技术方案选型

可选方案分类概述 对于ddal来说,最核心的一个需求莫过于分库分表,而对于分库分表,已经有很多的开源产品出现了,比如cobar-client、hibernate shards、guzz、halo-dal、ibatis-sharding、cobar、mysql proxy、tddl等。每一个产品都有针对于不同层面进行封装而达到屏蔽上层对底层分库分表的具体细节的依赖,都是加载数据库访问客户端和服务端之间的一些中间层。

总结一下上述列出的各种解决方案可以归纳为一下几大类。

1.DAO层。该方案即通过在实现DAO层代码时候,通过硬编码的方式加入分库分表的逻辑,该层实现一般由项目组自行根据需求实现。

2.ORM 框架层。该方案的实现是通过实现一个ORM框架,该框架自带分库分表功能,如:guzz;另外一种方式是基于开源成熟的ORM框架(比如MyBaits、HIbernate)进行扩展分库分表特性,主要的开源产品有:cobar-client、hibernate shard、shalo-dal、ibatis-sharding。

3.JDBC API层。该方案通过封装JDBC API,实现分库分表逻辑,这个方法比较直接,而且有比较强的可控制性,目前还没有发现成熟的开源产品可用。

4.数据访问代理层。该方案通过位于客户端和服务端中间的代理服务器实现分库分表逻辑,主要产品有mysql proxy、Cobar和amoeba等。

5.数据库分区。该方案是数据库自行实行的分库分表特性。目前主流的关系型数据库,商业数据库Oralce、SQL server和DB2早就有非常成熟的数据库分区解决方案,而主流的开源数据库MySQL和PostGre也在5.0和8.0版本也增加了数据库表分区的特性。

如上图所示,展示的是各种方案之间的关系,还包括了各种方案所处的层次,图中带颜色的各区块表示的是各种实现方案。

上图中的关系是越处于下方的层次越低,上层的总是依赖下层,下层不依赖上层。各种层次的实现方案都有自己的优缺点,有自己适合的场景。

可选方案对比分析

各种可选方案都能够从不能程度上实现分库分表的核心需求,每种方案都有自己的优势和适合的应用场景,同时也有它的缺点和使用上的限制,通过对各种方案的详细各种因素的综合对比分析才能选择一个最适合一种或者多种方案的组合。

Cobar试用记录

| Comments

1.介绍

Cobar是关系型数据的分布式处理系统,它可以在分布式的环境下看上去像传统数据库一样为您提供海量数据服务。

  • 产品在阿里巴巴B2B公司已经稳定运行了3年以上。

  • 目前已经接管了3000+个MySQL数据库的schema,为应用提供数据服务。

  • 据最近统计cobar集群目前平均每天处理近50亿次的SQL执行请求。

详细的产品文档见产品主页 http://code.alibabatech.com/wiki/display/cobar/Home

2.产品约束

  • 不支持跨库情况下的join、分页、排序、子查询操作。
  • SET语句执行会被忽略,事务和字符集设置除外。
  • 分库情况下,insert语句必须包含拆分字段列名。
  • 分库情况下,update语句不能更新拆分字段的值。
  • 不支持SAVEPOINT操作。
  • 暂时只支持MySQL数据节点。
  • 使用JDBC时,不支持rewriteBatchedStatements=true参数设置(默认为false)。
  • 使用JDBC时,不支持useServerPrepStmts=true参数设置(默认为false)。
  • 使用JDBC时,BLOB, BINARY, VARBINARY字段不能使用setBlob()或setBinaryStream()方法设置参数。

    3.功能概述

    Cobar是关系型数据的分布式处理系统,它可以在分布式的环境下看上去像传统数据库一样为您提供海量数据服务。

3.1 Cobar解决的问题

  • 分布式:Cobar的分布式主要是通过将表放入不同的库来实现:

1.Cobar支持将一张表水平拆分成多份分别放入不同的库来实现表的水平拆分

2.Cobar也支持将不同的表放入不同的库

3.多数情况下,用户会将以上两种方式混合使用 这里需要强调的是,Cobar不支持将一张表,例如test表拆分成test_1, test_2, test_3…..放在同一个库中,必须将拆分后的表分别放入不同的库来实现分布式。

  • HA: 在用户配置了MySQL心跳的情况下,Cobar可以自动向后端连接的MySQL发送心跳,判断MySQL运行状况,一旦运行出现异常,Cobar可以自动切换到备机工作。但需要强调的是:

1.Cobar的主备切换有两种触发方式,一种是用户手动触发,一种是Cobar的心跳语句检测到异常后自动触发。那么,当心跳检测到主机异常,切换到备机,如果主机恢复了,需要用户手动切回主机工作,Cobar不会在主机恢复时自动切换回主机,除非备机的心跳也返回异常。

2.Cobar只检查MySQL主备异常,不关心主备之间的数据同步,因此用户需要在使用Cobar之前在MySQL主备上配置双向同步,详情可以参阅MySQL参考手册。

3.2 Cobar逻辑层次图

  • dataSource:数据源,表示一个具体的数据库连接,与一个物理存在的schema一一对应。
  • dataNode:数据节点,由主、备数据源,数据源的HA以及连接池共同组成,可以将一个
  • dataNode理解为一个分库。
  • table:表,包括拆分表(如tb1,tb2)和非拆分表。
  • tableRule:路由规则,用于判断SQL语句被路由到具体哪些datanode执行。
  • schema:cobar可以定义包含拆分表的schema(如schema1),也可以定义无拆分表的schema(如schema2)。
  • 以上层次关系具有较强的灵活性,用户可以将表自由放置不同的datanode,也可将不同的datasource放置在同一MySQL实例上。

2.3 Cobar使用注意事项

  1. 请注意表的拆分方式,一张表水平拆分多份到不同的库中,而不是放入同一个库中。
  2. 如果使用HA功能,请在MySQL主备之间配置双向同步

4.Cobar试用记录

4.1 解决单表数据量过大问题

  1. 场景说明.

在即使通讯系统中,需要存储历史会话记录,但是历史消息会话的数据量会随时间和用户增长非常快,如果活跃用户数据量较大,而且用户使用即使通讯较为频繁的话,则数据增长较快,假设即时通讯系统中活跃用户量是30万,每位用户每天产生的会话消息数量是100条记录,则改表每日增长的数据量是30万*100=3000万条数据,按照这种增长速度,则历史消息表的增长会很快超过单表数据量限制,因此必须通过分表实现将数据分布到不同的数据中。

  1. 实现策略.

假设会话历史消息存储在表message中,该表胡结构如下所示:

field Type Comment

userId bigint(20) NOT NULL

from varchar(100) NOT NULL

to varchar(100) NOT NULL

msg varchar(500) NOT NULL

createTime datetime NOT NULL

创建该表SQL语句脚本如下:

CREATE TABLE `message` (
  `userId` bigint(20) NOT NULL,
  `from` varchar(100) NOT NULL,
  `to` varchar(100) NOT NULL,
  `msg` varchar(500) NOT NULL,
  `createTime` datetime NOT NULL,
  KEY `index_userId` (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

将表message中的数据分布到3个数据库中,这个三个数据库名称分别是:dbtest1,dbtest2和dbtest3。

insert into message(userId, `from`, `to`, msg, `createTime`) values('1', 'yangwubing', 'pandan', 'message 1', '2013-06-22 17:12:34');    
insert into message(userId, `from`, `to`, msg, `createTime`) values('2', 'yangwubing', 'pandan', 'message 2', '2013-06-22 17:12:34');
insert into message(userId, `from`, `to`, msg, `createTime`) values('3', 'yangwubing', 'pandan', 'message 3', '2013-06-22 17:12:34');
insert into message(userId, `from`, `to`, msg, `createTime`) values('4', 'yangwubing', 'pandan', 'message 3', '2013-06-22 17:12:34');

Ki4so-发起一个史上最开源的sso项目

| Comments

最近一直在研究单点登录,研究了比较流行的开源单点登录系统——CAS,对其做了比较深入的研究,深入学习了其原理和源代码。对其有一个比较深入的认识,我们公司也是一直在用它实现单点登录,在用的过程中觉得CAS存在以下方面不太适合我们的地方。

为什么要开发自己的SSO?

  1. 重量级。CAS作为一个开源的通用的SSO系统,要考虑的东西太多,要遵循的协议也太多,因此在CAS里面有很多其实你根本用不着的概念和特性,所以会导致相对比较笨重一些。
  2. 有状态。CAS存在着TGT、ST等票据信息,这些信息是用户登录的状态,有了状态之后,不利于集群扩展,降低了整体系统的可伸缩性,当然它也有它的集群方案,是可以实现的。但是如果减少这些状态,将状态分散到客户端,不仅减轻了服务器的压力,而且服务器可以更方便的伸缩,更适合大型互联网应用的场景。 因此我们打算重新开发一个自主的单点登录系统,它在设计理念上能够避免上述两点问题,下面是我们这个项目的介绍。

    项目介绍

ki4so是一个简约、无状态、易扩展、易伸缩的适合于大型互联网web应用场景的单点登录系统,它功能简单,只实现了统一登录和登出,它最大的特色是将用户状态写入到cookie中,最大程度减少了单点登录服务端的状态,服务端只需要存储公共的应用密钥,将用户凭证的认证分散到各应用服务中,最大程度减轻了ki4so服务器的压力。

为什么要用ki4so?

单点登录系统有很多,开源的成熟的产品也有很多,比如耶鲁大学的cas等。

  1. 无状态。系统可伸缩性好。
  2. 简单轻量级。
  3. 性能高。
  4. 安全性高。

    加入我们这个项目有什么好处?

  5. 我们的项目是最开源的。我们从有了一个想法之后,就开始彻底开源了,我们将概要设计、详细设计和所有文档都彻底开源,我们不一定是一个最好的项目,但一定是最开源的项目,我们毫无保留,将所有的思想、经验和项目成果彻底与所有人分享。

  6. 我们的项目刚开始,你可以最大程度的学习到更多东西。我们项目目前刚刚启动,正处于项目的概要和详细设计阶段,你可以一起参与项目的策划和设计,你不仅仅是学习源代码,还可以自己编写出色的源代码,这远比仅仅学习下CAS要学到的东西多得多。
  7. sso是几乎每个公司都要用的,你可以将ki4so应用到你们公司中。ki4so做的事情很简单,就是统一登录和登出,几乎能与任何公司的、任何平台开发的、任何业务领域的web应用进行整合。你可以让ki4so更好地位你所在的公司服务。
  8. 你可以为开源做贡献,你在做一件伟大的事情。你可以为ki4so写扩展、写各种语言的客户端、与更多的东西进行集成并贡献出来,为别人服务,这是一件非常伟大的事情。

    联系我们

项目主页:

我们的项目主页在:https://github.com/ebnew/ki4so 这里有更详细的项目介绍。

项目群:

199315835 项目的核心团队成员都在里面,你可以加入该群,一群探讨,你可以说说你的想法,提提你的意见,或者参与项目,总之非常欢迎大家一起。

Octopress安装总结

| Comments

前言

最近学习了github的使用,开始想折腾自己的个人博客,通过在网上查找资料,最终发现octopress比较符合我的需求,博客的风格清爽,而且还具有响应式设计效果,在移动端阅读十分方便。

安装

安装步骤参考octopress官网的文档说明,见地址:http://octopress.org/docs/setup/

经过我的实践证明,在安装的时候由于某些环境发生变化或者步骤省略,可能会发生一些错误。

  1. 执行bundle install错误。由于未安装DevKit而无法满足依赖,请去网址http://rubyinstaller.org/add-ons/devkit/下载DevKit,先安装该组件。
  2. 注意版本问题。如果下载的版本与文档说明的不一致,可能会安装完毕后运行不正常。文档时针对某个版本编写的,推荐使用如下版本。

Ruby 1.9.3-p429 DevKit-4.5.2

部署到github

网站部署在octopress官网上也有文档说明,见地址:http://octopress.org/docs/deploying/github/ 但是在安装文档操作的时候会碰到问题,特记录下来。

注意: 会碰到无权限访问的问题。当执行如下命令:

rake setup_github_pages

会出现提示语句:

Enter the read/write url for your repository

(For example, ‘git@github.com:your_username/your_username.github.io)

Repository url:

由于github网站发生变化,url地址不对,如果按照提示语句设置,则会再提交的时候报错。建议直接拷贝github网站上的ssh url地址,比如目前github地址是这样的格式,比如我的用户名是ywbrj042,则完整的地址如下所示:

git@github.com:ywbrj042/ywbrj042.github.com.git

模拟练车总结

| Comments

今天练了一下午,以前不太明白的地方都明白了。特记录下来以备忘。

1.发动车辆

发动前:调整座位,系好安全带,空档位置,手刹拉起。 发动:离合踩到底,挂一档,顺时针旋转车钥匙,松手刹,同时慢放离合和加油门。汽车开始启动。

2.提速加档

先通过加速踏板加速,再逐级加档,踩离合,加档位,放开离合生效。

3.减速降档

先通过制动踏板减速,降档可以越级,踩离合,减挡位,放开离合生效。

4.停车

开右转向灯,观察后方情况,右转向,减速,踩离合,挂空档,停车。

5.转向盘

控制汽车方向。尽量保持直线行驶,根据路况微调方向保持直行,手不离转向盘,转大湾使用交替式换手,向右转大湾,左手持续在方向盘上,右手转到90度位置放手,等到转180度时,右手抓另一边,此时转手放开,循环如此。如果是转大湾则相反。

6.离合器

最左侧,离合动力。只有离合器踩到底才能换档,离合要缓慢放开后生效。左脚一直在离合器周围,负责操作离合器。

7.制动踏板

中间位置,能够降低车速,一般要缓慢持续轻踏。

8.加速踏板

最右侧,能够加大进汽量,从而提高车速和发动机转速。加速应该逐步提升,速度越慢越容易控制车辆,但是高速上若车速过快则易被后车追尾。

9.档位控制杆

手动档小汽车有1至5,R和空共7个档位,1档速度最慢,但是牵引力较大,对于起步和上坡等情况应该用低档位,1档对应车速是1-20公里,2档车速是20-30,以此类推,5档速度是50-120,每档加10.先加速后加档,先减速后减档。R是倒车档。倒车必需调整到该档。还有一个空档,该档是原始位置,只有在该档位下车速允许是0,其它档位不允许车速为0,否则会熄火,因此为了不熄火停车,应该回归到空档后在彻底停车。

10.操作总结

学车光会理论是不绝对学不会的,对于实际操作我的总结有这些: 所有操作都是机械操作杆,一般是比较容易操作的,不能使用蛮力,若发现无法操作则肯定是方法有问题,要调整,一般操作成功后都能感觉哒的一声。碰到操作杆,开关都是这样的。 练习很重要。只有经过反复的练习才能够达到不用思考的境界,多个组合动作都能够很迅速,正所谓熟能生巧,最终达到人车合一,随心所欲的境界。 克服紧张恐惧情绪。对于比较复杂的情况我们都会很紧张,会进入恶性循环,在模拟练习的时候我都有这种感觉,实战那就能容易出现这种情况,要学会克服紧张情绪,努力做到不着急,从容面对。当然还要多实际练习才是能彻底解决,当我们实战经验丰富了后,何种场景都能面对的时候就能够很自信得上路了。