大话快速开发——III 回归

来源:互联网 发布:百度贴吧一键签到软件 编辑:程序博客网 时间:2024/05/17 03:28

没想到,这个系列还有第三篇,上一篇尝试使用一些数据同步机制来解决一些烦人的定义和约定过程。

但是我们在开发中却引入了另外一种约定:

1.每个对象都需要OpId来定位当前对象。

2.需要绑定修改事件,用于监测数据变化。

3.需要维持当前镜像,如果被释放或者意外解绑,会导致同步失败。

4.如果进行分布式的设计,需要维持多个镜像的一致。


以上暂且称之为缺点,如果在一个即时性较强的项目里面,上面的这些也就是非常必要的。

但是如果用作一个较小的,非即时的项目里面,反而会给项目带来负担。

所以当公司在开发一个小项目时,并无采用此方案。

但是采用传统模式开发,却依然存在一些问题。


先看看之前数据流程的几种模式:


传统数据流程1:(压力全在数据库上)

Web请求-》获取操作对象(从数据库)-》写入数据库-》返回操作结果

一般数据库压力较大会采用缓存模式流程2:(比上一种好点)

Web请求-》获取操作对象(从数据库/或缓存)-》写入数据库-》返回操作结果

后来有了ORM,变成了这样流程3:(用对象会舒服一点,不用写SQL)

Web请求-》获取操作对象(从数据库或缓存)-》修改对象-》同步到数据库-》返回操作结果

渐渐的当我们抛弃了数据库,仅作为持久化和查询使用,流程变成流程4:(更干脆了,但是不安全)

Web请求-》获取操作对象(从数据库或缓存)-》修改对象-》写入修改队列(会有个线程来写入数据)-》返回操作结果


流程1来说,最简单,但是众多的SQL语句写起来不够灵活。


流程2.3来说,其实压力还是在数据库上,虽然缓存分担了一些,但是缓存的代价是可能导致数据的不一致,需要检查缓存的版本。

逐个修改对象Update过去,如果遇到多个地方,还得使用事务,同步等待数据写入结果,会导致线程挂起,增加并发请求数。


流程4.相对来说写入队列可以减少更新压力,但是延迟写入会导致可能的回档和写入不完整。


设想的数据流程5

Web请求-》获取操作对象(从后端/或缓存)-》修改对象-》使用完整写入服务-》返回操作结果

写入服务详解:

检查缓存对象-》检查修改后对象-》检验对象差异-》如果无差异直接返回

-》有差异-》请求写入锁(单一锁)-》并发送修改后对象到后端服务-》返回

(异步)后端服务-》收到差异对象后-》获取当前版本对象-》合并差异-》写入数据库-》释放写入锁

从流程5来说,仅仅是替换了读数据库和写数据库,其实和流程3是一样的。却以较小的代价(数据校验和请求写入锁)获得了延迟写入的响应速度。

虽然依然可能存在回档,但是数据完整性却可以保证。

而且,在采用数据校验后,缓存即可拥有反向更新特性:

当你请求锁失败,则表示你的数据不正确,可能被其数据修改,应该获取新的数据版本进行重试。

代价:完整写入意味着,每次请求你都需要完整的序列化/转换整个对象,这意味着CPU的消耗。


数据库直接写入反向更新流程:

数据库直接更新-》触发器-》无写入锁-》直接更新-》更新写入锁和校验值

-》有写入锁-》提示更新失败

用户操作:

请求写入锁-》校验不一致-》返回失败


反过来,如何让传统流程拥有反向缓存更新功能?

1.放弃缓存?(这个当然不行)

2.写入锁和校验值:

如果直接完整校验,则拥有大量的查询(多个表组织成完整数据),这里依然需要校验缓存。(行不通)

子数据校验,每条数据都拥有校验值,写入前先上锁,并写入。行得通,但是如果业务逻辑较负载,要写在一个数据库业务里面。编写较复杂。


流程5和其他流程的差异:

1.简单的拥有反向缓存更新功能,意味着可以轻松扩容,虽然需要付出更多的CPU和内存

2.编码开发更简单,无需关心修改,无论如何都仅拥有一次修改/或者不修改。

3.获得基于异步写入的优秀响应性能,却没有延迟写入的一些缺陷。

4.拥有即时写入优点,却更少的关心更新逻辑。


新的结构概述:

1.依然采用实体类镜像模式。

2.采用Json文本差异进行同步。

3.同步完数据采用全刷新模式或者差异刷新模式更新UI,前者比较简单,后者比较高效

4.基于单一写入超时锁的即时写入模式。(会带来少许线程并发压力,可采用策略避免)

5.镜像数据校验,写入数据必须进行校验用于保持数据完整性。


优点:

1.干净,无需对象绑定,以及维持对象的绑定。

2.简单,无需大量Opid的约定,或者干脆无约定,仅保持根目录。

3.小巧,采用类似一个Memcache的用法,读取->修改->写入,可以替换原有缓存,如果原来采用Memcache的,可以采用类似Proxy的做法。

4.兼容,依然可以保持差异同步带来的优势。

5.灵活,采服务式的调用方式,可以通过部署多个服务来分担压力和扩容。


缺点:

1.一些额外的CPU


0 0
原创粉丝点击