为何要在服务层设计读写分离?

做者:陈叶皓(携程邮轮研发部软件架构师)html

个人架构师同事问我:“为何你总说要在服务层实现读写分离,咱们已经在数据库实现了读写分离,是否是已经够用”。如下是个人解释,面试

在作网站性能优化的时候,我经常忘记还有数据库读写分离这件事,由于数据库读写分离,对性能带来的提升太有限了,实际上,就是一倍(一台服务器变成两台服务器)。当你的网站业务发展,若是从无到有地使用数据库读写分离,提升了一倍的服务能力,你很快就须要想新的优化方案。实际上,数据库的读写分离,更像是数据安全的一个副产品,用一台数据库服务器不安全(怕数据丢失),用一台服务器做为备份,既然有了两台服务器,就充分利用吧,因而有了“读写分离”,提升一倍也是好的。redis

 

因而,可以十倍百倍提升性能的方案出现了,缓存加服务器集群,这是最经常使用且有效的提升网站访问量的设计。使用共享缓存(memcached,redis)能够得到十到几十倍的性能提高,使用进程内缓存,能够获得百倍的性能提高;集群中增长一倍的服务器,能够增长一倍的计算能力,服务更多的并发请求。等一下,上面所说的方案,其实只对“读”操做才有效,对“写”操做能够说是毫无用处。数据库

那么有什么办法能够提升“写”操做的性能,在架构部署的设计方面,个人答案是,“没有”。编程

从硬件入手,可使用SSD硬盘。愿意替换底层数据库,可使用hbase或者cassandra,都不在今天讨论的范围。我想说的是,既然使用缓存和增长服务器,对于“写”操做没有优化做用,在一开始,“写”操做相关的服务,就不应和“读”操做一块儿,被分配到数量庞大的计算机集群里。缓存

想象这样的架构设计,我有一个“读”服务的集群,一共4台服务器,我有一台“写”服务器(另外一台备用,故障时切换)。当个人网站访问量上升,我增长“读”服务器集群到8台,简单就能应付问题。由于“读”服务是状态无关的,增长到100台也不会带来错误的数据,这是一个重要的思想,状态无关的服务,才能够放心地水平扩展,事实上,状态无关的服务,一般只有“读”服务。安全

那么当“写”服务撑不住的时候,怎么办,嗯。。。总会有办法,反正不是加缓存或者是使用集群,这个能够作架构师面试题。性能优化

而后我解释一下为何不应在集群里面运行“写”服务,我把“写”服务分为两种。服务器

1.       和“状态”(可能发生冲突的情形)弱相关,好比用户提供内容(UGC)的操做,每一个用户提交本身的评论,或者发布本身的微博,不太容易发生冲突。对于这类“写”服务,部署在集群里面勉强可行,虽然没带来什么好处,但也没有引入错误架构

2.       和“状态”(可能发生冲突的情形)强相关,好比包含库存操做的电商网站,上千人“秒杀”热门商品,容许这样的操做在集群内并发,是架构师本身做死的节奏啊

明白了这个道理,你就知道我以前为何说是“一台”写服务器,只有一台服务器,才能够保证在“秒杀”场景下,不会在没有库存的状况下继续售卖成功。

细心的读者(嗯,就是你)会继续追问,在一台服务器的状况下,如今都是多核并发编程,保证串行操做也不是容易的事啊。问得太好了,我这大半年写的系列文章,都是为了解决这个问题,你须要的是actor模型。异步编程加上进程内的消息队列,能够高效地对并发操做进行串行的处理。

结论,使用服务器集群提升性能只对“读”服务有效,对“写”服务无效,“写”服务器应该使用主/从模式,同一时间只使用一台服务器。在“写”服务器内部,使用支持actor模型的编程语言,保证关键操做的串行。最后老生常谈,支持actor模型的编程语言是:Erlang,Go,Scala,F#

原文连接:http://techshow.ctrip.com/archives/784.html

相关文章
相关标签/搜索