MQ解耦应用

~ 为偷懒而艰苦思考ing (powered by rst2S5)

Authors:Zoom.Quiet
URL:http://zoomquiet.org/res/s5/111111-pyconchina-mq-taste

<Zoom.Quiet/>

是也乎;-)
是也乎,是也乎 Zoom.Quiet

<免责/>

山寨的,非业界公认的,个人体验为基础! 是也乎;-)

参考所有同好行为总结而得

  • 免责是必须的,分享是无理由的!

牛妞

\ (^o^) / 928d
表情牛妞
  • 我的女儿刚刚一岁半,非常牛,,,脾气牛,头脑牛,虽然不会说话,但是已经能指挥我们干活了...

<brief/>

简单想,简单试,简单用... 是也乎;-)

起因

各种杯具的根源 是也乎;-)

复杂

  • 是也乎?

根源在哪儿?!

多变/前后依赖/矛盾的业务 是也乎;-)

业务

  • 变化的发动者总是业务

为毛有乱来的业务?

是共军太狡猾 是也乎;-)

设计

  • 业务总是变化,是必然的,而且随着互联的发展越来越快

为毛要乱实现业务?

  • 没空宏观规划 是也乎;-)
  • 没空回顾整理
  • 没心情...

开发

  • 可是落实到一个即使很稳定的系统中,也将引发无数问题
  • 因为原先并没有考虑这么多变化
  • 代码/框架/系统,根本没有到可以随机应变的状态

真正的原因?

经验不足吧 是也乎;-)

耦合

  • 耦合的代码都是人为引入的!

依赖是种心理反应

不受控制的功能/代码叠加 是也乎;-)

蔓生

  • 在思想/态度/情绪失控后的乱来

<brief/>

简单想,简单试,简单用... 是也乎;-)

对策

简单的保持需要更加简单的设计 是也乎;-)

K ISS

  • 那么从根儿上尝试解决!

复杂的标志性表现

牵一发动全身 是也乎;-)

乱入

  • 不乱入,就得从一开始,任何一个组件都有一个统一的简单的可行的鲁棒性 结构

功能代码的模块化不解决问

业务的纠结是根源 是也乎;-)

概念

  • 整理各种概念

Business?!

  • 此"业务"非彼"业务" 是也乎;-)

业务

  • 代码要解决实际问题
  • 实际问题以用户故事描述
  • 应对方案就是业务定义

Application

方案的实现应用 是也乎;-)

应用

  • 对业务的支持是映射到各个应用中

Entities

组成应用的实体 是也乎;-)

实体

  • 应用一系列 代码/数据 集合构成

    • 实体代表了分离的数据系列(disjoint sets of data)
    • 每个数据项(datum)只位于一个实体中
    • 实体中的数据决不与其它实体的数据交叉(overlap)
  • 考虑实体的:

    • 分离的序列化范围 Disjoint Scopes of Serializability
    • 唯一标识的实体 Uniquely Keyed Entities
    • 重分区和实体 Repartitioning and Entities
    • 原子事务和实体 Atomic Transactions and Entities
  • 应用程序底层将确保每个实体键值(和实体)位于单一的机器(或群集)上,而不同实体则可能分布在任何地方

  • 实体是操作原子性的边界标志

Transactions

实体完成的行动是事务 是也乎;-)

事务

  • 对实体的操作是事务

ACTIVITIES

事务的具体执行 是也乎;-)

活动

  • 对事务的控制/调用/流传 就是活动
  • 活动包含了实体的状态集合

综上想达成的目标效果

是也乎;-)

期待

  • 开发系统的首选原则

Robustness

  • Almost-Infinite Scaling of Applications 是也乎;-)
  • 考虑无限伸缩应用

鲁棒

  • 稳健性~鲁棒性原是统计学中的一个专门术语
  • 控制论中:是指控制系统在一定(结构,大小)的参数摄动下,维持某些性能的特性

对策基于以下理论

假设

  • 是也乎?

伸缩性与应用的分层无关

分层

  • 底层是伸缩相关(scale-aware)的即它们了解这个映射关系
  • 我们假设底层为上层提供了一个伸缩无关的(scale-agnostic)编程抽象
  • 使用它编写应用程序上层代码时无需考虑伸缩问题

事务序列化范畴与伸缩性有关

范畴

  • 全局事务序列化(global transactional serializability)

    • 2PC(两阶段提交)在某节点不可用时容易阻塞
    • 协议例如Paxos算法,在节点失败时不会阻塞
  • 现在考虑的是非全局事务
  • 多个分离的事务序列化范围(multiple disjoint scopes of transactional serializability)

大部分应用使用"至少一次"的消息方式

At-Least-Once 模式 是也乎;-)

1+

  • 问题产生的原因是消息分发与持久化数据的更新不是直接结合在一起

综上

是也乎;-)

原则

  • 开发系统的首选原则

Idempotence

只包含单一安全事务 是也乎;-)

幂等

  • 识别出所有实体后

  • 明确各级原子性的事务来:

    • 安全且幂等: 读取
    • 安全不幂等: 查询/修订
    • 幂等不安全: 创建
    • 不安全幂等: 删除
  • 避免: 消息重试(retry)和重新订阅(reorder)

用消息来协调

是也乎;-)

消息

  • 隔离实体
  • 转移事务
  • 记录/协调/分发活动

Message-oriented programming

面向消息的编程 是也乎;-)

MOP

  • 这是 OOP 之后无数 XOP 的又一次概念冷饭
  • 之前体验到的 面向数据编程,在分布式后,推导成了 MOP
  • 当然还有 MOO ~ 面向肌肉的操作

通常系统

是也乎;-)
i/map/flow-nomor_wsd-napkin.png
  • 是也乎?

MOP系统

是也乎;-)
i/map/flow-mq_wsd-napkin.png
  • 是也乎?

常见邮件提醒

是也乎;-)
i/map/mailr-flow-nomor_wsd-napkin.png
  • 是也乎?

MOP邮件提醒

是也乎;-)
i/map/mailr-flow-mq_wsd-napkin.png
  • 是也乎?

通常业务日志

是也乎;-)
i/map/log-flow-nomor_wsd-napkin.png
  • 是也乎?

MOP业务日志

是也乎;-)
i/map/log-flow-mq_wsd-napkin.png
  • 是也乎?

加层

这次是通用的 是也乎;-)

1 板斧

  • 面对复杂问题永远可以通过增加一个抽象层来解决
  • MOP 之下,永远只多一层!

<brief/>

简单想,简单试,简单用... 是也乎;-)

业务原子化

内部全部 RESTful 接口化 是也乎;-)

前提

  • eat yself dog food!
  • 好处是每个原子操作都非常非常简单

分级

可RESTful 的... 是也乎;-)
  • eat yself dog food!
  • 好处是每个原子操作都非常非常简单

支撑核心

尽可能异步化一切 是也乎;-)

MQ

  • 是也乎?

Message

无状态事务的实体键 是也乎;-)

M Q

  • 消息可以是任何东西:
  • 数据片段
  • 代码片段
  • 状态
  • 指令
  • ...

Queue

FIFO的管道 是也乎;-)

M Q

  • 一个健壮的,基于 http的拥有多种数据结构的栈

Queue的能力

分支式请求可耐受 是也乎;-)

迸发

  • 即,能自动对缓存进行优化的

Queue的内容

Atomic Transactions 是也乎;-)

原子性

  • 对操作能进行原子保证的

Queue的监测

有方法将意外的任务回收 是也乎;-)

可回收

  • 这个要求不太,一般可以自制

芹菜

高档MQ选择... 是也乎;-)
  • 复杂

Celery

分布式任务/工作 队列 是也乎;-)
i/snap/Celery-Overview-v4.jpg

Djnago-celery

有Django扩展 是也乎;-)
i/snap/celery_2011-11-23-174734_1021x526_scrot.png

gearman

类似的知名作品 是也乎;-)
i/snap/gearman_2011-11-23-175608_620x561_scrot.png
  • 基于 Perl/RPC...

面向文档(document-oriented)的NoSQL 数据库

10gen 团队的魔幻作品! 是也乎;-)
i/logo/logo-mongodb-ondark_h300.png
  • 这个词是从humongous中截取出来的,其野心不言而明,直指海量数据存储

内存映射机制

天然自动化缓存调度 是也乎;-)

mmap

  • 内置分布式集群控制,迸发影响可用

capped collection

天然高速队列配合 Tailable Cursors 是也乎;-)

定长集

  • 不用计算空间的定长队列

文档级的原子操作

$findAndModify;相当于表安全 是也乎;-)

upset

  • $upset 也是

使用时间差

时间戳查询 是也乎;-)
now = datetime.datetime.now()
difference = datetime.timedelta(seconds=10)
timeout = now - difference

queue.find({'inProg' : True, 'start' : {'$lte' : timeout} })
  • 山寨,但是好用

Karait

轻便MQ选择... 是也乎;-)
  • 简陋,但是,作为开始很好用

Python 入Q

示例代码 是也乎;-)
from karait import Message, Queue
queue = Queue(
    database='karait',
    queue='messages',
)
queue.write({
    'name': 'Benjamin',
    'action': 'Rock'
    }
    ,routing_key='foobar'
    )#, expire=3.0
  • 是也乎?

Python 出Q

示例代码 是也乎;-)
from karait import Message, Queue
queue = Queue()

message = queue.read()[0]
print "%s" % (message.name)

message.delete()
  • 是也乎?

node.js 出Q

示例代码 是也乎;-)
var puts = require('sys').puts,
    Queue = require('karait').Queue;
new Queue(function(err, queue) {
    (function readMessages() {
        queue.read({routingKey: 'foobar'}, function(err, messages) {
            for (var i = 0, message; (message = messages[i]) != null; i++) {
            //...
            }
            queue.deleteMessages(messages, function() {
                readMessages();
            });
        })();
    });
  • 是也乎?

Ruby 出Q

示例代码 是也乎;-)
require 'karait'

queue = Karait::Queue.new
message = queue.read().first
print "#{message.name}"

message.delete
  • 是也乎?

原子保证

visibility_timeout 设定超时秒数 是也乎;-)
from karait import Message, Queue
queue = Queue()

message = queue.read(routing_key='foobar',
    visibility_timeout=3.0)[0]
print "%s" % (message.name)

message.delete
  • 是也乎?

未尽的

各种没现成的功能 是也乎;-)

ToDo

  • MOP 从思想到框架缺少的...

工作状态

是否超时/死亡/僵尸... 是也乎;-)

进程

监控

  • ip:port:start_time:pid 为组合,对进程进行标识:

    • pid 确保唯一性
    • gpid 生成成本低
    • gpid 有生产意义
    • gpid 有历史意义

数据传递

当事务有前后顺序时? 是也乎;-)

活动

序列

  • 再设计,通过多段提交,去顺序化

灾难响应

能否安全的迁移所有末尽事务? 是也乎;-)

灾难

迁移

  • MongoDB 的能力了!

业务状态

合理化业务整体进展的汇报 是也乎;-)

实时

统计

  • 分布式业务日志内置!

对策

简单的保持需要更加简单的设计 是也乎;-)

KI SS

  • 那么从根儿上尝试解决!

KISS

山寨才V5 是也乎;-)
  • 1、code review 的必须很快,代码排版到能够扫一眼文件就知道有没有 bug 和设计问题
  • 2、当无法起出一个PP的变量名时,已经有设计问题了

<brief/>

简单想,简单试,简单用... 是也乎;-)

总之:任何好想法

期望记住的~单位时间能记住的只有7+-2 个 是也乎;-)
  • Doing now! don't thinking!

<版本/>

是也乎;-)
反馈:Zoom.Quiet

http://zoomquiet.org/res/s5/111111-pyconchina-mq-taste

S5

纯HTML 幻灯撰写框架!... S5icon
  • 仅仅依靠 CSS+JS 的HTML格式幻灯演示框架
pix/2010-01-18-230729_605x421_leo.png
  • 虽然有很多其它替代方案,至今用得最爽的还是 S5
  • 最好也是最不好的,就是S5 需要专用的http 空间发布,无法直接分享到 slidshare.com 之类SNS空间中

<discuss/>

是也乎;-)

Q&A