发帖    主题    评论    推荐    标签    作者    订阅    查搜    注册   登陆   关注
 
面向对象 设计模式 领域驱动设计 企业架构 框架 开发教程 微服务 大数据 扩展性 并发编程 事件驱动 分布式 SOA
1 2 下一页 Go 2

使用Apache Samza对数据库进行彻底的"调教"

                   
2015-03-05 12:50
赞助商链接

数据库是全局的共享的可变的状态,自上世纪60年以来一直是这样,大多数有自尊的开发人员在他们代码中已经摆脱了全局变量,那么为什么我们还要容忍数据库作为一个全局变量呢?

这个谈话介绍了Apache Samza,它是一个由LinkedIn开发的分布式流处理框架,起初,它看起来像一个实时计算分析工具,但是它彻底地将数据库架构颠覆了。

在其核心是一个分布式的持久的提交日志,由Apache Kafka实现强大的流连接和管理大量的数据可靠性。

原文:Turning the database inside-out with Apache Samza

下图是典型的Web应用框架架构:




你有一个客户端比如是Web浏览器或移动应用,客户端向服务器端或者称为后端交互,后端实现一些业务逻辑,执行访问控制,接受输入,产生输出,当后端需要为将来保存一些数据,那么就存储到数据库,以后需要时查询数据库。这是目前大家非常熟悉的东西。

通常我们建立这种后端是无状态,这有很多优点:你能通过并行运行多个进程或实例来扩展后端,你能将客户端转发到多个实例服务器上,任何需要状态的请求将从数据库中查询,这通常与HTTP无状态特点吻合。

这个架构最大问题是:状态必须保存数据库中,这样导致将数据库作为一个巨大的、全球的、共享的可变状态,它是一个全局变量,在你的应用服务器之间共享。

在共享内存中进行并发是一件可怕的事情,LinkedIn已经斗争了很多年,从Actor模型 Channel gogroutine等,所有都是试图解决共享内存的并发问题,避免锁 死锁、并发修改、竞争条件等等。

我们试图摆脱共享内存的并发问题,但是数据库还是最大的共享的可变状态,那么值得思考:如果我们能在单服务器应用架构中能解决共享内存的并发问题,如果我们在整个系统级别克服这种全局的可变状态会如何呢?

在我们看来,将整个系统建立在可变的数据库系统上是习惯问题,我们几十年的架构习惯,现在我们想想有什么其他架构构建有状态的系统呢?

为了试图找出我们可以采取什么样的解决路线,我们先看看目前数据库做的四个事情,这四个例子也许为我们指明方向。

1.复制。数据库是在主从服务器之间复制数据,看看下面购物车案例:




这是一个关系数据库数据模型,这是一个通用模型,有一个表,表中有一些列等等,每行代表一组记录。

假设客户123改变主意,不需要一个产品999,而是需要3个,那么我们会更新到数据库。




那么对于复制来说,这些写操作都要从主服务器复制到从服务器上。

6
2015-03-05 12:56




这种复制有几种方式,一个是将同样的更新发送到从服务器,从服务器在自己的数据上执行同样的SQL语句;还有一种是将主服务器的写后日志传送到从服务器;第三种是是,逻辑日志,主服务器写出与以前的区别,比如哪个行插入或修改或删除了,对于本案例更新,逻辑日志指出了哪个行被改变,使用主键或其他元标识替代,以及相应的新值。

这里好像很正常,但是会有趣的事情发生:

2015-03-05 13:04



上图是更新语句,一个命令式语句描述了状态的变化,它命令数据修改某行记录。

从另外一个方面看,当这种写操作作为逻辑日志从主服务器复制到从服务,它其实有一个不同形式:它成为了一个事件,开始某个时间点,一个特定顾客修改了某个特定商品的数量,从1到3,这是发生过的事实,无论以后客户从购物车去除或者再次修改数量或者干脆走了,都不能改变目前这个状态改变的事实。

也就是说,即使你以传统方式使用你的数据库,以新状态覆盖旧状体,数据库内部的复制机制还是将这些命令式SQL语句转为一个不可变的事件流。

至此,可以好好想想,我们在谈论一个完全不同的东西。

2015-03-05 13:12

下面看数据库的第二索引,熟悉数据库的人应该知道,可以使用create index on cart (customer_id)来创建。

当你运行这些创建索引SQL语句时,数据库内部做了些什么呢?




上图左边是根据列customer_id创建,右边是根据product_id创建,数据库会扫描整个表,为每个索引创建辅助数据结构,看上去类似key-value结构,key是创建索引的列,值是代表记录的特定key:



2015-03-05 13:22

这个基于基表建立索引表的过程是机械的,它仅仅代表着现有的数据在不同的数据结构。(换句话说,如果你删除索引,不会从数据库中删除任何数据。)这是一个冗余的数据结构,只是为了提高查询速度,从原始表派生出来的。

以后你如果新增新的数据,数据库将自动在基表和索引数据结构之间保持事务一致性,在两个表中插入相同数据。这个过程是事务的,意味着,一旦出错回滚,索引表的修改也会回滚。

如果大型表上创建索引,可能需要几个小时,向一个生产现场数据库如果不断写数据,那么就会不断地建立索引。索引生成器真的像一个后台进程运行。

为了做到这些,数据库必须从某个时间的一致性快照建立索引,当索引构建时还需要对这个时间点以后的任何修改同时进行跟踪。这是一个很酷的功能。

2Go 1 2 下一页

赞助商链接

赞助商链接

返回顶部

移动版 关于本站 使用帮助 联系管理员 最佳分辨率1366x768
OpenSource JIVEJDON Powered by JdonFramework Code © 2002-20 jdon.com